make_brush.ts 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. function make_brush_run(vert: node_shader_t, frag: node_shader_t) {
  2. node_shader_write(frag, "float dist = 0.0;");
  3. if (context_raw.tool == workspace_tool_t.PARTICLE) {
  4. return;
  5. }
  6. let fill_layer: bool = context_raw.layer.fill_layer != null;
  7. let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT;
  8. if (decal && !fill_layer) {
  9. node_shader_write(frag, "if (decalMask.z > 0.0) {");
  10. }
  11. if (config_raw.brush_3d) {
  12. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  13. node_shader_write(frag, "float depth = textureLod(gbufferD, inp.xy, 0.0).r;");
  14. ///else
  15. node_shader_write(frag, "float depth = textureLod(gbufferD, vec2(inp.x, 1.0 - inp.y), 0.0).r;");
  16. ///end
  17. node_shader_add_uniform(frag, "mat4 invVP", "_inv_view_proj_matrix");
  18. node_shader_write(frag, "vec4 winp = vec4(vec2(inp.x, 1.0 - inp.y) * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);");
  19. node_shader_write(frag, "winp = mul(winp, invVP);");
  20. node_shader_write(frag, "winp.xyz /= winp.w;");
  21. frag.wposition = true;
  22. if (config_raw.brush_angle_reject || context_raw.xray) {
  23. node_shader_add_function(frag, str_octahedron_wrap);
  24. node_shader_add_uniform(frag, "sampler2D gbuffer0");
  25. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  26. node_shader_write(frag, "vec2 g0 = textureLod(gbuffer0, inp.xy, 0.0).rg;");
  27. ///else
  28. node_shader_write(frag, "vec2 g0 = textureLod(gbuffer0, vec2(inp.x, 1.0 - inp.y), 0.0).rg;");
  29. ///end
  30. node_shader_write(frag, "vec3 wn;");
  31. node_shader_write(frag, "wn.z = 1.0 - abs(g0.x) - abs(g0.y);");
  32. node_shader_write(frag, "wn.xy = wn.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);");
  33. node_shader_write(frag, "wn = normalize(wn);");
  34. node_shader_write(frag, "float planeDist = dot(wn, winp.xyz - wposition);");
  35. if (config_raw.brush_angle_reject && !context_raw.xray) {
  36. node_shader_write(frag, "if (planeDist < -0.01) discard;");
  37. frag.n = true;
  38. let angle: f32 = context_raw.brush_angle_reject_dot;
  39. node_shader_write(frag, "if (dot(wn, n) < " + angle + ") discard;");
  40. }
  41. }
  42. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  43. node_shader_write(frag, "float depthlast = textureLod(gbufferD, inplast.xy, 0.0).r;");
  44. ///else
  45. node_shader_write(frag, "float depthlast = textureLod(gbufferD, vec2(inplast.x, 1.0 - inplast.y), 0.0).r;");
  46. ///end
  47. node_shader_write(frag, "vec4 winplast = vec4(vec2(inplast.x, 1.0 - inplast.y) * 2.0 - 1.0, depthlast * 2.0 - 1.0, 1.0);");
  48. node_shader_write(frag, "winplast = mul(winplast, invVP);");
  49. node_shader_write(frag, "winplast.xyz /= winplast.w;");
  50. node_shader_write(frag, "vec3 pa = wposition - winp.xyz;");
  51. if (context_raw.xray) {
  52. node_shader_write(frag, "pa += wn * vec3(planeDist, planeDist, planeDist);");
  53. }
  54. node_shader_write(frag, "vec3 ba = winplast.xyz - winp.xyz;");
  55. if (context_raw.brush_lazy_radius > 0 && context_raw.brush_lazy_step > 0) {
  56. // Sphere
  57. node_shader_write(frag, "dist = distance(wposition, winp.xyz);");
  58. }
  59. else {
  60. // Capsule
  61. node_shader_write(frag, "float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);");
  62. node_shader_write(frag, "dist = length(pa - ba * h);");
  63. }
  64. }
  65. else { // !brush3d
  66. node_shader_write(frag, "vec2 binp = inp.xy * 2.0 - 1.0;");
  67. node_shader_write(frag, "binp.x *= aspectRatio;");
  68. node_shader_write(frag, "binp = binp * 0.5 + 0.5;");
  69. node_shader_write(frag, "vec2 binplast = inplast.xy * 2.0 - 1.0;");
  70. node_shader_write(frag, "binplast.x *= aspectRatio;");
  71. node_shader_write(frag, "binplast = binplast * 0.5 + 0.5;");
  72. node_shader_write(frag, "vec2 pa = bsp.xy - binp.xy;");
  73. node_shader_write(frag, "vec2 ba = binplast.xy - binp.xy;");
  74. node_shader_write(frag, "float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);");
  75. node_shader_write(frag, "dist = length(pa - ba * h);");
  76. }
  77. node_shader_write(frag, "if (dist > brushRadius) discard;");
  78. if (decal && !fill_layer) {
  79. node_shader_write(frag, "}");
  80. }
  81. }