{"id":654,"date":"2020-10-22T17:42:28","date_gmt":"2020-10-22T17:42:28","guid":{"rendered":"https:\/\/half4.xyz\/?p=654"},"modified":"2024-01-25T10:02:51","modified_gmt":"2024-01-25T10:02:51","slug":"character-clothing-part-3-ue4-shaders","status":"publish","type":"post","link":"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-part-3-ue4-shaders\/","title":{"rendered":"Character Clothing &#8211; Part 3: UE4 Shaders"},"content":{"rendered":"<h2 class=\"wp-block-heading\">Table of Contents<\/h2>\n<blockquote class=\"wp-embedded-content\" data-secret=\"CDWpVqdDdG\"><p><a href=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-zone-culling\/\">Character Clothing Zone Culling<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Character Clothing Zone Culling&#8221; &#8212; half4.xyz\" src=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-zone-culling\/embed\/#?secret=87dDB24m1i#?secret=CDWpVqdDdG\" data-secret=\"CDWpVqdDdG\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"gAdTmajuTa\"><p><a href=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-part-2-maya\/\">Character Clothing &#8211; Part 2: Maya<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Character Clothing &#8211; Part 2: Maya&#8221; &#8212; half4.xyz\" src=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-part-2-maya\/embed\/#?secret=2FqM9ma047#?secret=gAdTmajuTa\" data-secret=\"gAdTmajuTa\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"WXhfdAgq27\"><p><a href=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-part-3-ue4-shaders\/\">Character Clothing &#8211; Part 3: UE4 Shaders<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Character Clothing &#8211; Part 3: UE4 Shaders&#8221; &#8212; half4.xyz\" src=\"https:\/\/half4.xyz\/index.php\/2020\/10\/22\/character-clothing-part-3-ue4-shaders\/embed\/#?secret=q5iJ5FqyNN#?secret=WXhfdAgq27\" data-secret=\"WXhfdAgq27\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"ApGokkacfu\"><p><a href=\"https:\/\/half4.xyz\/index.php\/2020\/10\/26\/character-clothing-part-4-ue4-logic\/\">Character Clothing \u2013 Part 4: UE4 Logic<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Character Clothing \u2013 Part 4: UE4 Logic&#8221; &#8212; half4.xyz\" src=\"https:\/\/half4.xyz\/index.php\/2020\/10\/26\/character-clothing-part-4-ue4-logic\/embed\/#?secret=text8j1IzS#?secret=ApGokkacfu\" data-secret=\"ApGokkacfu\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<h2 class=\"wp-block-heading\">Unreal Engine 4<\/h2>\n<p>Now we move into the next stage. We now need to do the following:<\/p>\n<ol>\n<li>Create a shader than can dynamically cull mesh, based on a bitmask value<\/li>\n<li>Create a Blueprint that can send and update the bitmask value, based on user input<\/li>\n<li>Create a Blueprint that will propagate bitmask values so that layers of cloths all appropriately cull other meshes<\/li>\n<\/ol>\n<h3 class=\"wp-block-heading\">The Shader<\/h3>\n<p>We\u2019ll start by setting up a <em>Material <\/em>in Unreal that exposes the properties we need for each piece of clothing, then we\u2019ll create <em>Material Instances<\/em> off this for each piece of clothing\/mesh \u2013 this is standard practice in UE4.<\/p>\n<p>For Unity you would need to make a <em>Shader <\/em>using this approach, then create <em>Materials <\/em>using that base <em>Shader <\/em>for each mesh. Its the same process, just different terminology between the engines.<\/p>\n<p>Start off by adding Texture Parameters for each of your texture maps. You can do these however if you wish, i.e. if you have certain features such as re-colouring, etc., then add these in here.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"wp-image-626\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-1024x798.png\" sizes=\"(max-width: 1024px) 100vw, 1024px\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-1024x798.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-300x234.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-768x599.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-1536x1197.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-32-2048x1597.png 2048w\" alt=\"\" width=\"1024\" height=\"798\" \/>Basic Material implementation for the green t-shirt<\/p>\n<p>Next, create a Material Instance for every Material you need, then apply it to your meshes.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-628\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-1024x652.png\" sizes=\"(max-width: 1024px) 100vw, 1024px\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-1024x652.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-300x191.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-768x489.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-1536x979.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-33-2048x1305.png 2048w\" alt=\"\" width=\"1024\" height=\"652\" \/><\/p>\n<p>Here I have one Material for the skin, one base material for the clothing \u2013 all the clothing materials are instanced from this base material.<\/p>\n<p>Next, create a new Material Function, we\u2019ll call this \u201cMF_Cullzone\u201d.<\/p>\n<p>In this, create the following graph:<\/p>\n<p><img decoding=\"async\" class=\"wp-image-629\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34-1024x662.png\" sizes=\"(max-width: 1024px) 100vw, 1024px\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34-1024x662.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34-300x194.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34-768x497.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34-1536x993.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-34.png 1825w\" alt=\"\" width=\"1024\" height=\"662\" \/><\/p>\n<p>In the Custom node, add in the 3 Inputs you can see, then paste this code into the Custom node:<\/p>\n<pre class=\"wp-block-code\"><code>if(bitmask &gt; 0)\n{\n\t\/\/ 2^32 is the most we can do with a 32-bit signed integer\n\tint maxPower = 32;\n\tfloat uvCoordRange = 1.0 \/ maxPower;\n\tint a = int(bitmask);\n\tfor(int i = 0; i &lt; maxPower; i++)\n\t{\n\t\tif(a &amp; 1 &lt;&lt; i)\n\t\t{\n\t\t\tif(UV.x &gt; i * uvCoordRange &amp;&amp; UV.x &lt; (1 + i) * uvCoordRange)\n\t\t\t{\n\t\t\t\treturn worldPos \/ 0.0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nreturn worldPos;<\/code><code>\n<\/code><\/pre>\n<p>This code takes our bitmask value and checks to see if our UV sits within that value. For example, if our bitmask value is 3, this equates to:<br \/>\n0000 0000 0000 0000 0000 0000 0000 0011. We therefore check if our UV is in the first <em>or<\/em> second zone in our UV mask \u2013 UV.x range 0.0 \u2013 0.0625. If it is, we divide its position by 0.<\/p>\n<p>The \u201cWorld Position\u201d input node allows you to pass through an existing World Position Offset, in case you need to for a different effect.<\/p>\n<p>Save this Material Function and then hook it up into the World Position Offset node of all your base materials:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-630\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-35.png\" sizes=\"(max-width: 621px) 100vw, 621px\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-35.png 621w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-35-300x288.png 300w\" alt=\"\" width=\"621\" height=\"596\" \/><\/p>\n<p>Now head into your Material Instance and crank up\/down that bitmask value:<\/p>\n<figure class=\"wp-block-video\"><video src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/UV_Cull.mp4\" controls=\"controls\" width=\"300\" height=\"150\"><\/video><\/figure>\n<p>&nbsp;<\/p>\n<p>Here\u2019s a quick example of the values working:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-640\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-41-364x1024.png\" sizes=\"(max-width: 364px) 100vw, 364px\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-41-364x1024.png 364w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/10\/image-41.png 590w\" alt=\"\" width=\"364\" height=\"1024\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Now on to the final part:<\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"ApGokkacfu\"><p><a href=\"https:\/\/half4.xyz\/index.php\/2020\/10\/26\/character-clothing-part-4-ue4-logic\/\">Character Clothing \u2013 Part 4: UE4 Logic<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Character Clothing \u2013 Part 4: UE4 Logic&#8221; &#8212; half4.xyz\" src=\"https:\/\/half4.xyz\/index.php\/2020\/10\/26\/character-clothing-part-4-ue4-logic\/embed\/#?secret=text8j1IzS#?secret=ApGokkacfu\" data-secret=\"ApGokkacfu\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table of Contents Character Clothing Zone Culling Character Clothing &#8211; Part 2: Maya Character Clothing &#8211; Part 3: UE4 Shaders Character Clothing \u2013 Part 4: UE4 Logic Unreal Engine 4 Now we move into the next stage. We now need to do the following: Create a shader than can dynamically cull mesh, based on a bitmask value Create a Blueprint that can send and update the bitmask value, based on user input Create a Blueprint that will propagate bitmask values so that layers of cloths all appropriately cull other meshes The Shader We\u2019ll start by setting up a Material in Unreal that exposes the properties we need for each piece of clothing, then we\u2019ll create Material Instances off this for each piece of clothing\/mesh \u2013 this is standard practice in UE4. For Unity you would need to make a Shader using this approach, then create Materials using that base Shader for each mesh. Its the same process, just different terminology between the engines. Start off by adding Texture Parameters for each of your texture maps. You can do these however if you wish, i.e. if you have certain features such as re-colouring, etc., then add these in here. Basic Material implementation for the green t-shirt Next, create a Material Instance for every Material you need, then apply it to your meshes. Here I have one Material for the skin, one base material for the clothing \u2013 all the clothing materials are instanced from this base material. Next, create a new Material Function, we\u2019ll call this \u201cMF_Cullzone\u201d. In this, create the following graph: In the Custom node, add in the 3 Inputs you can see, then paste this code into the Custom node: if(bitmask &gt; 0) { \/\/ 2^32 is the most we can do with a 32-bit signed integer int maxPower = 32; float uvCoordRange = 1.0 \/ maxPower; int a = int(bitmask); for(int i = 0; i &lt; maxPower; i++) { if(a &amp; 1 &lt;&lt; i) { if(UV.x &gt; i * uvCoordRange &amp;&amp; UV.x &lt; (1 + i) * uvCoordRange) { return worldPos \/ 0.0; } } } } return worldPos; This code takes our bitmask value and checks to see if our UV sits within that value. For example, if our bitmask value is 3, this equates to: 0000 0000 0000 0000 0000 0000 0000 0011. We therefore check if our UV is in the first or second zone in our UV mask \u2013 UV.x range 0.0 \u2013 0.0625. If it is, we divide its position by 0. The \u201cWorld Position\u201d input node allows you to pass through an existing World Position Offset, in case you need to for a different effect. Save this Material Function and then hook it up into the World Position Offset node of all your base materials: Now head into your Material Instance and crank up\/down that bitmask value: &nbsp; Here\u2019s a quick example of the values working: &nbsp; Now on to the final part: Character Clothing \u2013 Part 4: UE4 Logic &nbsp;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-654","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/654"}],"collection":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=654"}],"version-history":[{"count":4,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/654\/revisions"}],"predecessor-version":[{"id":1272,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/654\/revisions\/1272"}],"wp:attachment":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}