IBL.glsl 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #line 10001
  2. #ifdef COMPILEPS
  3. float GetMipFromRoughness(float roughness)
  4. {
  5. return (roughness * 12.0 - pow(roughness, 6.0) * 1.5);
  6. }
  7. vec3 EnvBRDFApprox (vec3 SpecularColor, float Roughness, float NoV)
  8. {
  9. vec4 c0 = vec4(-1, -0.0275, -0.572, 0.022 );
  10. vec4 c1 = vec4(1, 0.0425, 1.0, -0.04 );
  11. vec4 r = Roughness * c0 + c1;
  12. float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
  13. vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
  14. return SpecularColor * AB.x + AB.y;
  15. }
  16. vec3 FixCubeLookup(vec3 v)
  17. {
  18. float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
  19. float scale = (1024 - 1) / 1024;
  20. if (abs(v.x) != M) v.x += scale;
  21. if (abs(v.y) != M) v.y += scale;
  22. if (abs(v.z) != M) v.z += scale;
  23. return v;
  24. }
  25. /// Calculate IBL contributation
  26. /// reflectVec: reflection vector for cube sampling
  27. /// wsNormal: surface normal in word space
  28. /// toCamera: normalized direction from surface point to camera
  29. /// roughness: surface roughness
  30. /// ambientOcclusion: ambient occlusion
  31. vec3 ImageBasedLighting(vec3 reflectVec, vec3 wsNormal, vec3 toCamera, vec3 diffColor, vec3 specColor, float roughness, inout vec3 reflectionCubeColor)
  32. {
  33. roughness = max(roughness, 0.08);
  34. reflectVec = GetSpecularDominantDir(wsNormal, reflectVec, roughness);
  35. float ndv = clamp(dot(-toCamera, wsNormal), 0.0, 1.0);
  36. // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
  37. //float GlossScale = 16.0;
  38. //float GlossBias = 5.0;
  39. float mipSelect = GetMipFromRoughness(roughness); //exp2(GlossScale * roughness * roughness + GlossBias) - exp2(GlossBias);
  40. // OpenGL ES does not support textureLod without extensions and does not have the sZoneCubeMap sampler,
  41. // so for now, sample without explicit LOD, and from the environment sampler, where the zone texture will be put
  42. // on mobile hardware
  43. #ifndef GL_ES
  44. vec3 cube = textureLod(sZoneCubeMap, FixCubeLookup(reflectVec), mipSelect).rgb;
  45. vec3 cubeD = textureLod(sZoneCubeMap, FixCubeLookup(wsNormal), 9.0).rgb;
  46. #else
  47. vec3 cube = textureCube(sEnvCubeMap, FixCubeLookup(reflectVec)).rgb;
  48. vec3 cubeD = textureCube(sEnvCubeMap, FixCubeLookup(wsNormal)).rgb;
  49. #endif
  50. // Fake the HDR texture
  51. float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
  52. float darknessCutoff = clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25);
  53. const float hdrMaxBrightness = 5.0;
  54. vec3 hdrCube = pow(cube + darknessCutoff, vec3(max(1.0, cAmbientColor.a)));
  55. hdrCube += max(vec3(0.0), hdrCube - vec3(1.0)) * hdrMaxBrightness;
  56. vec3 hdrCubeD = pow(cubeD + darknessCutoff, vec3(max(1.0, cAmbientColor.a)));
  57. hdrCubeD += max(vec3(0.0), hdrCubeD - vec3(1.0)) * hdrMaxBrightness;
  58. vec3 environmentSpecular = EnvBRDFApprox(specColor, roughness, ndv);
  59. vec3 environmentDiffuse = EnvBRDFApprox(diffColor, 1.0, ndv);
  60. return (hdrCube * environmentSpecular + hdrCubeD * environmentDiffuse) * brightness;
  61. }
  62. #endif