ParticleForward.hx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package hrt.shader;
  2. class ParticleForward extends h3d.shader.pbr.DefaultForward {
  3. static var SRC = {
  4. @global var global : {
  5. @perObject var modelView : Mat4;
  6. };
  7. @const var NORMAL : Bool = false;
  8. @const var NORMAL_FLIP_Y : Bool = false;
  9. @const var NORMAL_FLIP_X : Bool = false;
  10. @const var VERTEX : Bool = true;
  11. // Lighting Params
  12. @param var directLightingIntensity : Float;
  13. @param var indirectLightingIntensity : Float;
  14. // Normal Map Params
  15. @param var normalMap : Sampler2D;
  16. @param var normalIntensity : Float;
  17. var calculatedUV : Vec2;
  18. // CuvedNormal Input
  19. var localNormal : Vec3;
  20. var localTangent : Vec3;
  21. // BackLighting Input
  22. var backLightingIntensity : Float;
  23. // HL2 Basis
  24. @param var hl2_basis0 : Vec3;
  25. @param var hl2_basis1 : Vec3;
  26. @param var hl2_basis2 : Vec3;
  27. // HL2 Basis Transformed
  28. var hl2_basis0Transformed : Vec3;
  29. var hl2_basis1Transformed : Vec3;
  30. var hl2_basis2Transformed : Vec3;
  31. // HL2 Basis Light Accumulation
  32. var color0 : Vec3;
  33. var color1 : Vec3;
  34. var color2 : Vec3;
  35. // Light Accumulation
  36. var lighting : Vec3;
  37. function indirectLighting() : Vec3 {
  38. var indirect = vec3(0);
  39. // HL2 basis for vertexLighting with normalmap
  40. if( NORMAL && VERTEX ) {
  41. var rotatedNormal = rotateNormal(transformedNormal);
  42. var diffuse = irrDiffuse.get(rotatedNormal).rgb;
  43. color0 += diffuse * irrPower * indirectLightingIntensity;
  44. color1 += diffuse * irrPower * indirectLightingIntensity;
  45. color2 += diffuse * irrPower * indirectLightingIntensity;
  46. }
  47. else {
  48. var rotatedNormal = rotateNormal(transformedNormal);
  49. var diffuse = irrDiffuse.get(rotatedNormal).rgb;
  50. indirect += diffuse * irrPower * indirectLightingIntensity;
  51. }
  52. return indirect;
  53. }
  54. function directLighting( lightColor : Vec3, lightDirection : Vec3) : Vec3 {
  55. var result = vec3(0);
  56. // HL2 basis for vertexLighting with normalmap
  57. if( NORMAL && VERTEX ) {
  58. var localBitangent = normalize(localNormal.cross(vec3(localTangent.x, localTangent.y, localTangent.z)));
  59. var TBN = mat3( vec3(localTangent.x, localBitangent.x, localNormal.x),
  60. vec3(localTangent.y, localBitangent.y, localNormal.y),
  61. vec3(localTangent.z, localBitangent.z, localNormal.z));
  62. hl2_basis0Transformed = normalize(hl2_basis0 * TBN * global.modelView.mat3());
  63. hl2_basis1Transformed = normalize(hl2_basis1 * TBN * global.modelView.mat3());
  64. hl2_basis2Transformed = normalize(hl2_basis2 * TBN * global.modelView.mat3());
  65. var weights = saturate(vec3(lightDirection.dot(hl2_basis0Transformed),
  66. lightDirection.dot(hl2_basis1Transformed),
  67. lightDirection.dot(hl2_basis2Transformed)));
  68. color0 += weights.x * lightColor * directLightingIntensity;
  69. color1 += weights.y * lightColor * directLightingIntensity;
  70. color2 += weights.z * lightColor * directLightingIntensity;
  71. }
  72. else {
  73. // Front Lighting
  74. var NdL = transformedNormal.dot(lightDirection);
  75. result += lightColor * clamp(NdL, 0.0, 1.0);
  76. }
  77. // Back Lighting
  78. var bNdL = clamp(-transformedNormal.dot(lightDirection), 0.0, 1.0);
  79. result += lightColor * bNdL * backLightingIntensity;
  80. return result * directLightingIntensity;
  81. }
  82. function evaluateLighting() : Vec3 {
  83. var lightAccumulation = vec3(0);
  84. color0 = vec3(0);
  85. color1 = vec3(0);
  86. color2 = vec3(0);
  87. // Dir Light
  88. for( l in 0 ... dirLightCount )
  89. lightAccumulation += evaluateDirLight(l);
  90. // Point Light
  91. for( l in 0 ... pointLightCount )
  92. lightAccumulation += evaluatePointLight(l);
  93. // Spot Light
  94. for( l in 0 ... spotLightCount )
  95. lightAccumulation += evaluateSpotLight(l);
  96. // Indirect only support the main env from the scene at the moment
  97. if( USE_INDIRECT )
  98. lightAccumulation += indirectLighting();
  99. return lightAccumulation;
  100. }
  101. function normalMapping() {
  102. var n = unpackNormal(normalMap.get(calculatedUV).rgba);
  103. n = vec3(NORMAL_FLIP_X ? -n.x : n.x, NORMAL_FLIP_Y ? -n.y : n.y, n.z);
  104. var localBitangent = normalize(localNormal.cross(vec3(localTangent.x, localTangent.y, localTangent.z)));
  105. var TBN = mat3( vec3(localTangent.x, localBitangent.x, localNormal.x),
  106. vec3(localTangent.y, localBitangent.y, localNormal.y),
  107. vec3(localTangent.z, localBitangent.z, localNormal.z));
  108. transformedNormal = mix(transformedNormal, normalize(n * TBN * global.modelView.mat3()), normalIntensity);
  109. }
  110. function init() {
  111. // Normal Mapping with pixel mode
  112. if( NORMAL && !VERTEX )
  113. normalMapping();
  114. view = (cameraPosition - transformedPosition).normalize();
  115. NdV = transformedNormal.dot(view).max(0.);
  116. }
  117. function vertex() {
  118. if( VERTEX ) {
  119. init();
  120. lighting = evaluateLighting();
  121. }
  122. }
  123. function fragment() {
  124. if( VERTEX && NORMAL ) {
  125. // Normal Mapping with vertex mode
  126. normalMapping();
  127. var w = saturate(vec3( transformedNormal.dot(hl2_basis0Transformed),
  128. transformedNormal.dot(hl2_basis1Transformed),
  129. transformedNormal.dot(hl2_basis2Transformed)));
  130. lighting += color0 * w.x + color1 * w.y + color2 * w.z;
  131. }
  132. else if( !VERTEX ) {
  133. init();
  134. lighting = evaluateLighting();
  135. }
  136. output.color.rgb *= lighting;
  137. }
  138. }
  139. }