pbrBlockReflection.fx 11 KB

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