| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #ifdef REFLECTION
- struct reflectionOutParams
- {
- vec4 environmentRadiance;
- vec3 environmentIrradiance;
- #ifdef REFLECTIONMAP_3D
- vec3 reflectionCoords;
- #else
- vec2 reflectionCoords;
- #endif
- #ifdef SS_TRANSLUCENCY
- #ifdef USESPHERICALFROMREFLECTIONMAP
- #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
- vec3 irradianceVector;
- #endif
- #endif
- #endif
- };
- void reflectionBlock(
- const in vec3 vPositionW,
- const in vec3 normalW,
- const in float alphaG,
- const in vec3 vReflectionMicrosurfaceInfos,
- const in vec2 vReflectionInfos,
- #ifdef ANISOTROPIC
- const in anisotropicOutParams anisotropicOut,
- #endif
- #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
- const in float NdotVUnclamped,
- #endif
- #ifdef LINEARSPECULARREFLECTION
- const in float roughness,
- #endif
- #ifdef REFLECTIONMAP_3D
- const in samplerCube reflectionSampler,
- #else
- const in sampler2D reflectionSampler,
- #endif
- #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
- const in vec3 vEnvironmentIrradiance,
- #endif
- #ifdef USESPHERICALFROMREFLECTIONMAP
- #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
- const in mat4 reflectionMatrix,
- #endif
- #endif
- #ifdef USEIRRADIANCEMAP
- #ifdef REFLECTIONMAP_3D
- const in samplerCube irradianceSampler,
- #else
- const in sampler2D irradianceSampler,
- #endif
- #endif
- out reflectionOutParams outParams
- )
- {
- vec4 environmentRadiance = vec4(0., 0., 0., 0.);
- vec3 environmentIrradiance = vec3(0., 0., 0.);
- #ifdef ANISOTROPIC
- vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), anisotropicOut.anisotropicNormal);
- #else
- vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
- #endif
- #ifdef REFLECTIONMAP_OPPOSITEZ
- reflectionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef REFLECTIONMAP_3D
- vec3 reflectionCoords = reflectionVector;
- #else
- vec2 reflectionCoords = reflectionVector.xy;
- #ifdef REFLECTIONMAP_PROJECTION
- reflectionCoords /= reflectionVector.z;
- #endif
- reflectionCoords.y = 1.0 - reflectionCoords.y;
- #endif
- #if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
- float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
- #elif defined(LINEARSPECULARREFLECTION)
- float reflectionLOD = getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x, roughness);
- #else
- float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
- #ifdef LODINREFLECTIONALPHA
- // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
- // is constrained to appropriate LOD levels in order to prevent aliasing.
- // The environment map is first sampled without custom LOD selection to determine
- // the hardware-selected LOD, and this is then used to constrain the final LOD selection
- // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
- // where the normal is varying rapidly).
- // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
- // manual calculation via derivatives is also possible, but for simplicity we use the
- // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
- float automaticReflectionLOD = UNPACK_LOD(sampleReflection(reflectionSampler, reflectionCoords).a);
- float requestedReflectionLOD = max(automaticReflectionLOD, reflectionLOD);
- #else
- float requestedReflectionLOD = reflectionLOD;
- #endif
- environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, requestedReflectionLOD);
- #else
- float lodReflectionNormalized = saturate(reflectionLOD / log2(vReflectionMicrosurfaceInfos.x));
- float lodReflectionNormalizedDoubled = lodReflectionNormalized * 2.0;
- vec4 environmentSpecularMid = sampleReflection(reflectionSampler, reflectionCoords);
- if(lodReflectionNormalizedDoubled < 1.0){
- environmentRadiance = mix(
- sampleReflection(reflectionSamplerHigh, reflectionCoords),
- environmentSpecularMid,
- lodReflectionNormalizedDoubled
- );
- }else{
- environmentRadiance = mix(
- environmentSpecularMid,
- sampleReflection(reflectionSamplerLow, reflectionCoords),
- lodReflectionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef RGBDREFLECTION
- environmentRadiance.rgb = fromRGBD(environmentRadiance);
- #endif
- #ifdef GAMMAREFLECTION
- environmentRadiance.rgb = toLinearSpace(environmentRadiance.rgb);
- #endif
- // _____________________________ Irradiance ________________________________
- #ifdef USESPHERICALFROMREFLECTIONMAP
- #if defined(NORMAL) && defined(USESPHERICALINVERTEX)
- environmentIrradiance = vEnvironmentIrradiance;
- #else
- #ifdef ANISOTROPIC
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(anisotropicOut.anisotropicNormal, 0)).xyz;
- #else
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
- #endif
- #ifdef REFLECTIONMAP_OPPOSITEZ
- irradianceVector.z *= -1.0;
- #endif
- environmentIrradiance = computeEnvironmentIrradiance(irradianceVector);
- #ifdef SS_TRANSLUCENCY
- outParams.irradianceVector = irradianceVector;
- #endif
- #endif
- #elif defined(USEIRRADIANCEMAP)
- vec4 environmentIrradiance4 = sampleReflection(irradianceSampler, reflectionCoords);
- environmentIrradiance = environmentIrradiance4.rgb;
- #ifdef RGBDREFLECTION
- environmentIrradiance.rgb = fromRGBD(environmentIrradiance4);
- #endif
- #ifdef GAMMAREFLECTION
- environmentIrradiance.rgb = toLinearSpace(environmentIrradiance.rgb);
- #endif
- #endif
- // _____________________________ Levels _____________________________________
- environmentRadiance.rgb *= vReflectionInfos.x;
- environmentRadiance.rgb *= vReflectionColor.rgb;
- environmentIrradiance *= vReflectionColor.rgb;
- outParams.environmentRadiance = environmentRadiance;
- outParams.environmentIrradiance = environmentIrradiance;
- outParams.reflectionCoords = reflectionCoords;
- }
- #endif
|