pbrBlockReflection.fx 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #ifdef REFLECTION
  2. struct reflectionOutParams
  3. {
  4. vec4 environmentRadiance;
  5. vec3 environmentIrradiance;
  6. #ifdef REFLECTIONMAP_3D
  7. vec3 reflectionCoords;
  8. #else
  9. vec2 reflectionCoords;
  10. #endif
  11. #ifdef SS_TRANSLUCENCY
  12. #ifdef USESPHERICALFROMREFLECTIONMAP
  13. #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
  14. vec3 irradianceVector;
  15. #endif
  16. #endif
  17. #endif
  18. };
  19. void reflectionBlock(
  20. const in vec3 vPositionW,
  21. const in vec3 normalW,
  22. const in float alphaG,
  23. const in vec3 vReflectionMicrosurfaceInfos,
  24. const in vec2 vReflectionInfos,
  25. #ifdef ANISOTROPIC
  26. const in anisotropicOutParams anisotropicOut,
  27. #endif
  28. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  29. const in float NdotVUnclamped,
  30. #endif
  31. #ifdef LINEARSPECULARREFLECTION
  32. const in float roughness,
  33. #endif
  34. #ifdef REFLECTIONMAP_3D
  35. const in samplerCube reflectionSampler,
  36. #else
  37. const in sampler2D reflectionSampler,
  38. #endif
  39. #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
  40. const in vec3 vEnvironmentIrradiance,
  41. #endif
  42. #ifdef USESPHERICALFROMREFLECTIONMAP
  43. #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
  44. const in mat4 reflectionMatrix,
  45. #endif
  46. #endif
  47. #ifdef USEIRRADIANCEMAP
  48. #ifdef REFLECTIONMAP_3D
  49. const in samplerCube irradianceSampler,
  50. #else
  51. const in sampler2D irradianceSampler,
  52. #endif
  53. #endif
  54. out reflectionOutParams outParams
  55. )
  56. {
  57. vec4 environmentRadiance = vec4(0., 0., 0., 0.);
  58. vec3 environmentIrradiance = vec3(0., 0., 0.);
  59. #ifdef ANISOTROPIC
  60. vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), anisotropicOut.anisotropicNormal);
  61. #else
  62. vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
  63. #endif
  64. #ifdef REFLECTIONMAP_OPPOSITEZ
  65. reflectionVector.z *= -1.0;
  66. #endif
  67. // _____________________________ 2D vs 3D Maps ________________________________
  68. #ifdef REFLECTIONMAP_3D
  69. vec3 reflectionCoords = reflectionVector;
  70. #else
  71. vec2 reflectionCoords = reflectionVector.xy;
  72. #ifdef REFLECTIONMAP_PROJECTION
  73. reflectionCoords /= reflectionVector.z;
  74. #endif
  75. reflectionCoords.y = 1.0 - reflectionCoords.y;
  76. #endif
  77. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  78. float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
  79. #elif defined(LINEARSPECULARREFLECTION)
  80. float reflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, roughness);
  81. #else
  82. float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
  83. #endif
  84. #ifdef LODBASEDMICROSFURACE
  85. // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
  86. reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
  87. #ifdef LODINREFLECTIONALPHA
  88. // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
  89. // is constrained to appropriate LOD levels in order to prevent aliasing.
  90. // The environment map is first sampled without custom LOD selection to determine
  91. // the hardware-selected LOD, and this is then used to constrain the final LOD selection
  92. // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
  93. // where the normal is varying rapidly).
  94. // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
  95. // manual calculation via derivatives is also possible, but for simplicity we use the
  96. // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
  97. float automaticReflectionLOD = UNPACK_LOD(sampleReflection(reflectionSampler, reflectionCoords).a);
  98. float requestedReflectionLOD = max(automaticReflectionLOD, reflectionLOD);
  99. #else
  100. float requestedReflectionLOD = reflectionLOD;
  101. #endif
  102. environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, requestedReflectionLOD);
  103. #else
  104. float lodReflectionNormalized = saturate(reflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
  105. float lodReflectionNormalizedDoubled = lodReflectionNormalized * 2.0;
  106. vec4 environmentSpecularMid = sampleReflection(reflectionSampler, reflectionCoords);
  107. if(lodReflectionNormalizedDoubled < 1.0){
  108. environmentRadiance = mix(
  109. sampleReflection(reflectionSamplerHigh, reflectionCoords),
  110. environmentSpecularMid,
  111. lodReflectionNormalizedDoubled
  112. );
  113. }else{
  114. environmentRadiance = mix(
  115. environmentSpecularMid,
  116. sampleReflection(reflectionSamplerLow, reflectionCoords),
  117. lodReflectionNormalizedDoubled - 1.0
  118. );
  119. }
  120. #endif
  121. #ifdef RGBDREFLECTION
  122. environmentRadiance.rgb = fromRGBD(environmentRadiance);
  123. #endif
  124. #ifdef GAMMAREFLECTION
  125. environmentRadiance.rgb = toLinearSpace(environmentRadiance.rgb);
  126. #endif
  127. // _____________________________ Irradiance ________________________________
  128. #ifdef USESPHERICALFROMREFLECTIONMAP
  129. #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
  130. environmentIrradiance = vEnvironmentIrradiance;
  131. #else
  132. #ifdef ANISOTROPIC
  133. vec3 irradianceVector = vec3(reflectionMatrix * vec4(anisotropicOut.anisotropicNormal, 0)).xyz;
  134. #else
  135. vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
  136. #endif
  137. #ifdef REFLECTIONMAP_OPPOSITEZ
  138. irradianceVector.z *= -1.0;
  139. #endif
  140. environmentIrradiance = computeEnvironmentIrradiance(irradianceVector);
  141. #ifdef SS_TRANSLUCENCY
  142. outParams.irradianceVector = irradianceVector;
  143. #endif
  144. #endif
  145. #elif defined(USEIRRADIANCEMAP)
  146. vec4 environmentIrradiance4 = sampleReflection(irradianceSampler, reflectionCoords);
  147. environmentIrradiance = environmentIrradiance4.rgb;
  148. #ifdef RGBDREFLECTION
  149. environmentIrradiance.rgb = fromRGBD(environmentIrradiance4);
  150. #endif
  151. #ifdef GAMMAREFLECTION
  152. environmentIrradiance.rgb = toLinearSpace(environmentIrradiance.rgb);
  153. #endif
  154. #endif
  155. // _____________________________ Levels _____________________________________
  156. environmentRadiance.rgb *= vReflectionInfos.x;
  157. environmentRadiance.rgb *= vReflectionColor.rgb;
  158. environmentIrradiance *= vReflectionColor.rgb;
  159. outParams.environmentRadiance = environmentRadiance;
  160. outParams.environmentIrradiance = environmentIrradiance;
  161. outParams.reflectionCoords = reflectionCoords;
  162. }
  163. #endif