make_mesh_preview.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. function make_mesh_preview_run(data: material_t, matcon: material_context_t): node_shader_context_t {
  2. let context_id: string = "mesh";
  3. let props: shader_context_t = {
  4. name : context_id,
  5. depth_write : true,
  6. compare_mode : "less",
  7. cull_mode : "clockwise",
  8. vertex_elements : [ {name : "pos", data : "short4norm"}, {name : "nor", data : "short2norm"}, {name : "tex", data : "short2norm"} ],
  9. color_attachments : [ "RGBA64", "RGBA64" ],
  10. depth_attachment : "D32"
  11. };
  12. let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
  13. let kong: node_shader_t = node_shader_context_make_kong(con_mesh);
  14. let pos: string = "input.pos";
  15. node_shader_add_constant(kong, "WVP: float4x4", "_world_view_proj_matrix");
  16. node_shader_write_attrib_vert(kong, "output.pos = constants.WVP * float4(" + pos + ".xyz, 1.0);");
  17. let sc: f32 = context_raw.brush_scale * context_raw.brush_nodes_scale;
  18. let brush_scale: string = sc + "";
  19. node_shader_add_out(kong, "tex_coord: float2");
  20. node_shader_write_attrib_vert(kong, "output.tex_coord = input.tex * float(" + brush_scale + ");");
  21. node_shader_write_attrib_frag(kong, "var tex_coord: float2 = input.tex_coord;");
  22. let decal: bool = context_raw.decal_preview;
  23. parser_material_sample_keep_aspect = decal;
  24. parser_material_sample_uv_scale = brush_scale;
  25. parser_material_parse_height = make_material_height_used;
  26. parser_material_parse_height_as_channel = true;
  27. let sout: shader_out_t = parser_material_parse(context_raw.material.canvas, con_mesh, kong, matcon);
  28. parser_material_parse_height = false;
  29. parser_material_parse_height_as_channel = false;
  30. parser_material_sample_keep_aspect = false;
  31. let base: string = sout.out_basecol;
  32. let rough: string = sout.out_roughness;
  33. let met: string = sout.out_metallic;
  34. let occ: string = sout.out_occlusion;
  35. let opac: string = sout.out_opacity;
  36. let height: string = sout.out_height;
  37. let nortan: string = parser_material_out_normaltan;
  38. node_shader_write_frag(kong, "var basecol: float3 = pow3(" + base + ", float3(2.2, 2.2, 2.2));");
  39. node_shader_write_frag(kong, "var roughness: float = " + rough + ";");
  40. node_shader_write_frag(kong, "var metallic: float = " + met + ";");
  41. node_shader_write_frag(kong, "var occlusion: float = " + occ + ";");
  42. node_shader_write_frag(kong, "var opacity: float = " + opac + ";");
  43. node_shader_write_frag(kong, "var nortan: float3 = " + nortan + ";");
  44. node_shader_write_frag(kong, "var height: float = " + height + ";");
  45. if (decal) {
  46. if (context_raw.tool == tool_type_t.TEXT) {
  47. node_shader_add_texture(kong, "textexttool", "_textexttool");
  48. node_shader_write_frag(kong, "opacity *= sample_lod(textexttool, sampler_linear, tex_coord / float(" + brush_scale + "), 0.0).r;");
  49. }
  50. }
  51. if (decal) {
  52. let opac: f32 = config_raw.brush_alpha_discard;
  53. node_shader_write_frag(kong, "if (opacity <= float(" + opac + ")) { discard; }");
  54. }
  55. kong.frag_out = "float4[2]";
  56. kong.frag_n = true;
  57. node_shader_add_function(kong, str_pack_float_int16);
  58. node_shader_add_function(kong, str_cotangent_frame);
  59. node_shader_add_function(kong, str_octahedron_wrap);
  60. // if (make_material_opac_used) {
  61. // kong.frag_wvpposition = true;
  62. // node_shader_add_function(kong, str_dither_bayer);
  63. // node_shader_write_frag(kong, "var fragcoord1: float2 = float2(input.wvpposition.x / input.wvpposition.w, input.wvpposition.y / input.wvpposition.w) * 0.5 + 0.5;");
  64. // node_shader_write_frag(kong, "var dither: float = dither_bayer(fragcoord1 * float2(256.0, 256.0));");
  65. // node_shader_write_frag(kong, "if (opacity < dither) { discard; }");
  66. // }
  67. if (make_material_height_used) {
  68. node_shader_write_frag(kong, "if (height > 0.0) {");
  69. node_shader_write_frag(kong, "var height_dx: float = ddx(height * 2.0);");
  70. node_shader_write_frag(kong, "var height_dy: float = ddy(height * 2.0);");
  71. // Whiteout blend
  72. node_shader_write_frag(kong, "var n1: float3 = nortan * float3(2.0, 2.0, 2.0) - float3(1.0, 1.0, 1.0);");
  73. node_shader_write_frag(kong, "var n2: float3 = normalize(float3(height_dx * 16.0, height_dy * 16.0, 1.0));");
  74. node_shader_write_frag(kong, "nortan = normalize(float3(n1.xy + n2.xy, n1.z * n2.z)) * float3(0.5, 0.5, 0.5) + float3(0.5, 0.5, 0.5);");
  75. node_shader_write_frag(kong, "}");
  76. }
  77. // Apply normal channel
  78. if (decal) {
  79. // TODO
  80. }
  81. else {
  82. kong.frag_vvec = true;
  83. node_shader_write_frag(kong, "var TBN: float3x3 = cotangent_frame(n, vvec, tex_coord);");
  84. node_shader_write_frag(kong, "n = nortan * 2.0 - 1.0;");
  85. node_shader_write_frag(kong, "n.y = -n.y;");
  86. node_shader_write_frag(kong, "n = normalize(TBN * n);");
  87. }
  88. node_shader_write_frag(kong, "n = n / (abs(n.x) + abs(n.y) + abs(n.z));");
  89. // node_shader_write_frag(kong, "n.xy = n.z >= 0.0 ? n.xy : octahedron_wrap(n.xy);");
  90. node_shader_write_frag(kong, "if (n.z < 0.0) { n.xy = octahedron_wrap(n.xy); }");
  91. // uint matid = uint(0);
  92. if (decal) {
  93. node_shader_write_frag(kong, "output[0] = float4(n.x, n.y, roughness, pack_f32_i16(metallic, uint(0)));"); // metallic/matid
  94. node_shader_write_frag(kong, "output[1] = float4(basecol, occlusion);");
  95. }
  96. else {
  97. node_shader_write_frag(
  98. kong, "output[0] = float4(n.x, n.y, lerp(1.0, roughness, opacity), pack_f32_i16(lerp(1.0, metallic, opacity), uint(0)));"); // metallic/matid
  99. node_shader_write_frag(kong, "output[1] = float4(lerp3(float3(0.0, 0.0, 0.0), basecol, opacity), occlusion);");
  100. }
  101. parser_material_finalize(con_mesh);
  102. con_mesh.data.shader_from_source = true;
  103. gpu_create_shaders_from_kong(node_shader_get(kong), ADDRESS(con_mesh.data.vertex_shader), ADDRESS(con_mesh.data.fragment_shader),
  104. ADDRESS(con_mesh.data._.vertex_shader_size), ADDRESS(con_mesh.data._.fragment_shader_size));
  105. return con_mesh;
  106. }