make_particle.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. function make_particle_run(data: material_t): node_shader_context_t {
  2. let context_id: string = "mesh";
  3. let props: shader_context_t = {
  4. name: context_id,
  5. depth_write: false,
  6. compare_mode: "always",
  7. cull_mode: "clockwise",
  8. vertex_elements: [
  9. {
  10. name: "pos",
  11. data: "short4norm"
  12. }
  13. ],
  14. color_attachments: ["R8"]
  15. };
  16. let con_part: node_shader_context_t = node_shader_context_create(data, props);
  17. let vert: node_shader_t = node_shader_context_make_vert(con_part);
  18. let frag: node_shader_t = node_shader_context_make_frag(con_part);
  19. frag.ins = vert.outs;
  20. node_shader_write_attrib(vert, "vec4 spos = vec4(pos.xyz, 1.0);");
  21. node_shader_add_uniform(vert, "float brushRadius", "_brushRadius");
  22. node_shader_write_attrib(vert, "vec3 emitFrom = vec3(fhash(gl_InstanceID), fhash(gl_InstanceID * 2), fhash(gl_InstanceID * 3));");
  23. node_shader_write_attrib(vert, "emitFrom = emitFrom * brushRadius - brushRadius / 2.0;");
  24. node_shader_write_attrib(vert, "spos.xyz += emitFrom * vec3(256.0, 256.0, 256.0);");
  25. node_shader_add_uniform(vert, "mat4 pd", "_particle_data");
  26. let str_tex_hash: string = "float fhash(int n) { return fract(sin(float(n)) * 43758.5453); }\n";
  27. node_shader_add_function(vert, str_tex_hash);
  28. node_shader_add_out(vert, "float p_age");
  29. node_shader_write(vert, "p_age = pd[3][3] - float(gl_InstanceID) * pd[0][1];");
  30. node_shader_write(vert, "p_age -= p_age * fhash(gl_InstanceID) * pd[2][3];");
  31. node_shader_write(vert, "if (pd[0][0] > 0.0 && p_age < 0.0) p_age += float(int(-p_age / pd[0][0]) + 1) * pd[0][0];");
  32. node_shader_add_out(vert, "float p_lifetime");
  33. node_shader_write(vert, "p_lifetime = pd[0][2];");
  34. node_shader_write(vert, "if (p_age < 0.0 || p_age > p_lifetime) {");
  35. // write(vert, "SPIRV_Cross_Output stage_output;");
  36. // write(vert, "stage_output.svpos /= 0.0;");
  37. // write(vert, "return stage_output;");
  38. node_shader_write(vert, "spos /= 0.0;");
  39. node_shader_write(vert, "}");
  40. node_shader_add_out(vert, "vec3 p_velocity");
  41. node_shader_write(vert, "p_velocity = vec3(pd[1][0], pd[1][1], pd[1][2]);");
  42. node_shader_write(vert, "p_velocity.x += fhash(gl_InstanceID) * pd[1][3] - pd[1][3] / 2.0;");
  43. node_shader_write(vert, "p_velocity.y += fhash(gl_InstanceID + int(pd[0][3])) * pd[1][3] - pd[1][3] / 2.0;");
  44. node_shader_write(vert, "p_velocity.z += fhash(gl_InstanceID + 2 * int(pd[0][3])) * pd[1][3] - pd[1][3] / 2.0;");
  45. node_shader_write(vert, "p_velocity.x += (pd[2][0] * p_age) / 5.0;");
  46. node_shader_write(vert, "p_velocity.y += (pd[2][1] * p_age) / 5.0;");
  47. node_shader_write(vert, "p_velocity.z += (pd[2][2] * p_age) / 5.0;");
  48. node_shader_add_out(vert, "vec3 p_location");
  49. node_shader_write(vert, "p_location = p_velocity * p_age;");
  50. node_shader_write(vert, "spos.xyz += p_location;");
  51. node_shader_write(vert, "spos.xyz *= vec3(0.01, 0.01, 0.01);");
  52. node_shader_add_uniform(vert, "mat4 WVP", "_world_view_proj_matrix");
  53. node_shader_write(vert, "gl_Position = mul(spos, WVP);");
  54. node_shader_add_uniform(vert, "vec4 inp", "_inputBrush");
  55. node_shader_write(vert, "vec2 binp = vec2(inp.x, 1.0 - inp.y);");
  56. node_shader_write(vert, "binp = binp * 2.0 - 1.0;");
  57. node_shader_write(vert, "binp *= gl_Position.w;");
  58. node_shader_write(vert, "gl_Position.xy += binp;");
  59. node_shader_add_out(vert, "float p_fade");
  60. node_shader_write(vert, "p_fade = sin(min((p_age / 8.0) * 3.141592, 3.141592));");
  61. node_shader_add_out(frag, "float fragColor");
  62. node_shader_write(frag, "fragColor = p_fade;");
  63. // add_out(vert, "vec4 wvpposition");
  64. // write(vert, "wvpposition = gl_Position;");
  65. // write(frag, "vec2 texCoord = wvpposition.xy / wvpposition.w;");
  66. // add_uniform(frag, "sampler2D gbufferD");
  67. // write(frag, "fragColor *= 1.0 - clamp(distance(textureLod(gbufferD, texCoord, 0.0).r, wvpposition.z), 0.0, 1.0);");
  68. // Material.finalize(con_part);
  69. con_part.data.shader_from_source = true;
  70. con_part.data.vertex_shader = node_shader_get(vert);
  71. con_part.data.fragment_shader = node_shader_get(frag);
  72. return con_part;
  73. }
  74. function make_particle_mask(vert: node_shader_t, frag: node_shader_t) {
  75. ///if arm_physics
  76. if (context_raw.particle_physics) {
  77. node_shader_add_out(vert, "vec4 wpos");
  78. node_shader_add_uniform(vert, "mat4 W", "_world_matrix");
  79. node_shader_write_attrib(vert, "wpos = mul(vec4(pos.xyz, 1.0), W);");
  80. node_shader_add_uniform(frag, "vec3 particleHit", "_particleHit");
  81. node_shader_add_uniform(frag, "vec3 particleHitLast", "_particleHitLast");
  82. node_shader_write(frag, "vec3 pa = wpos.xyz - particleHit;");
  83. node_shader_write(frag, "vec3 ba = particleHitLast - particleHit;");
  84. node_shader_write(frag, "float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);");
  85. node_shader_write(frag, "dist = length(pa - ba * h) * 10.0;");
  86. // write(frag, "dist = distance(particleHit, wpos.xyz) * 10.0;");
  87. node_shader_write(frag, "if (dist > 1.0) discard;");
  88. node_shader_write(frag, "float str = clamp(pow(1.0 / dist * brushHardness * 0.2, 4.0), 0.0, 1.0) * opacity;");
  89. node_shader_write(frag, "if (particleHit.x == 0.0 && particleHit.y == 0.0 && particleHit.z == 0.0) str = 0.0;");
  90. node_shader_write(frag, "if (str == 0.0) discard;");
  91. return;
  92. }
  93. ///end
  94. node_shader_add_uniform(frag, "sampler2D texparticle", "_texparticle");
  95. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  96. node_shader_write(frag, "float str = textureLod(texparticle, sp.xy, 0.0).r;");
  97. ///else
  98. node_shader_write(frag, "float str = textureLod(texparticle, vec2(sp.x, (1.0 - sp.y)), 0.0).r;");
  99. ///end
  100. }