make_mesh_preview.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. let make_mesh_preview_opacity_discard_decal: f32 = 0.05;
  2. function make_mesh_preview_run(data: material_t, matcon: material_context_t): node_shader_context_t {
  3. let context_id: string = "mesh";
  4. let props: shader_context_t = {
  5. name: context_id,
  6. depth_write: true,
  7. compare_mode: "less",
  8. cull_mode: "clockwise",
  9. vertex_elements: [
  10. {
  11. name: "pos",
  12. data: "short4norm"
  13. },
  14. {
  15. name: "nor",
  16. data: "short2norm"
  17. },
  18. {
  19. name: "tex",
  20. data: "short2norm"
  21. }
  22. ],
  23. color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
  24. depth_attachment: "DEPTH32"
  25. };
  26. let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
  27. let vert: node_shader_t = node_shader_context_make_vert(con_mesh);
  28. let frag: node_shader_t = node_shader_context_make_frag(con_mesh);
  29. frag.ins = vert.outs;
  30. let pos: string = "pos";
  31. ///if arm_skin
  32. let skin: bool = mesh_data_get_vertex_array(context_raw.paint_object.data, "bone") != null;
  33. if (skin) {
  34. pos = "spos";
  35. node_shader_context_add_elem(con_mesh, "bone", "short4norm");
  36. node_shader_context_add_elem(con_mesh, "weight", "short4norm");
  37. node_shader_add_function(vert, str_get_skinning_dual_quat);
  38. node_shader_add_uniform(vert, "vec4 skinBones[128 * 2]", "_skin_bones");
  39. node_shader_add_uniform(vert, "float posUnpack", "_pos_unpack");
  40. node_shader_write_attrib(vert, "vec4 skinA;");
  41. node_shader_write_attrib(vert, "vec4 skinB;");
  42. node_shader_write_attrib(vert, "getSkinningDualQuat(ivec4(bone * 32767), weight, skinA, skinB);");
  43. node_shader_write_attrib(vert, "vec3 spos = pos.xyz;");
  44. node_shader_write_attrib(vert, "spos.xyz *= posUnpack;");
  45. node_shader_write_attrib(vert, "spos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, spos.xyz) + skinA.w * spos.xyz);");
  46. node_shader_write_attrib(vert, "spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz));");
  47. node_shader_write_attrib(vert, "spos.xyz /= posUnpack;");
  48. }
  49. ///end
  50. node_shader_add_uniform(vert, "mat4 WVP", "_world_view_proj_matrix");
  51. node_shader_write_attrib(vert, "gl_Position = mul(vec4(" + pos + ".xyz, 1.0), WVP);");
  52. let brush_scale: string = (context_raw.brush_scale * context_raw.brush_nodes_scale) + "";
  53. node_shader_add_out(vert, "vec2 texCoord");
  54. node_shader_write_attrib(vert, "texCoord = tex * float(" + brush_scale + ");");
  55. let decal: bool = context_raw.decal_preview;
  56. parser_material_sample_keep_aspect = decal;
  57. parser_material_sample_uv_scale = brush_scale;
  58. parser_material_parse_height = make_material_height_used;
  59. parser_material_parse_height_as_channel = true;
  60. let sout: shader_out_t = parser_material_parse(ui_nodes_get_canvas_material(), con_mesh, vert, frag, matcon);
  61. parser_material_parse_height = false;
  62. parser_material_parse_height_as_channel = false;
  63. parser_material_sample_keep_aspect = false;
  64. let base: string = sout.out_basecol;
  65. let rough: string = sout.out_roughness;
  66. let met: string = sout.out_metallic;
  67. let occ: string = sout.out_occlusion;
  68. let opac: string = sout.out_opacity;
  69. let height: string = sout.out_height;
  70. let nortan: string = parser_material_out_normaltan;
  71. node_shader_write(frag, "vec3 basecol = pow(" + base + ", vec3(2.2, 2.2, 2.2));");
  72. node_shader_write(frag, "float roughness = " + rough + ";");
  73. node_shader_write(frag, "float metallic = " + met + ";");
  74. node_shader_write(frag, "float occlusion = " + occ + ";");
  75. node_shader_write(frag, "float opacity = " + opac + ";");
  76. node_shader_write(frag, "vec3 nortan = " + nortan + ";");
  77. node_shader_write(frag, "float height = " + height + ";");
  78. // parse_height_as_channel = false;
  79. // write(vert, "float vheight = " + height + ";");
  80. // add_out(vert, "float height");
  81. // write(vert, "height = vheight;");
  82. // let displaceStrength: f32 = 0.1;
  83. // if (heightUsed && displaceStrength > 0.0) {
  84. // write(vert, "vec3 pos2 = " + pos + ".xyz + vec3(nor.xy, pos.w) * vec3(" + height + ", " + height + ", " + height + ") * vec3(" + displaceStrength + ", " + displaceStrength + ", " + displaceStrength + ");");
  85. // write(vert, "gl_Position = mul(vec4(pos2.xyz, 1.0), WVP);");
  86. // }
  87. if (decal) {
  88. if (context_raw.tool == workspace_tool_t.TEXT) {
  89. node_shader_add_uniform(frag, "sampler2D textexttool", "_textexttool");
  90. node_shader_write(frag, "opacity *= textureLod(textexttool, texCoord / float(" + brush_scale + "), 0.0).r;");
  91. }
  92. }
  93. if (decal) {
  94. let opac: f32 = make_mesh_preview_opacity_discard_decal;
  95. node_shader_write(frag, "if (opacity < " + opac + ") discard;");
  96. }
  97. node_shader_add_out(frag, "vec4 fragColor[3]");
  98. frag.n = true;
  99. node_shader_add_function(frag, str_pack_float_int16);
  100. node_shader_add_function(frag, str_cotangent_frame);
  101. node_shader_add_function(frag, str_octahedron_wrap);
  102. if (make_material_height_used) {
  103. node_shader_write(frag, "if (height > 0.0) {");
  104. node_shader_write(frag, "float height_dx = dFdx(height * 2.0);");
  105. node_shader_write(frag, "float height_dy = dFdy(height * 2.0);");
  106. // write(frag, "float height_dx = height0 - height1;");
  107. // write(frag, "float height_dy = height2 - height3;");
  108. // Whiteout blend
  109. node_shader_write(frag, "vec3 n1 = nortan * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);");
  110. node_shader_write(frag, "vec3 n2 = normalize(vec3(height_dx * 16.0, height_dy * 16.0, 1.0));");
  111. node_shader_write(frag, "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);");
  112. node_shader_write(frag, "}");
  113. }
  114. // Apply normal channel
  115. if (decal) {
  116. // TODO
  117. }
  118. else {
  119. frag.vvec = true;
  120. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  121. node_shader_write(frag, "mat3 TBN = cotangentFrame(n, vVec, texCoord);");
  122. ///else
  123. node_shader_write(frag, "mat3 TBN = cotangentFrame(n, -vVec, texCoord);");
  124. ///end
  125. node_shader_write(frag, "n = nortan * 2.0 - 1.0;");
  126. node_shader_write(frag, "n.y = -n.y;");
  127. node_shader_write(frag, "n = normalize(mul(n, TBN));");
  128. }
  129. node_shader_write(frag, "n /= (abs(n.x) + abs(n.y) + abs(n.z));");
  130. node_shader_write(frag, "n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);");
  131. // uint matid = 0;
  132. if (decal) {
  133. node_shader_write(frag, "fragColor[0] = vec4(n.x, n.y, roughness, packFloatInt16(metallic, uint(0)));"); // metallic/matid
  134. node_shader_write(frag, "fragColor[1] = vec4(basecol, occlusion);");
  135. }
  136. else {
  137. node_shader_write(frag, "fragColor[0] = vec4(n.x, n.y, mix(1.0, roughness, opacity), packFloatInt16(mix(1.0, metallic, opacity), uint(0)));"); // metallic/matid
  138. node_shader_write(frag, "fragColor[1] = vec4(mix(vec3(0.0, 0.0, 0.0), basecol, opacity), occlusion);");
  139. }
  140. node_shader_write(frag, "fragColor[2] = vec4(0.0, 0.0, 0.0, 0.0);"); // veloc
  141. parser_material_finalize(con_mesh);
  142. ///if arm_skin
  143. if (skin) {
  144. node_shader_write(vert, "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));");
  145. }
  146. ///end
  147. con_mesh.data.shader_from_source = true;
  148. con_mesh.data.vertex_shader = node_shader_get(vert);
  149. con_mesh.data.fragment_shader = node_shader_get(frag);
  150. return con_mesh;
  151. }