MakeMeshPreview.hx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package arm.node;
  2. import iron.object.MeshObject;
  3. import iron.data.SceneFormat;
  4. import arm.ui.UIHeader;
  5. import arm.ui.UINodes;
  6. import arm.shader.MaterialParser;
  7. import arm.shader.NodeShader;
  8. import arm.shader.NodeShaderData;
  9. import arm.shader.NodeShaderContext;
  10. import arm.shader.ShaderFunctions;
  11. import arm.Enums;
  12. class MakeMeshPreview {
  13. public static var opacityDiscardDecal = 0.05;
  14. public static function run(data: NodeShaderData, matcon: TMaterialContext): NodeShaderContext {
  15. var context_id = "mesh";
  16. var con_mesh: NodeShaderContext = data.add_context({
  17. name: context_id,
  18. depth_write: true,
  19. compare_mode: "less",
  20. cull_mode: "clockwise",
  21. vertex_elements: [{name: "pos", data: "short4norm"}, {name: "nor", data: "short2norm"}, {name: "tex", data: "short2norm"}],
  22. color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
  23. depth_attachment: "DEPTH32"
  24. });
  25. var vert = con_mesh.make_vert();
  26. var frag = con_mesh.make_frag();
  27. frag.ins = vert.outs;
  28. var pos = "pos";
  29. #if arm_skin
  30. var isMesh = Std.isOfType(Context.object, MeshObject);
  31. var skin = isMesh && cast(Context.object, MeshObject).data.geom.getVArray("bone") != null;
  32. if (skin) {
  33. pos = "spos";
  34. con_mesh.add_elem("bone", 'short4norm');
  35. con_mesh.add_elem("weight", 'short4norm');
  36. vert.add_function(ShaderFunctions.str_getSkinningDualQuat);
  37. vert.add_uniform('vec4 skinBones[128 * 2]', '_skinBones');
  38. vert.add_uniform('float posUnpack', '_posUnpack');
  39. vert.write_attrib('vec4 skinA;');
  40. vert.write_attrib('vec4 skinB;');
  41. vert.write_attrib('getSkinningDualQuat(ivec4(bone * 32767), weight, skinA, skinB);');
  42. vert.write_attrib('vec3 spos = pos.xyz;');
  43. vert.write_attrib('spos.xyz *= posUnpack;');
  44. vert.write_attrib('spos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, spos.xyz) + skinA.w * spos.xyz);');
  45. vert.write_attrib('spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz));');
  46. vert.write_attrib('spos.xyz /= posUnpack;');
  47. }
  48. #end
  49. vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
  50. vert.write_attrib('gl_Position = mul(vec4($pos.xyz, 1.0), WVP);');
  51. var brushScale = (Context.brushScale * Context.brushNodesScale) + "";
  52. vert.add_out('vec2 texCoord');
  53. vert.write_attrib('texCoord = tex * float(${brushScale});');
  54. var decal = Context.decalPreview;
  55. MaterialParser.sample_keep_aspect = decal;
  56. MaterialParser.sample_uv_scale = brushScale;
  57. MaterialParser.parse_height = MakeMaterial.heightUsed;
  58. MaterialParser.parse_height_as_channel = true;
  59. var sout = MaterialParser.parse(UINodes.inst.getCanvasMaterial(), con_mesh, vert, frag, matcon);
  60. MaterialParser.parse_height = false;
  61. MaterialParser.parse_height_as_channel = false;
  62. MaterialParser.sample_keep_aspect = false;
  63. var base = sout.out_basecol;
  64. var rough = sout.out_roughness;
  65. var met = sout.out_metallic;
  66. var occ = sout.out_occlusion;
  67. var opac = sout.out_opacity;
  68. var height = sout.out_height;
  69. var nortan = MaterialParser.out_normaltan;
  70. frag.write('vec3 basecol = pow($base, vec3(2.2, 2.2, 2.2));');
  71. frag.write('float roughness = $rough;');
  72. frag.write('float metallic = $met;');
  73. frag.write('float occlusion = $occ;');
  74. frag.write('float opacity = $opac;');
  75. frag.write('vec3 nortan = $nortan;');
  76. frag.write('float height = $height;');
  77. // MaterialParser.parse_height_as_channel = false;
  78. // vert.write('float vheight = $height;');
  79. // vert.add_out('float height');
  80. // vert.write('height = vheight;');
  81. // var displaceStrength = 0.1;
  82. // if (MakeMaterial.heightUsed && displaceStrength > 0.0) {
  83. // vert.write('vec3 pos2 = $pos.xyz + vec3(nor.xy, pos.w) * vec3($height, $height, $height) * vec3($displaceStrength, $displaceStrength, $displaceStrength);');
  84. // vert.write('gl_Position = mul(vec4(pos2.xyz, 1.0), WVP);');
  85. // }
  86. if (decal) {
  87. if (Context.tool == ToolText) {
  88. frag.add_uniform('sampler2D textexttool', '_textexttool');
  89. frag.write('opacity *= textureLod(textexttool, texCoord / float(${brushScale}), 0.0).r;');
  90. }
  91. }
  92. if (decal) {
  93. var opac = opacityDiscardDecal;
  94. frag.write('if (opacity < $opac) discard;');
  95. }
  96. frag.add_out('vec4 fragColor[3]');
  97. frag.n = true;
  98. frag.add_function(ShaderFunctions.str_packFloatInt16);
  99. frag.add_function(ShaderFunctions.str_cotangentFrame);
  100. frag.add_function(ShaderFunctions.str_octahedronWrap);
  101. if (MakeMaterial.heightUsed) {
  102. frag.write('if (height > 0.0) {');
  103. frag.write('float height_dx = dFdx(height * 2.0);');
  104. frag.write('float height_dy = dFdy(height * 2.0);');
  105. // frag.write('float height_dx = height0 - height1;');
  106. // frag.write('float height_dy = height2 - height3;');
  107. // Whiteout blend
  108. frag.write('vec3 n1 = nortan * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);');
  109. frag.write('vec3 n2 = normalize(vec3(height_dx * 16.0, height_dy * 16.0, 1.0));');
  110. frag.write('nortan = normalize(vec3(n1.xy + n2.xy, n1.z * n2.z)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);');
  111. frag.write('}');
  112. }
  113. // Apply normal channel
  114. if (decal) {
  115. // TODO
  116. }
  117. else {
  118. frag.vVec = true;
  119. #if (kha_direct3d11 || kha_direct3d12 || kha_metal || kha_vulkan)
  120. frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);');
  121. #else
  122. frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);');
  123. #end
  124. frag.write('n = nortan * 2.0 - 1.0;');
  125. frag.write('n.y = -n.y;');
  126. frag.write('n = normalize(mul(n, TBN));');
  127. }
  128. frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));');
  129. frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);');
  130. // uint matid = 0;
  131. if (decal) {
  132. frag.write('fragColor[0] = vec4(n.x, n.y, roughness, packFloatInt16(metallic, uint(0)));'); // metallic/matid
  133. frag.write('fragColor[1] = vec4(basecol, occlusion);');
  134. }
  135. else {
  136. frag.write('fragColor[0] = vec4(n.x, n.y, mix(1.0, roughness, opacity), packFloatInt16(mix(1.0, metallic, opacity), uint(0)));'); // metallic/matid
  137. frag.write('fragColor[1] = vec4(mix(vec3(0.0, 0.0, 0.0), basecol, opacity), occlusion);');
  138. }
  139. frag.write('fragColor[2] = vec4(0.0, 0.0, 0.0, 0.0);'); // veloc
  140. MaterialParser.finalize(con_mesh);
  141. #if arm_skin
  142. if (skin) {
  143. vert.write('wnormal = normalize(mul(vec3(nor.xy, pos.w) + 2.0 * cross(skinA.xyz, cross(skinA.xyz, vec3(nor.xy, pos.w)) + skinA.w * vec3(nor.xy, pos.w)), N));');
  144. }
  145. #end
  146. con_mesh.data.shader_from_source = true;
  147. con_mesh.data.vertex_shader = vert.get();
  148. con_mesh.data.fragment_shader = frag.get();
  149. return con_mesh;
  150. }
  151. }