pbrBlockReflection.fx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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 createReflectionCoords(
  20. const in vec3 vPositionW,
  21. const in vec3 normalW,
  22. #ifdef ANISOTROPIC
  23. const in anisotropicOutParams anisotropicOut,
  24. #endif
  25. #ifdef REFLECTIONMAP_3D
  26. out vec3 reflectionCoords
  27. #else
  28. out vec2 reflectionCoords
  29. #endif
  30. )
  31. {
  32. #ifdef ANISOTROPIC
  33. vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), anisotropicOut.anisotropicNormal);
  34. #else
  35. vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
  36. #endif
  37. #ifdef REFLECTIONMAP_OPPOSITEZ
  38. reflectionVector.z *= -1.0;
  39. #endif
  40. // _____________________________ 2D vs 3D Maps ________________________________
  41. #ifdef REFLECTIONMAP_3D
  42. reflectionCoords = reflectionVector;
  43. #else
  44. reflectionCoords = reflectionVector.xy;
  45. #ifdef REFLECTIONMAP_PROJECTION
  46. reflectionCoords /= reflectionVector.z;
  47. #endif
  48. reflectionCoords.y = 1.0 - reflectionCoords.y;
  49. #endif
  50. }
  51. void sampleReflectionTexture(
  52. const in float alphaG,
  53. const in vec3 vReflectionMicrosurfaceInfos,
  54. const in vec2 vReflectionInfos,
  55. const in vec3 vReflectionColor,
  56. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  57. const in float NdotVUnclamped,
  58. #endif
  59. #ifdef LINEARSPECULARREFLECTION
  60. const in float roughness,
  61. #endif
  62. #ifdef REFLECTIONMAP_3D
  63. const in samplerCube reflectionSampler,
  64. const vec3 reflectionCoords,
  65. #else
  66. const in sampler2D reflectionSampler,
  67. const vec2 reflectionCoords,
  68. #endif
  69. #ifndef LODBASEDMICROSFURACE
  70. #ifdef REFLECTIONMAP_3D
  71. const in samplerCube reflectionSamplerLow,
  72. const in samplerCube reflectionSamplerHigh,
  73. #else
  74. const in sampler2D reflectionSamplerLow,
  75. const in sampler2D reflectionSamplerHigh,
  76. #endif
  77. #endif
  78. out vec4 environmentRadiance
  79. )
  80. {
  81. // _____________________________ 2D vs 3D Maps ________________________________
  82. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  83. float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
  84. #elif defined(LINEARSPECULARREFLECTION)
  85. float reflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, roughness);
  86. #else
  87. float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
  88. #endif
  89. #ifdef LODBASEDMICROSFURACE
  90. // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
  91. reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
  92. #ifdef LODINREFLECTIONALPHA
  93. // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
  94. // is constrained to appropriate LOD levels in order to prevent aliasing.
  95. // The environment map is first sampled without custom LOD selection to determine
  96. // the hardware-selected LOD, and this is then used to constrain the final LOD selection
  97. // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
  98. // where the normal is varying rapidly).
  99. // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
  100. // manual calculation via derivatives is also possible, but for simplicity we use the
  101. // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
  102. float automaticReflectionLOD = UNPACK_LOD(sampleReflection(reflectionSampler, reflectionCoords).a);
  103. float requestedReflectionLOD = max(automaticReflectionLOD, reflectionLOD);
  104. #else
  105. float requestedReflectionLOD = reflectionLOD;
  106. #endif
  107. environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, reflectionLOD);
  108. #else
  109. float lodReflectionNormalized = saturate(reflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
  110. float lodReflectionNormalizedDoubled = lodReflectionNormalized * 2.0;
  111. vec4 environmentMid = sampleReflection(reflectionSampler, reflectionCoords);
  112. if (lodReflectionNormalizedDoubled < 1.0){
  113. environmentRadiance = mix(
  114. sampleReflection(reflectionSamplerHigh, reflectionCoords),
  115. environmentMid,
  116. lodReflectionNormalizedDoubled
  117. );
  118. } else {
  119. environmentRadiance = mix(
  120. environmentMid,
  121. sampleReflection(reflectionSamplerLow, reflectionCoords),
  122. lodReflectionNormalizedDoubled - 1.0
  123. );
  124. }
  125. #endif
  126. #ifdef RGBDREFLECTION
  127. environmentRadiance.rgb = fromRGBD(environmentRadiance);
  128. #endif
  129. #ifdef GAMMAREFLECTION
  130. environmentRadiance.rgb = toLinearSpace(environmentRadiance.rgb);
  131. #endif
  132. // _____________________________ Levels _____________________________________
  133. environmentRadiance.rgb *= vReflectionInfos.x;
  134. environmentRadiance.rgb *= vReflectionColor.rgb;
  135. }
  136. void reflectionBlock(
  137. const in vec3 vPositionW,
  138. const in vec3 normalW,
  139. const in float alphaG,
  140. const in vec3 vReflectionMicrosurfaceInfos,
  141. const in vec2 vReflectionInfos,
  142. const in vec3 vReflectionColor,
  143. #ifdef ANISOTROPIC
  144. const in anisotropicOutParams anisotropicOut,
  145. #endif
  146. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  147. const in float NdotVUnclamped,
  148. #endif
  149. #ifdef LINEARSPECULARREFLECTION
  150. const in float roughness,
  151. #endif
  152. #ifdef REFLECTIONMAP_3D
  153. const in samplerCube reflectionSampler,
  154. #else
  155. const in sampler2D reflectionSampler,
  156. #endif
  157. #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
  158. const in vec3 vEnvironmentIrradiance,
  159. #endif
  160. #ifdef USESPHERICALFROMREFLECTIONMAP
  161. #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
  162. const in mat4 reflectionMatrix,
  163. #endif
  164. #endif
  165. #ifdef USEIRRADIANCEMAP
  166. #ifdef REFLECTIONMAP_3D
  167. const in samplerCube irradianceSampler,
  168. #else
  169. const in sampler2D irradianceSampler,
  170. #endif
  171. #endif
  172. #ifndef LODBASEDMICROSFURACE
  173. #ifdef REFLECTIONMAP_3D
  174. const in samplerCube reflectionSamplerLow,
  175. const in samplerCube reflectionSamplerHigh,
  176. #else
  177. const in sampler2D reflectionSamplerLow,
  178. const in sampler2D reflectionSamplerHigh,
  179. #endif
  180. #endif
  181. out reflectionOutParams outParams
  182. )
  183. {
  184. // _____________________________ Radiance ________________________________
  185. vec4 environmentRadiance = vec4(0., 0., 0., 0.);
  186. #ifdef REFLECTIONMAP_3D
  187. vec3 reflectionCoords = vec3(0.);
  188. #else
  189. vec2 reflectionCoords = vec2(0.);
  190. #endif
  191. createReflectionCoords(
  192. vPositionW,
  193. normalW,
  194. #ifdef ANISOTROPIC
  195. anisotropicOut,
  196. #endif
  197. reflectionCoords
  198. );
  199. sampleReflectionTexture(
  200. alphaG,
  201. vReflectionMicrosurfaceInfos,
  202. vReflectionInfos,
  203. vReflectionColor,
  204. #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
  205. NdotVUnclamped,
  206. #endif
  207. #ifdef LINEARSPECULARREFLECTION
  208. roughness,
  209. #endif
  210. #ifdef REFLECTIONMAP_3D
  211. reflectionSampler,
  212. reflectionCoords,
  213. #else
  214. reflectionSampler,
  215. reflectionCoords,
  216. #endif
  217. #ifndef LODBASEDMICROSFURACE
  218. reflectionSamplerLow,
  219. reflectionSamplerHigh,
  220. #endif
  221. environmentRadiance
  222. );
  223. // _____________________________ Irradiance ________________________________
  224. vec3 environmentIrradiance = vec3(0., 0., 0.);
  225. #ifdef USESPHERICALFROMREFLECTIONMAP
  226. #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
  227. environmentIrradiance = vEnvironmentIrradiance;
  228. #else
  229. #ifdef ANISOTROPIC
  230. vec3 irradianceVector = vec3(reflectionMatrix * vec4(anisotropicOut.anisotropicNormal, 0)).xyz;
  231. #else
  232. vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
  233. #endif
  234. #ifdef REFLECTIONMAP_OPPOSITEZ
  235. irradianceVector.z *= -1.0;
  236. #endif
  237. #if defined(WEBGL2) && defined(REALTIME_FILTERING)
  238. environmentIrradiance = irradiance(reflectionSampler, irradianceVector);
  239. #else
  240. environmentIrradiance = computeEnvironmentIrradiance(irradianceVector);
  241. #endif
  242. #ifdef SS_TRANSLUCENCY
  243. outParams.irradianceVector = irradianceVector;
  244. #endif
  245. #endif
  246. #elif defined(USEIRRADIANCEMAP)
  247. vec4 environmentIrradiance4 = sampleReflection(irradianceSampler, reflectionCoords);
  248. environmentIrradiance = environmentIrradiance4.rgb;
  249. #ifdef RGBDREFLECTION
  250. environmentIrradiance.rgb = fromRGBD(environmentIrradiance4);
  251. #endif
  252. #ifdef GAMMAREFLECTION
  253. environmentIrradiance.rgb = toLinearSpace(environmentIrradiance.rgb);
  254. #endif
  255. #endif
  256. environmentIrradiance *= vReflectionColor.rgb;
  257. outParams.environmentRadiance = environmentRadiance;
  258. outParams.environmentIrradiance = environmentIrradiance;
  259. outParams.reflectionCoords = reflectionCoords;
  260. }
  261. #endif