pbrLightFunctions.fx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Light Computing
  2. struct lightingInfo
  3. {
  4. vec3 diffuse;
  5. #ifdef SPECULARTERM
  6. vec3 specular;
  7. #endif
  8. };
  9. lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float roughness, float NdotV, float lightRadius, out float NdotL) {
  10. lightingInfo result;
  11. vec3 lightDirection;
  12. float attenuation = 1.0;
  13. float lightDistance;
  14. // Point
  15. if (lightData.w == 0.)
  16. {
  17. vec3 lightOffset = lightData.xyz - vPositionW;
  18. float lightDistanceSquared = dot(lightOffset, lightOffset);
  19. attenuation = computeLightFalloff(lightOffset, lightDistanceSquared, range);
  20. lightDistance = sqrt(lightDistanceSquared);
  21. lightDirection = normalize(lightOffset);
  22. }
  23. // Directional
  24. else
  25. {
  26. lightDistance = length(-lightData.xyz);
  27. lightDirection = normalize(-lightData.xyz);
  28. }
  29. // Roughness
  30. roughness = adjustRoughnessFromLightProperties(roughness, lightRadius, lightDistance);
  31. // diffuse
  32. vec3 H = normalize(viewDirectionW + lightDirection);
  33. NdotL = max(0.00000000001, dot(vNormal, lightDirection));
  34. float VdotH = clamp(0.00000000001, 1.0, dot(viewDirectionW, H));
  35. float diffuseTerm = computeDiffuseTerm(NdotL, NdotV, VdotH, roughness);
  36. result.diffuse = diffuseTerm * diffuseColor * attenuation;
  37. #ifdef SPECULARTERM
  38. // Specular
  39. float NdotH = max(0.00000000001, dot(vNormal, H));
  40. vec3 specTerm = computeSpecularTerm(NdotH, NdotL, NdotV, VdotH, roughness, specularColor);
  41. result.specular = specTerm * attenuation;
  42. #endif
  43. return result;
  44. }
  45. lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float range, float roughness, float NdotV, float lightRadius, out float NdotL) {
  46. lightingInfo result;
  47. vec3 lightOffset = lightData.xyz - vPositionW;
  48. vec3 lightVectorW = normalize(lightOffset);
  49. // diffuse
  50. float cosAngle = max(0.000000000000001, dot(-lightDirection.xyz, lightVectorW));
  51. if (cosAngle >= lightDirection.w)
  52. {
  53. cosAngle = max(0., pow(cosAngle, lightData.w));
  54. // Inverse squared falloff.
  55. float lightDistanceSquared = dot(lightOffset, lightOffset);
  56. float attenuation = computeLightFalloff(lightOffset, lightDistanceSquared, range);
  57. // Directional falloff.
  58. attenuation *= cosAngle;
  59. // Roughness.
  60. float lightDistance = sqrt(lightDistanceSquared);
  61. roughness = adjustRoughnessFromLightProperties(roughness, lightRadius, lightDistance);
  62. // Diffuse
  63. vec3 H = normalize(viewDirectionW - lightDirection.xyz);
  64. NdotL = max(0.00000000001, dot(vNormal, -lightDirection.xyz));
  65. float VdotH = clamp(dot(viewDirectionW, H), 0.00000000001, 1.0);
  66. float diffuseTerm = computeDiffuseTerm(NdotL, NdotV, VdotH, roughness);
  67. result.diffuse = diffuseTerm * diffuseColor * attenuation;
  68. #ifdef SPECULARTERM
  69. // Specular
  70. float NdotH = max(0.00000000001, dot(vNormal, H));
  71. vec3 specTerm = computeSpecularTerm(NdotH, NdotL, NdotV, VdotH, roughness, specularColor);
  72. result.specular = specTerm * attenuation;
  73. #endif
  74. return result;
  75. }
  76. result.diffuse = vec3(0.);
  77. #ifdef SPECULARTERM
  78. result.specular = vec3(0.);
  79. #endif
  80. return result;
  81. }
  82. lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float roughness, float NdotV, float lightRadius, out float NdotL) {
  83. lightingInfo result;
  84. // Roughness
  85. // Do not touch roughness on hemispheric.
  86. // Diffuse
  87. NdotL = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
  88. result.diffuse = mix(groundColor, diffuseColor, NdotL);
  89. #ifdef SPECULARTERM
  90. // Specular
  91. vec3 lightVectorW = normalize(lightData.xyz);
  92. vec3 H = normalize(viewDirectionW + lightVectorW);
  93. float NdotH = max(0.00000000001, dot(vNormal, H));
  94. NdotL = max(0.00000000001, NdotL);
  95. float VdotH = clamp(0.00000000001, 1.0, dot(viewDirectionW, H));
  96. vec3 specTerm = computeSpecularTerm(NdotH, NdotL, NdotV, VdotH, roughness, specularColor);
  97. result.specular = specTerm;
  98. #endif
  99. return result;
  100. }