pbrLighting.glsl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. vec3 lambertianDiffuse(vec3 diffuseColor)
  2. {
  3. return diffuseColor / czm_pi;
  4. }
  5. vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH)
  6. {
  7. return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);
  8. }
  9. float smithVisibilityG1(float NdotV, float roughness)
  10. {
  11. // this is the k value for direct lighting.
  12. // for image based lighting it will be roughness^2 / 2
  13. float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
  14. return NdotV / (NdotV * (1.0 - k) + k);
  15. }
  16. float smithVisibilityGGX(float roughness, float NdotL, float NdotV)
  17. {
  18. return (
  19. smithVisibilityG1(NdotL, roughness) *
  20. smithVisibilityG1(NdotV, roughness)
  21. );
  22. }
  23. float GGX(float roughness, float NdotH)
  24. {
  25. float roughnessSquared = roughness * roughness;
  26. float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;
  27. return roughnessSquared / (czm_pi * f * f);
  28. }
  29. /**
  30. * Compute the diffuse and specular contributions using physically based
  31. * rendering. This function only handles direct lighting.
  32. * <p>
  33. * This function only handles the lighting calculations. Metallic/roughness
  34. * and specular/glossy must be handled separately. See {@czm_pbrMetallicRoughnessMaterial}, {@czm_pbrSpecularGlossinessMaterial} and {@czm_defaultPbrMaterial}
  35. * </p>
  36. *
  37. * @name czm_pbrlighting
  38. * @glslFunction
  39. *
  40. * @param {vec3} positionEC The position of the fragment in eye coordinates
  41. * @param {vec3} normalEC The surface normal in eye coordinates
  42. * @param {vec3} lightDirectionEC Unit vector pointing to the light source in eye coordinates.
  43. * @param {vec3} lightColorHdr radiance of the light source. This is a HDR value.
  44. * @param {czm_pbrParameters} The computed PBR parameters.
  45. * @return {vec3} The computed HDR color
  46. *
  47. * @example
  48. * czm_pbrParameters pbrParameters = czm_pbrMetallicRoughnessMaterial(
  49. * baseColor,
  50. * metallic,
  51. * roughness
  52. * );
  53. * vec3 color = czm_pbrlighting(
  54. * positionEC,
  55. * normalEC,
  56. * lightDirectionEC,
  57. * lightColorHdr,
  58. * pbrParameters);
  59. */
  60. vec3 czm_pbrLighting(
  61. vec3 positionEC,
  62. vec3 normalEC,
  63. vec3 lightDirectionEC,
  64. vec3 lightColorHdr,
  65. czm_pbrParameters pbrParameters
  66. )
  67. {
  68. vec3 v = -normalize(positionEC);
  69. vec3 l = normalize(lightDirectionEC);
  70. vec3 h = normalize(v + l);
  71. vec3 n = normalEC;
  72. float NdotL = clamp(dot(n, l), 0.001, 1.0);
  73. float NdotV = abs(dot(n, v)) + 0.001;
  74. float NdotH = clamp(dot(n, h), 0.0, 1.0);
  75. float LdotH = clamp(dot(l, h), 0.0, 1.0);
  76. float VdotH = clamp(dot(v, h), 0.0, 1.0);
  77. vec3 f0 = pbrParameters.f0;
  78. float reflectance = max(max(f0.r, f0.g), f0.b);
  79. vec3 f90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));
  80. vec3 F = fresnelSchlick2(f0, f90, VdotH);
  81. float alpha = pbrParameters.roughness;
  82. float G = smithVisibilityGGX(alpha, NdotL, NdotV);
  83. float D = GGX(alpha, NdotH);
  84. vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);
  85. vec3 diffuseColor = pbrParameters.diffuseColor;
  86. // F here represents the specular contribution
  87. vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(diffuseColor);
  88. // Lo = (diffuse + specular) * Li * NdotL
  89. return (diffuseContribution + specularContribution) * NdotL * lightColorHdr;
  90. }