{"id":1715,"date":"2026-10-21T19:13:58","date_gmt":"2026-10-21T10:13:58","guid":{"rendered":"https:\/\/heyyocg.link\/?p=1715"},"modified":"2026-10-21T19:13:58","modified_gmt":"2026-10-21T10:13:58","slug":"ue5-poly-decompose-coloso","status":"publish","type":"post","link":"https:\/\/heyyocg.link\/en\/ue5-poly-decompose-coloso\/","title":{"rendered":"[UE5] A Foundation for Various Polygon Decomposition Effects! How It Works in Niagara"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Effects where a model breaks apart into its polygons have been around since older games like FF9, and back then they were most likely implemented by programmers making full use of shaders.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a134c15&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a134c15\" class=\"wp-block-image size-large wp-lightbox-container\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15-1024x576.jpg\" alt=\"\" class=\"wp-image-1707\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15-1024x576.jpg 1024w, https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15-300x169.jpg 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15-768x432.jpg 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15-1536x864.jpg 1536w, https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/noheallowlv_23-15.jpg 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Ozma&#8217;s defeat effect in FF9<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To control polygon decomposition and deformation in a shader, you can implement it in the Geometry Shader stage, which works even in general-purpose game engines like Unity. However, some graphics pipelines don&#8217;t support it, so it isn&#8217;t something you can use casually.<br>And unfortunately, UE5 doesn&#8217;t support Geometry Shaders.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2193 A polygon deformation I made with a Geometry Shader in Unity a while back<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-twitter wp-block-embed-twitter\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"500\" data-dnt=\"true\"><p lang=\"ja\" dir=\"ltr\">\u3084\u3063\u3068\u3001\u5185\u7a4d\u3067\u30bf\u30a4\u30df\u30f3\u30b0\u5236\u5fa1\u3059\u308b\u3084\u308a\u65b9\u7406\u89e3\u3057\u305f<br>\u30b3\u30fc\u30c9\u2193<a href=\"https:\/\/t.co\/wtRFi32DVn\">https:\/\/t.co\/wtRFi32DVn<\/a><a href=\"https:\/\/x.com\/hashtag\/unity?src=hash&amp;ref_src=twsrc%5Etfw\">#unity<\/a> <a href=\"https:\/\/x.com\/hashtag\/geometryshader?src=hash&amp;ref_src=twsrc%5Etfw\">#geometryshader<\/a> <a href=\"https:\/\/t.co\/LbCWwWTPGo\">pic.twitter.com\/LbCWwWTPGo<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/x.com\/yo_hanashima\/status\/1160478458004119553?ref_src=twsrc%5Etfw\">August 11, 2019<\/a><\/blockquote><script async src=\"https:\/\/platform.x.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But UE5 has Niagara!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By making full use of Niagara&#8217;s features, you can work around the drawbacks of a shader-based approach and create all kinds of interesting polygon decomposition effects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Specifically, we recreate the mesh with particles, which turns &#8220;controlling polygons&#8221; into &#8220;controlling particles.&#8221;<br>In this article, I&#8217;ll walk you through the basics of how that works, step by step!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you understand these basics, all you have to do is change how the particles are controlled (how they move), and you can apply it to various decomposition and deformation effects. I&#8217;d really love for you to master this as a foundation for expanding your range of expression!<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-x wp-block-embed-x\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"500\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\">Polygon Decomposition from my Coloso course Mastering the Mechanics of Advanced Niagara &amp; Material VFX<br>\u2192 <a href=\"https:\/\/t.co\/tUTQstjRxk\">https:\/\/t.co\/tUTQstjRxk<\/a><br>It\u2019s a versatile technique that converts mesh polygons into particles<br>Optimized for 1 particle per polygon with LOD support, it\u2019s practical for games <a href=\"https:\/\/t.co\/nnaNFTjTLV\">pic.twitter.com\/nnaNFTjTLV<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/x.com\/yo_hanashima\/status\/2035340658295394320?ref_src=twsrc%5Etfw\">March 21, 2026<\/a><\/blockquote><script async src=\"https:\/\/platform.x.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Building the Base System: Replacing the Mesh with Particles<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">First, let&#8217;s lay the groundwork for replacing the character mesh with &#8220;a collection of particles.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Get the Mesh&#8217;s Total Polygon Count and Spawn Particles<\/h3>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a1350db&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a1350db\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/01a_get_tri_count.jpg\" alt=\"The Get_Tri_Count Scratch Pad: Map Get reads TargetSkeletalMesh, and the Count from Get Triangle Count is written to TriCount with Map Set\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Get the mesh&#8217;s polygon count in a Scratch Pad (Get_Tri_Count) and write it to TriCount<\/figcaption><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135279&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135279\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/01b_spawn_count.jpg\" alt=\"The GPU emitter stack, and the Details panel with Spawn Burst Instantaneous's Spawn Count set to EMITTER TriCount\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Set Spawn Burst Instantaneous&#8217;s Spawn Count to TriCount (the emitter runs on the GPU)<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If the target mesh is made of &#8220;10,000 polygons,&#8221; we spawn exactly &#8220;10,000 particles.&#8221; That&#8217;s why we basically use a GPU Emitter.<br>Using a Niagara Scratch Pad, we get the exact polygon count (Triangle Count) of the target mesh and plug it straight in as the number of particles to spawn (the Count of Spawn Burst Instantaneous).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Assign Exactly One Particle to Each Polygon<\/h3>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135462&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135462\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/02_skeletal_mesh_location.jpg\" alt=\"The Skeletal Mesh Location module with Triangle Sampling Mode set to Direct (All Triangles) and Return Exec Index (Execution Index) plugged into Triangle ID\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Set Triangle Sampling Mode to &#8220;Direct (All Triangles)&#8221; and plug Execution Index into Triangle ID<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we place particles on every polygon without any duplicates: &#8220;particle 0 goes on polygon 0, particle 1 on polygon 1&#8230;&#8221; and so on. Change the sampling mode of Skeletal Mesh Location to &#8220;Direct,&#8221; and assign the particle&#8217;s sequential number, Execution Index, directly to the polygon number, Triangle ID.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135644&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135644\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/03_red_sprites.jpg\" alt=\"Bright red square particles densely packed on top of each triangle of the character's wireframe\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">One square sprite stuck to each polygon (still full of gaps)<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now the particles are placed on the surface of the mesh.<br>But as you can see in the image, at this stage they&#8217;re just &#8220;square sprites&#8221; stuck to the surface, with gaps everywhere. Next, we&#8217;ll deform them into &#8220;triangles&#8221; that exactly match the original mesh.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recreating the Shape: Deforming Square Sprites into &#8220;Triangles&#8221; with WPO<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To change the shape of the particles, we use a material feature called <strong>WPO (World Position Offset)<\/strong>. It&#8217;s a powerful feature that lets you freely move a model&#8217;s vertex positions from the material side.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Calculate the Vectors to &#8220;the Polygon&#8217;s 3 Vertices&#8221; in Niagara<\/h3>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a1358af&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a1358af\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/04_vertex_vectors.jpg\" alt=\"A slide diagram with yellow vectors extending from the center of a triangle (the particle's position) to its 3 vertices\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Vectors from the particle&#8217;s center to the polygon&#8217;s 3 vertices<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Inside a Niagara Scratch Pad, we get <strong>&#8220;the absolute positions of the 3 vertices&#8221;<\/strong> of the polygon (triangle) the particle is attached to.<br>Then, by subtraction, we calculate the vectors from &#8220;the particle&#8217;s current center position&#8221; to &#8220;the 3 vertices&#8221; (which direction, and how far, to move to reach each vertex).<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135aac&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135aac\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/04b_scratchpad_vertex_vectors.jpg\" alt=\"A Scratch Pad graph that gets the Position from Get Skinned Triangle Data WS (the particle's center) and WS001\u2013WS003 (the 3 vertices), subtracts the center position from each vertex position with Subtract nodes, and writes the results with Map Set\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Inside the Scratch Pad: get the Position of the center (WS) and the 3 vertices (WS001\u2013003), then subtract (\u2212) to get the vectors<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Send the Values to the Material with Dynamic Parameters<\/h3>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135c8a&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135c8a\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/05a_dynamic_param_vertvec1.jpg\" alt=\"A Dynamic Material Parameters module added, with the X, Y and Z of VertVec1 set to Param0\u20132 of Index 0 using Make Float from Vector\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Add Dynamic Material Parameters and set the X, Y and Z of VertVec1 to the parameters<\/figcaption><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a135e2e&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a135e2e\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/05b_dynamic_param_vertvec23.jpg\" alt=\"The Details panel with the X, Y and Z of VertVec2 and VertVec3 set to the remaining parameters of Index 0\u20132 in the same way\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Set VertVec2 and VertVec3 to the remaining parameters in the same way<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We send the 3 calculated vectors to the material using Dynamic Material Parameters. Now the material knows &#8220;which direction to move each vertex to form a triangle.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Move the Vertices (WPO) Using UVs in the Material<\/h3>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a136044&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a136044\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/06a_material_dynamic_param.jpg\" alt=\"In the Material Editor, values received from three Dynamic Parameter nodes (Parameter Index 0\u20132) are combined into vectors with MakeFloat3 and stored in the VertVec1, VertVec2 and VertVec3 named reroutes\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Combine the values received through Dynamic Parameters with MakeFloat3 and store them in VertVec1\u20133<\/figcaption><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a1361e1&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a1361e1\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/06_wpo_material.jpg\" alt=\"The full node graph: TexCoord is split with BreakOutFloat2Components, VertVec1\u20133 are distributed with Lerp, and the result is added to the difference between Particle Position and Absolute World Position and connected to World Position Offset\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">The full graph: distribute VertVec1\u20133 with TexCoord and Lerp, and connect the result to World Position Offset<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the material, we use the received vectors to move the square&#8217;s vertices.<br>We use the UV coordinates (TexCoord) to decide &#8220;which corner&#8221; of the square sprite moves along &#8220;which vector.&#8221;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If U (horizontal) is 0, it&#8217;s the left vertex; if it&#8217;s 1, it&#8217;s the right vertex.<\/li>\n\n\n\n<li>If V (vertical) is 1, it&#8217;s the bottom vertex.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">By building the math with Lerp (linear interpolation) like this, we can &#8220;align the square&#8217;s top 2 vertices with the base of the triangle, and squeeze the bottom 2 vertices together into one point to match the triangle&#8217;s remaining vertex.&#8221;<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a136457&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a136457\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/07_triangles_result.jpg\" alt=\"A bright red character whose square sprites have been deformed into triangles that line up perfectly with the character mesh\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">The squares deform into triangles that line up perfectly with the original mesh<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Plug this result into WPO, and&#8230; the square sprites are forced into triangles and line up perfectly with the shape of the original character mesh!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Got the Basics! \u2026But How Do You Finish It from Here?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ve now &#8220;recreated the shape&#8221;! Every polygon has been replaced with a particle. Once you have this state, all kinds of effects become possible just by deciding how to move the particles.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2026However, as you can see from the image in Step 5, right now it&#8217;s just &#8220;a bunch of bright red triangles.&#8221;<br>To turn this into a real, finished effect, you need to get past two big hurdles:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Recreating the &#8220;look&#8221;<\/strong><br>Just matching the shape loses the original character&#8217;s textures and smooth shading (normals), so it ends up looking different from the original. How do you copy the texture and normal information onto the particles to bring it closer to the original character&#8217;s look?<\/li>\n<\/ol>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a136724&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a136724\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/08_look_reproduced.jpg\" alt=\"Left: the original mesh. Right: the character turned into particles with its textures and normals copied over. They look almost identical\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Left: the original mesh \/ Right: the particle version (once textures and normals are copied, they look almost identical)<\/figcaption><\/figure>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Turning it into cool &#8220;animation&#8221;<\/strong><br>Once the look is recreated, it&#8217;s time to make it move. How do you control it as an actual effect, like shattering apart randomly, or deforming into square digital noise as it disappears?<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">For Those Who Want to Learn Practical &#8220;Look Recreation&#8221; and &#8220;Two Example Effects&#8221;!<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If this article made you think, &#8220;I want to use this base system in my own project!&#8221; or &#8220;I want to take this further and build a decomposition effect that&#8217;s actually good enough for a game, all the way to the end!&#8221;&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my online course on Coloso, I cover everything hands-on, from <strong>a more detailed explanation of the basics<\/strong> to what comes next: <strong>from &#8220;recreating the look&#8221; all the way to &#8220;building two example effects&#8221;<\/strong>!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udd3d Coloso course: Advanced VFX with Niagara \u00d7 Material \u2014 Learn from How It Works<br><a href=\"https:\/\/coloso.global\/en\/products\/vfxartist-heyyo-us\">https:\/\/coloso.global\/en\/products\/vfxartist-heyyo-us<\/a><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-x wp-block-embed-x\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"500\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\">The English subbed version of my class \u201cMastering the Mechanics of Advanced Niagara &amp; Material VFX&quot; is now up for pre-order on Coloso(<a href=\"https:\/\/x.com\/colosoglobal?ref_src=twsrc%5Etfw\">@colosoglobal<\/a>)<br><br>We&#39;ll learn how to enhance any gameplay experience with advanced, high-quality game VFX!<br><br>Link \u2192 <a href=\"https:\/\/t.co\/tUTQstjjHM\">https:\/\/t.co\/tUTQstjjHM<\/a><a href=\"https:\/\/x.com\/hashtag\/coloso?src=hash&amp;ref_src=twsrc%5Etfw\">#coloso<\/a> <a href=\"https:\/\/t.co\/ySXgSc75bQ\">pic.twitter.com\/ySXgSc75bQ<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/x.com\/yo_hanashima\/status\/2001834875842617482?ref_src=twsrc%5Etfw\">December 19, 2025<\/a><\/blockquote><script async src=\"https:\/\/platform.x.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">(The content of this article is covered in detail in <strong>Lessons 21\u201324<\/strong> of the course.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the course, you&#8217;ll learn not only exactly how to build the nodes for the &#8220;complex vector math in the Scratch Pad&#8221; I touched on here, but also a highly practical workflow for passing normals and textures to the material via render targets to <strong>&#8220;create the same look as the original mesh.&#8221;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, building on that system, we&#8217;ll create<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Example 1: A simple effect where the polygons break apart and scatter<\/li>\n\n\n\n<li>Example 2: An effect that deforms into squares and spins as it fades away digitally<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u2014two effects you can put to use in production right away, built together step by step!<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a136da7&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a136da7\" class=\"wp-block-image size-full wp-lightbox-container\"><img decoding=\"async\" width=\"400\" height=\"400\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/09a_example1_shatter.gif\" alt=\"\" class=\"wp-image-1711\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Example 1: The polygons break apart and scatter<\/figcaption><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ad952a1374ba&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ad952a1374ba\" class=\"wp-block-image size-full wp-lightbox-container\"><img decoding=\"async\" width=\"400\" height=\"400\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2026\/10\/09b_example2_digital.gif\" alt=\"\" class=\"wp-image-1712\"\/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Example 2: Deforms into squares and spins as it fades away digitally<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">For Those Who &#8220;Just Want to Look Inside the Finished Data!&#8221;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;I don&#8217;t have time to sit through a whole course!&#8221; &#8220;If I can see the finished data, I can figure out how the nodes are built myself!&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For anyone in that camp, I also sell the project data on its own on Gumroad.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udd3d Gumroad: Project Data<br><a href=\"https:\/\/heyyohanashima.gumroad.com\/l\/qmmmk\">https:\/\/heyyohanashima.gumroad.com\/l\/qmmmk<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to step beyond ordinary particle effects, I hope you&#8217;ll experience this advanced, highly adaptable system through the course or the project data!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Effects where a model breaks apart into its polygons have been around since older games like FF9, and back then they were most likely implemented by programmers making full use of shaders. To control polygon decomposition and deformation in a shader, you can implement it in the Geometry Shader stage, which works even in general-purpose [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1713,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","_locale":"en_US","_original_post":"https:\/\/heyyocg.link\/?p=1705","footnotes":""},"categories":[20,17,31],"tags":[32,15,30],"class_list":["post-1715","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ue4-tutorial","category-ue","category-ue4-tech-info","tag-niagara","tag-vfx","tag-tech-info","en-US"],"modified_by":"yohanashima","_links":{"self":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/comments?post=1715"}],"version-history":[{"count":2,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1715\/revisions"}],"predecessor-version":[{"id":1719,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1715\/revisions\/1719"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/media\/1713"}],"wp:attachment":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/media?parent=1715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/categories?post=1715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/tags?post=1715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}