{"id":1492,"date":"2024-11-20T00:02:12","date_gmt":"2024-11-19T15:02:12","guid":{"rendered":"https:\/\/heyyocg.link\/?p=1492"},"modified":"2024-11-20T00:37:51","modified_gmt":"2024-11-19T15:37:51","slug":"geometry-shader-kind-houdini-sop","status":"publish","type":"post","link":"https:\/\/heyyocg.link\/en\/geometry-shader-kind-houdini-sop\/","title":{"rendered":"Houdini Polygon Deform VFX"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>The VFX explained here is inspired by one of <a href=\"https:\/\/radiumsoftware.tumblr.com\/archive\" data-type=\"link\" data-id=\"https:\/\/radiumsoftware.tumblr.com\/archive\">Keijiro&#8217;s works<\/a>, which implements cool deforming character visual effects with Geometry Shader in Unity.<\/p>\n\n\n\n<p>I also imitated those works in Unity before like below.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-2 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"480\" height=\"272\" data-id=\"623\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/VoxelSizeAnimation.gif\" alt=\"\" class=\"wp-image-623\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"368\" height=\"208\" data-id=\"624\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/VoxelTeleporter.gif\" alt=\"\" class=\"wp-image-624\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"368\" height=\"208\" data-id=\"625\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/VoxelTeleporter2.gif\" alt=\"\" class=\"wp-image-625\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"320\" height=\"180\" data-id=\"622\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/Bandlizer.gif\" alt=\"\" class=\"wp-image-622\"\/><\/figure>\n<figcaption class=\"blocks-gallery-caption wp-element-caption\">Previuos Works in Unity<br><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/YoHana19\/VoxelSizeAnimation\" target=\"_blank\">https:\/\/github.com\/YoHana19\/VoxelSizeAnimation<\/a><br><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/YoHana19\/VoxelTeleporter\" target=\"_blank\">https:\/\/github.com\/YoHana19\/VoxelTeleporter<\/a><br><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/YoHana19\/VoxelTeleporter2\" target=\"_blank\">https:\/\/github.com\/YoHana19\/VoxelTeleporter2<\/a><br><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/YoHana19\/Bandlizer\" target=\"_blank\">https:\/\/github.com\/YoHana19\/Bandlizer<\/a><\/figcaption><\/figure>\n\n\n\n<p>This time, I decided to reproduce them with Houdini and created the first three effects listed above.<\/p>\n\n\n\n<blockquote class=\"twitter-tweet\" data-media-max-width=\"560\"><p lang=\"ja\" dir=\"ltr\">\u30a2\u30c9\u30d9\u30f3\u30c8\u30ab\u30ec\u30f3\u30c0\u30fc\u7528\u2460<br>Keijiro\u795e\u306e\u4f5c\u4f8b\u3092Houdini\u3067\u518d\u73fe<a href=\"https:\/\/twitter.com\/hashtag\/Houdini?src=hash&amp;ref_src=twsrc%5Etfw\">#Houdini<\/a> <a href=\"https:\/\/t.co\/gzYylIdSZz\">pic.twitter.com\/gzYylIdSZz<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/twitter.com\/yo_hanashima\/status\/1471717112083533824?ref_src=twsrc%5Etfw\">December 17, 2021<\/a><\/blockquote> <script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n\n\n\n<blockquote class=\"twitter-tweet\" data-media-max-width=\"560\"><p lang=\"ja\" dir=\"ltr\">\u30a2\u30c9\u30d9\u30f3\u30c8\u30ab\u30ec\u30f3\u30c0\u30fc\u7528\u2461<br>Keijiro\u795e\u306e\u4f5c\u4f8b\u3092Houdini\u3067\u518d\u73fe<a href=\"https:\/\/twitter.com\/hashtag\/Houdini?src=hash&amp;ref_src=twsrc%5Etfw\">#Houdini<\/a> <a href=\"https:\/\/t.co\/o3X56orD9F\">pic.twitter.com\/o3X56orD9F<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/twitter.com\/yo_hanashima\/status\/1471867691913068546?ref_src=twsrc%5Etfw\">December 17, 2021<\/a><\/blockquote> <script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n\n\n\n<blockquote class=\"twitter-tweet\" data-media-max-width=\"560\"><p lang=\"ja\" dir=\"ltr\">\u30a2\u30c9\u30d9\u30f3\u30c8\u30ab\u30ec\u30f3\u30c0\u30fc\u7528\u2462<br>Keijiro\u795e\u306e\u4f5c\u4f8b\u3092Houdini\u3067\u518d\u73fe<a href=\"https:\/\/twitter.com\/hashtag\/Houdini?src=hash&amp;ref_src=twsrc%5Etfw\">#Houdini<\/a> <a href=\"https:\/\/t.co\/qDJeDYTudP\">pic.twitter.com\/qDJeDYTudP<\/a><\/p>&mdash; HeyYo (@yo_hanashima) <a href=\"https:\/\/twitter.com\/yo_hanashima\/status\/1472080256240881670?ref_src=twsrc%5Etfw\">December 18, 2021<\/a><\/blockquote> <script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n\n\n\n<p>The actual working data is also available for purchase here, so feel free to check it out if you&#8217;re interested.<\/p>\n\n\n\n<p><a href=\"https:\/\/heyyohanashima.gumroad.com\/l\/svdbo\">https:\/\/heyyohanashima.gumroad.com\/l\/svdbo<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Overview<\/h2>\n\n\n\n<p>The concept behind the creation process for all the examples listed above is the same: it involves processing the triangular polygons that make up the geometry using a <code>foreach<\/code> loop, transforming them into shapes like squares, cubes, etc., one by one.<\/p>\n\n\n\n<p>At this stage, we make the size, center position, and deformation timing customizable for each primitive from the outside to create variations.<\/p>\n\n\n\n<p>So, I\u2019ll first explain the common transformation process for a single triangular polygon geometry before delving into each example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Transformation Process From Single Polygon <\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"863\" height=\"542\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-152852.png\" alt=\"\" class=\"wp-image-628\" style=\"width:432px;height:271px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-152852.png 863w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-152852-300x188.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-152852-768x482.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-152852-816x512.png 816w\" sizes=\"(max-width: 863px) 100vw, 863px\" \/><figcaption class=\"wp-element-caption\">A triangular polygon to transform<\/figcaption><\/figure><\/div>\n\n\n<p>There are three types of transformations: triangle transformation, square transformation, and cube transformation. The triangle transformation only alters the size of the triangular shape. In this example, about 90% of the polygons simply shrink or enlarge and disappear or reappear. If all polygons were transformed into squares or cubes, the result would be a cluttered mess that\u2019s hard to see.<\/p>\n\n\n\n<p>These transformation processes are used in the actual examples, so I\u2019ve encapsulated them into a subnetwork.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Triangle Transformation<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-15-45-46_1.gif\" alt=\"\" class=\"wp-image-676\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"365\" height=\"426\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153409.png\" alt=\"\" class=\"wp-image-629\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153409.png 365w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153409-257x300.png 257w\" sizes=\"(max-width: 365px) 100vw, 365px\" \/><\/figure>\n\n\n\n<p>First, I check if the necessary attributes are present. The <code>tri_morph<\/code> attribute controls the distance of each vertex from the center of the polygon, which in turn controls the size of the triangular polygon.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"407\" height=\"201\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153531.png\" alt=\"\" class=\"wp-image-630\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153531.png 407w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153531-300x148.png 300w\" sizes=\"(max-width: 407px) 100vw, 407px\" \/><\/figure>\n\n\n\n<p>Using the &#8220;Extract Centroid&#8221; node, I store the centroid (the center of the polygon) in an attribute named <code>centroid<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"347\" height=\"151\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153555.png\" alt=\"\" class=\"wp-image-632\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153555.png 347w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153555-300x131.png 300w\" sizes=\"(max-width: 347px) 100vw, 347px\" \/><\/figure>\n\n\n\n<p>Then, by multiplying the <code>tri_morph<\/code> value by the vector from the centroid to each vertex, the size is controlled. When the <code>tri_morph<\/code> value is 0, the polygon becomes a point, so it is deleted.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"188\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153625.png\" alt=\"\" class=\"wp-image-633\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153625.png 400w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-153625-300x141.png 300w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Square Transformation<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-16-02-15_1.gif\" alt=\"\" class=\"wp-image-677\"\/><figcaption class=\"wp-element-caption\">pivot: (0,0,0)\u3001center: (-1,0,0)\u3001size: (1,1,1)<\/figcaption><\/figure>\n\n\n\n<p>This transformation is slightly customized to match the example. It is not entirely generalized. Specifically, the square shape is always aligned with the Y-axis, and the pivot and center positions are used to control the orientation of the face. More details follow.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"326\" height=\"416\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154714.png\" alt=\"\" class=\"wp-image-635\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154714.png 326w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154714-235x300.png 235w\" sizes=\"(max-width: 326px) 100vw, 326px\" \/><\/figure>\n\n\n\n<p>First, I check the required attributes. The attributes used for control are below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"538\" height=\"200\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154809.png\" alt=\"\" class=\"wp-image-637\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154809.png 538w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-154809-300x112.png 300w\" sizes=\"(max-width: 538px) 100vw, 538px\" \/><figcaption class=\"wp-element-caption\">quad_morph: Controls the degree of transformation (0 = triangle, 1 = square)<br>quad_size: The size of the square<br>quad_pivot: The starting point of the direction vector for the face<br>quad_center] The position of the center of the square<\/figcaption><\/figure>\n\n\n\n<p>Next, I add one point and transform the polygon into a square by adding the new point to the polygon\u2019s vertices. The position and UV values can be chosen arbitrarily. For this example, I added the point at the position of the second vertex and used the UV of the first vertex for the new square&#8217;s UV.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"325\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162355.png\" alt=\"\" class=\"wp-image-641\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162355.png 473w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162355-300x206.png 300w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><\/figure>\n\n\n\n<p>For each vertex, I decide the direction (in tangent space) from the center and store it in <code>tan_dir<\/code>. This can be chosen arbitrarily, but the key is ensuring that the vertices are ordered in a clockwise direction to maintain the correct orientation of the polygon.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"630\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-161436.png\" alt=\"\" class=\"wp-image-639\" style=\"width:395px;height:315px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-161436.png 790w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-161436-300x239.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-161436-768x612.png 768w\" sizes=\"(max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p>I then proceed with the transformation. First, I compute the direction from the center to each vertex in world space (converting the tangent XYZ directions to world space).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"594\" height=\"308\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162649.png\" alt=\"\" class=\"wp-image-642\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162649.png 594w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-162649-300x156.png 300w\" sizes=\"(max-width: 594px) 100vw, 594px\" \/><\/figure>\n\n\n\n<p>The tangent Y direction (<code>wld_tan_y<\/code>) is parallel to the Y-axis, so it is set to (0, 1, 0).<\/p>\n\n\n\n<p>The tangent Z direction (<code>wld_tan_z<\/code>) is determined by the vector from the pivot to the center (ignoring the Y-axis since it must remain parallel to the Y-axis). This ensures the square faces outward from the pivot.<\/p>\n\n\n\n<p>The tangent X direction (<code>wld_tan_x<\/code>) is calculated by taking the cross product of <code>wld_tan_x<\/code> and <code>wld_tan_z<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"866\" height=\"633\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-163238.png\" alt=\"\" class=\"wp-image-643\" style=\"width:433px;height:317px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-163238.png 866w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-163238-300x219.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-163238-768x561.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-163238-816x596.png 816w\" sizes=\"(max-width: 866px) 100vw, 866px\" \/><\/figure>\n\n\n\n<p>Using these results, I multiply the precomputed <code>tan_dir<\/code> by the vectors, add the center position, and compute the position of each vertex in world space. The size of the square can be controlled by multiplying the result by the <code>size<\/code> vector.<\/p>\n\n\n\n<p>Finally, I interpolate between the original position and the square position to control the degree of transformation.<\/p>\n\n\n\n<p>Afterward, I fuse any overlapping points to ensure clean geometry.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cube Transformation<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-17-46-16_1.gif\" alt=\"\" class=\"wp-image-678\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"585\" height=\"790\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-164907.png\" alt=\"\" class=\"wp-image-645\" style=\"width:439px;height:593px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-164907.png 585w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-164907-222x300.png 222w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><\/figure>\n\n\n\n<p>This process is a bit more complex, especially when it comes to matching up the newly created vertices with the original vertices.<\/p>\n\n\n\n<p>First, I check the required attributes as same as others.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"186\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165254.png\" alt=\"\" class=\"wp-image-647\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165254.png 525w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165254-300x106.png 300w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><figcaption class=\"wp-element-caption\">cube_scale: Controls the size of the cube<br>cube_morph: Controls the degree of transformation (0 = triangle, 1 = cube)<br>cube_offset: The offset from the center of the original polygon<\/figcaption><\/figure>\n\n\n\n<p>These attributes are moved into detail attributes, and the average distance from the center to each vertex is also stored in detail attributes to reflect the original polygon size to scale the cube after transformation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"464\" height=\"183\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165309.png\" alt=\"\" class=\"wp-image-648\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165309.png 464w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165309-300x118.png 300w\" sizes=\"(max-width: 464px) 100vw, 464px\" \/><figcaption class=\"wp-element-caption\">Extract the center of the polygon<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"698\" height=\"284\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165325.png\" alt=\"\" class=\"wp-image-649\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165325.png 698w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165325-300x122.png 300w\" sizes=\"(max-width: 698px) 100vw, 698px\" \/><figcaption class=\"wp-element-caption\">Compute the average distance to each vertex (stored as the <code>size<\/code> attribute).<\/figcaption><\/figure>\n\n\n\n<p>Next, I will add 8 points using the &#8220;Add&#8221; node, set their original positions (corresponding to one of the vertices of the original triangular polygon) as well as their deformed positions, and create polygons for each face of the cube.<\/p>\n\n\n\n<p>There are a couple of important considerations:<\/p>\n\n\n\n<ol>\n<li><strong>Vertex Order<\/strong>: The direction of the polygon&#8217;s face is determined by the clockwise order of the vertices, so I must be careful to maintain the correct order when creating the polygons.<\/li>\n\n\n\n<li><strong>Mapping Original to New Vertices<\/strong>: Each cube face must map to the original triangular vertices in such a way that all three vertices of the original triangle are included in each cube face.<\/li>\n<\/ol>\n\n\n\n<p>\u4eca\u56de\u306f\u3001\u4e0b\u306e\u5199\u771f\u306b\u306a\u308b\u3088\u3046\u306b\u5404\u7a2e\u8a2d\u5b9a\u3057\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"663\" height=\"589\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-173022.png\" alt=\"\" class=\"wp-image-650\" style=\"width:497px;height:442px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-173022.png 663w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-173022-300x267.png 300w\" sizes=\"(max-width: 663px) 100vw, 663px\" \/><figcaption class=\"wp-element-caption\">Blue Number: Point Index<br>Red Number: Vertex Index of Original Polygon<\/figcaption><\/figure>\n\n\n\n<p>I create a <code>origin<\/code> attribute on the new vertices to store the positions of the original vertices. I then add the <code>cube_offset<\/code> to the center position and multiply the <code>cube_scale<\/code> by the size of the original polygon to determine the size of the cube.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"379\" height=\"344\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165344.png\" alt=\"\" class=\"wp-image-651\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165344.png 379w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165344-300x272.png 300w\" sizes=\"(max-width: 379px) 100vw, 379px\" \/><\/figure>\n\n\n\n<p>The direction of each vertex from the center is calculated, scaled by the <code>cube_scale<\/code>, and added to the center to determine the final position of each vertex in the cube, which is stored as. <code>goal<\/code> attribute.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"557\" height=\"283\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165357.png\" alt=\"\" class=\"wp-image-652\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165357.png 557w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165357-300x152.png 300w\" sizes=\"(max-width: 557px) 100vw, 557px\" \/><\/figure>\n\n\n\n<p>Finally, I select the vertices to create the cube faces, ensuring that the vertices are ordered in a clockwise direction for proper polygon orientation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"211\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165416.png\" alt=\"\" class=\"wp-image-653\"\/><\/figure>\n\n\n\n<p>I also apply UV2 to each face of the cube to calculate emission mask later.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"398\" height=\"192\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165451.png\" alt=\"\" class=\"wp-image-654\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165451.png 398w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165451-300x145.png 300w\" sizes=\"(max-width: 398px) 100vw, 398px\" \/><\/figure>\n\n\n\n<p>To transfer the attributes from the original polygon, I will first move each vertex to the origin position, then use attribute transfer to transfer the attributes. (This step is optional.)<\/p>\n\n\n\n<p>Finally, I will lerp the positions of the origin and goal using <code>cube_morph<\/code> to control the deformation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"336\" height=\"162\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165538.png\" alt=\"\" class=\"wp-image-656\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165538.png 336w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-165538-300x145.png 300w\" sizes=\"(max-width: 336px) 100vw, 336px\" \/><\/figure>\n\n\n\n<p>Note that the cube transformation process may not be perfectly smooth in this approach, so there could be a better way to achieve smoother results.<\/p>\n\n\n\n<p>With the explanation of the common transformation process complete, I will now move on to explaining each example. The focus will be on how to animate the parameters that can be controlled externally in the deformation process to achieve the effects seen in the examples.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example1: Quad Teleport<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-17-57-10.gif\" alt=\"\" class=\"wp-image-679\"\/><\/figure>\n\n\n\n<p>I\u2019ll start with some preparation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"428\" height=\"471\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180823.png\" alt=\"\" class=\"wp-image-661\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180823.png 428w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180823-273x300.png 273w\" sizes=\"(max-width: 428px) 100vw, 428px\" \/><\/figure>\n\n\n\n<p>First, I divide the <code>rubbertoy<\/code> into triangular polygons.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"713\" height=\"594\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180232.png\" alt=\"\" class=\"wp-image-659\" style=\"width:357px;height:297px\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180232.png 713w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180232-300x250.png 300w\" sizes=\"(max-width: 713px) 100vw, 713px\" \/><\/figure>\n\n\n\n<p>Next, I create a <code>morph<\/code> attribute, which will be used to control the degree of transformation during the deformation process.<\/p>\n\n\n\n<p>This is done by animating two planes moving from top to bottom. When the <code>y<\/code> position of a primitive is between the two planes, the <code>morph<\/code> value changes from 0 to 1.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-20-29-11.gif\" alt=\"\" class=\"wp-image-696\"\/><\/figure>\n\n\n\n<p>Therefore, when the lower plane passes, the effect starts (<code>morph=0<\/code>), and when the upper plane passes, it ends (<code>morph=1<\/code>).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"248\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-181622.png\" alt=\"\" class=\"wp-image-663\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-181622.png 414w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-181622-300x180.png 300w\" sizes=\"(max-width: 414px) 100vw, 414px\" \/><\/figure>\n\n\n\n<p>The <code>set_group<\/code> node groups the triangles into two groups: one that shrinks and disappears and one that transforms into squares. Around 96% of the polygons will shrink and disappear.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"368\" height=\"368\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180450.png\" alt=\"\" class=\"wp-image-660\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180450.png 368w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180450-300x300.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180450-150x150.png 150w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-180450-88x88.png 88w\" sizes=\"(max-width: 368px) 100vw, 368px\" \/><\/figure>\n\n\n\n<p>I&#8217;ll store the <code>primnum<\/code> as an <code>id<\/code> for convenience when applying colors or other attributes later.<\/p>\n\n\n\n<p>Now, let&#8217;s move on to explaining the control of the deformation parameters.<\/p>\n\n\n\n<p>The triangle transformation is simple. I subtract the <code>morph<\/code> value from 1 and assign it to the <code>tri_morph<\/code> attribute to control the transformation for each primitive.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-17-58-58.gif\" alt=\"\" class=\"wp-image-680\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"336\" height=\"463\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182051.png\" alt=\"\" class=\"wp-image-664\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182051.png 336w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182051-218x300.png 218w\" sizes=\"(max-width: 336px) 100vw, 336px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"287\" height=\"140\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182124.png\" alt=\"\" class=\"wp-image-665\"\/><\/figure>\n\n\n\n<p>Next, for the square deformation, I&#8217;ve also included an effect at the beginning where the triangular polygon is expanded, so triangle deformation is used a little as well. I&#8217;ll explain everything step by step, including that.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-17-59-14.gif\" alt=\"\" class=\"wp-image-681\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"245\" height=\"763\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182727.png\" alt=\"\" class=\"wp-image-666\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182727.png 245w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-182727-96x300.png 96w\" sizes=\"(max-width: 245px) 100vw, 245px\" \/><\/figure>\n\n\n\n<p>First, let&#8217;s control the <code>quad_pivot<\/code>. In this example, <code>quad_pivot<\/code> is used as the center point around which the square rotates. Since the rubbertoy model has a significantly different center point on the XZ plane for its top part, I use a plane animated for the morph effect to cut the rubbertoy, then calculate the center point for each frame and connect them into a line.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"757\" height=\"561\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183355.png\" alt=\"\" class=\"wp-image-667\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183355.png 757w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183355-300x222.png 300w\" sizes=\"(max-width: 757px) 100vw, 757px\" \/><\/figure>\n\n\n\n<p>For this line, I perform a <code>nearpoint<\/code> operation on each primitive to determine the closest point&#8217;s position, which is then assigned to the <code>quad_pivot<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"311\" height=\"180\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183426.png\" alt=\"\" class=\"wp-image-668\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183426.png 311w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183426-300x174.png 300w\" sizes=\"(max-width: 311px) 100vw, 311px\" \/><\/figure>\n\n\n\n<p>Next, to scale up the triangular polygon at the beginning, I set the value of <code>tri_morph<\/code> using <code>inflation_morph<\/code>. By controlling the ramp value, I create the initial expansion effect.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"555\" height=\"152\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183445.png\" alt=\"\" class=\"wp-image-669\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183445.png 555w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183445-300x82.png 300w\" sizes=\"(max-width: 555px) 100vw, 555px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"848\" height=\"388\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225534.png\" alt=\"\" class=\"wp-image-700\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225534.png 848w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225534-300x137.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225534-768x351.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225534-816x373.png 816w\" sizes=\"(max-width: 848px) 100vw, 848px\" \/><\/figure>\n\n\n\n<p>Then, using <code>set_quad_center<\/code>, I define the position of the square&#8217;s center, <code>quad_center<\/code>. I calculate vectors from the <code>quad_pivot<\/code> position to each primitive, and use the ramp-controlled <code>morph<\/code> value to rotate them. Additionally, I use the ramp-controlled <code>morph<\/code> value to control the distance from the <code>quad_pivot<\/code>, which animates <code>quad_center<\/code> moving away from the pivot while rotating in sync with the morph effect.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"533\" height=\"360\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-184423.png\" alt=\"\" class=\"wp-image-671\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-184423.png 533w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-184423-300x203.png 300w\" sizes=\"(max-width: 533px) 100vw, 533px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"758\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643-1024x758.png\" alt=\"\" class=\"wp-image-701\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643-1024x758.png 1024w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643-300x222.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643-768x568.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643-816x604.png 816w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225643.png 1035w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>For <code>quad_size<\/code>, I control the ramp so that it ultimately reduces to 0, creating an animation where it disappears at the end.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"182\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183653.png\" alt=\"\" class=\"wp-image-672\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183653.png 512w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-183653-300x107.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"842\" height=\"383\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225707.png\" alt=\"\" class=\"wp-image-702\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225707.png 842w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225707-300x136.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225707-768x349.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225707-816x371.png 816w\" sizes=\"(max-width: 842px) 100vw, 842px\" \/><\/figure>\n\n\n\n<p>Finally, I control the value of <code>quad_morph<\/code> using the original <code>morph<\/code> value and the ramp, adjusting it so that the square transformation is completed around the middle of the animation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"345\" height=\"127\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185101.png\" alt=\"\" class=\"wp-image-673\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185101.png 345w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185101-300x110.png 300w\" sizes=\"(max-width: 345px) 100vw, 345px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"347\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225722.png\" alt=\"\" class=\"wp-image-703\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225722.png 838w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225722-300x124.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225722-768x318.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-225722-816x338.png 816w\" sizes=\"(max-width: 838px) 100vw, 838px\" \/><\/figure>\n\n\n\n<p>With all the parameters set, I will now apply the triangle and square deformation processes to each primitive.<\/p>\n\n\n\n<p>Since the deformation process can be heavy, I will cache it, and then adjust the look by setting necessary parameters like Color and Emission to match the morph values before finishing.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"327\" height=\"372\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185439.png\" alt=\"\" class=\"wp-image-674\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185439.png 327w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-185439-264x300.png 264w\" sizes=\"(max-width: 327px) 100vw, 327px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Example2: Voxel Animation<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-19-15-15.gif\" alt=\"\" class=\"wp-image-692\"\/><\/figure>\n\n\n\n<p>This example is quite simple, and since the control of the <code>morph<\/code> and the separation of triangle and cube deformations are almost the same as in Example 1, I will skip those details.<\/p>\n\n\n\n<p>The key part is how to animate the <code>cube_scale<\/code>, so I will explain that. It&#8217;s not very complex \u2014 I use the UV values of three vertices as seeds, animate each axis (x, y, z) with sine functions, multiply them by an appropriate scale, and then set the result to <code>cube_scale<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"494\" height=\"330\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-192835.png\" alt=\"\" class=\"wp-image-682\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-192835.png 494w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-192835-300x200.png 300w\" sizes=\"(max-width: 494px) 100vw, 494px\" \/><\/figure>\n\n\n\n<p>After that, I apply the cube deformation process to each primitive.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example3: Voxel Teleport<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"319\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/D__Houdini_GeometryShader.hiplc-Houdini-Indie-Limited-Commercial-19.0.383-Python-3-2021-12-18-19-15-42.gif\" alt=\"\" class=\"wp-image-693\"\/><\/figure>\n\n\n\n<p>This example is also similar to Example 1 in terms of the base morph control and the separation of triangle and cube deformations, so I will skip those details.<\/p>\n\n\n\n<p>The crucial part is controlling the animation of <code>cube_scale<\/code> and <code>cube_offset<\/code>, so I will explain that.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"317\" height=\"311\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193533.png\" alt=\"\" class=\"wp-image-683\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193533.png 317w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193533-300x294.png 300w\" sizes=\"(max-width: 317px) 100vw, 317px\" \/><\/figure>\n\n\n\n<p>First, in <code>cube_teleport_offset_scale<\/code>, I set the <code>cube_scale<\/code> and <code>cube_offset<\/code>. The animation starts with a tall cube falling from the top and gradually transforming into a regular cube, so I animate the values accordingly.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"684\" height=\"455\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-194255.png\" alt=\"\" class=\"wp-image-684\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-194255.png 684w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-194255-300x200.png 300w\" sizes=\"(max-width: 684px) 100vw, 684px\" \/><\/figure>\n\n\n\n<p>In this case, since the effect is to revert from the deformed state to the original, the <code>morph<\/code> value changes from 1 to 0. The <code>move<\/code> value, which controls the size of the offset and scale, changes from 1 to 0 as <code>morph<\/code> transitions from 1 to 0.75. This means that during the first quarter of the animation, the cube falls back to its original position.<\/p>\n\n\n\n<p>For the <code>scale<\/code>, the <code>y<\/code> value animates from a larger value to 1, while the <code>xz<\/code> values animate from 0 to 1, giving the effect of a tall cube gradually becoming a regular cube.<\/p>\n\n\n\n<p>I also introduce some noise to add variation to the animation.<\/p>\n\n\n\n<p>Next, I want to animate the size slightly during the brief period before the falling cube transforms back into a triangle, similar to Example 2. I do this by adjusting the <code>cube_scale<\/code> with <code>cube_scale_anim<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"455\" height=\"385\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193631.png\" alt=\"\" class=\"wp-image-686\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193631.png 455w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193631-300x254.png 300w\" sizes=\"(max-width: 455px) 100vw, 455px\" \/><\/figure>\n\n\n\n<p>Since the implementation is quite similar to Example 2, I\u2019ll skip the details, but essentially, after the cube finishes falling, I control the timing of the animation with a <code>ramp<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"819\" height=\"404\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193753.png\" alt=\"\" class=\"wp-image-687\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193753.png 819w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193753-300x148.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193753-768x379.png 768w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193753-816x403.png 816w\" sizes=\"(max-width: 819px) 100vw, 819px\" \/><\/figure>\n\n\n\n<p>I also control the timing of the deformation using the <code>ramp<\/code>, ensuring that the cube smoothly transitions back into the original triangle at the right moment.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"338\" height=\"172\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195255.png\" alt=\"\" class=\"wp-image-688\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195255.png 338w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195255-300x153.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"813\" height=\"363\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193727.png\" alt=\"\" class=\"wp-image-689\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193727.png 813w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193727-300x134.png 300w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-193727-768x343.png 768w\" sizes=\"(max-width: 813px) 100vw, 813px\" \/><\/figure>\n\n\n\n<p>Finally, I apply the triangle and cube deformation processes to each primitive.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"401\" height=\"304\" src=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195429.png\" alt=\"\" class=\"wp-image-690\" srcset=\"https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195429.png 401w, https:\/\/heyyocg.link\/wp-content\/uploads\/2021\/12\/2021-12-18-195429-300x227.png 300w\" sizes=\"(max-width: 401px) 100vw, 401px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Visual Adjustments<\/h2>\n\n\n\n<p>I won&#8217;t go into detailed explanations regarding the visual adjustments, so if you&#8217;re interested, please check the data I provide below.<\/p>\n\n\n\n<p><a href=\"https:\/\/heyyohanashima.gumroad.com\/l\/svdbo\">https:\/\/heyyohanashima.gumroad.com\/l\/svdbo<\/a><\/p>\n\n\n\n<p>Here, I&#8217;ll just provide a brief overview.<\/p>\n\n\n\n<p>I directly edited the materials inside the rubbertoy, adding only the emission values. Essentially, I used <code>uv2<\/code> and other attributes to create emission effects around the edges of the square and cube faces. For the voxel teleport, I set the entire surface to emit when the object first falls.<\/p>\n\n\n\n<p>The control of the emission values is also handled by adjusting the <code>morph<\/code> value using a ramp.<\/p>\n\n\n\n<p>For the glow effect, I applied it in post-processing using Houdini&#8217;s compositing tools. Since I didn&#8217;t know a good way to extract only the emission areas, I used a LumaMatte to isolate the high-luminance areas, applied a blur, and added the glow effect that way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>My first impression is that it&#8217;s <em>&#8220;heavy!&#8221;<\/em> haha.<br>If I had implemented this in Unity using Geometry Shader, it would have run smoothly in real-time, but it took about 15 minutes just to cache 180 frames&#8230;<\/p>\n\n\n\n<p>However, one thing I like about Houdini is that it works exactly as written. When you implement it in Geometry Shader, there are often parts that become black boxes and aren&#8217;t as clear. In contrast, Houdini follows the instructions precisely, which makes implementation much easier.<\/p>\n\n\n\n<p>Ultimately, the key is how you animate the parameters. For this example, I simply borrowed the ideas that Keijiro-sensei had already developed, so moving forward, I\u2019d like to see what variations I can come up with on my own. Whenever I feel like it, I\u2019ll challenge myself to explore new possibilities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The VFX explained here is inspired by one of Keijiro&#8217;s works, which implements cool deforming character visual effects with Geometry Shader in Unity. I also imitated those works in Unity before like below. This time, I decided to reproduce them with Houdini and created the first three effects listed above. \u30a2\u30c9\u30d9\u30f3\u30c8\u30ab\u30ec\u30f3\u30c0\u30fc\u7528\u2460Keijiro\u795e\u306e\u4f5c\u4f8b\u3092Houdini\u3067\u518d\u73fe#Houdini pic.twitter.com\/gzYylIdSZz &mdash; HeyYo [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":619,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"no","_lmt_disable":"","_mi_skip_tracking":false,"footnotes":"","_locale":"en_US","_original_post":"http:\/\/heyyocg.link\/?p=617"},"categories":[5,33],"tags":[15,30],"modified_by":"yohanashima","_links":{"self":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1492"}],"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=1492"}],"version-history":[{"count":5,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1492\/revisions"}],"predecessor-version":[{"id":1507,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/posts\/1492\/revisions\/1507"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/media\/619"}],"wp:attachment":[{"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/media?parent=1492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/categories?post=1492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/heyyocg.link\/wp-json\/wp\/v2\/tags?post=1492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}