123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- struct subSurfaceOutParams
- {
- vec3 specularEnvironmentReflectance;
- #ifdef SS_REFRACTION
- vec3 finalRefraction;
- vec3 surfaceAlbedo;
- #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
- float alpha;
- #endif
- #ifdef REFLECTION
- float refractionFactorForIrradiance;
- #endif
- #endif
- #ifdef SS_TRANSLUCENCY
- vec3 transmittance;
- #ifdef REFLECTION
- vec3 refractionIrradiance;
- #endif
- #endif
- #if DEBUGMODE > 0
- vec4 thicknessMap;
- vec4 environmentRefraction;
- vec3 refractionTransmittance;
- #endif
- };
- #ifdef SUBSURFACE
- #define pbr_inline
- #define inline
- void subSurfaceBlock(
- const in vec3 vSubSurfaceIntensity,
- const in vec2 vThicknessParam,
- const in vec4 vTintColor,
- const in vec3 normalW,
- const in vec3 specularEnvironmentReflectance,
- #ifdef SS_THICKNESSANDMASK_TEXTURE
- const in vec4 thicknessMap,
- #endif
- #ifdef REFLECTION
- #ifdef SS_TRANSLUCENCY
- const in mat4 reflectionMatrix,
- #ifdef USESPHERICALFROMREFLECTIONMAP
- #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
- const in vec3 irradianceVector_,
- #endif
- #endif
- #ifdef USEIRRADIANCEMAP
- #ifdef REFLECTIONMAP_3D
- const in samplerCube irradianceSampler,
- #else
- const in sampler2D irradianceSampler,
- #endif
- #endif
- #endif
- #endif
- #ifdef SS_REFRACTION
- const in vec3 vPositionW,
- const in vec3 viewDirectionW,
- const in mat4 view,
- const in vec3 surfaceAlbedo,
- const in vec4 vRefractionInfos,
- const in mat4 refractionMatrix,
- const in vec3 vRefractionMicrosurfaceInfos,
- const in vec4 vLightingIntensity,
- #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
- const in float alpha,
- #endif
- #ifdef SS_LODINREFRACTIONALPHA
- const in float NdotVUnclamped,
- #endif
- #ifdef SS_LINEARSPECULARREFRACTION
- const in float roughness,
- #else
- const in float alphaG,
- #endif
- #ifdef SS_REFRACTIONMAP_3D
- const in samplerCube refractionSampler,
- #ifndef LODBASEDMICROSFURACE
- const in samplerCube refractionSamplerLow,
- const in samplerCube refractionSamplerHigh,
- #endif
- #else
- const in sampler2D refractionSampler,
- #ifndef LODBASEDMICROSFURACE
- const in sampler2D refractionSamplerLow,
- const in sampler2D refractionSamplerHigh,
- #endif
- #endif
- #ifdef ANISOTROPIC
- const in anisotropicOutParams anisotropicOut,
- #endif
- #endif
- #ifdef SS_TRANSLUCENCY
- const in vec3 vDiffusionDistance,
- #endif
- out subSurfaceOutParams outParams
- )
- {
- outParams.specularEnvironmentReflectance = specularEnvironmentReflectance;
- // ______________________________________________________________________________________
- // _____________________________ Intensities & thickness ________________________________
- // ______________________________________________________________________________________
- #ifdef SS_REFRACTION
- float refractionIntensity = vSubSurfaceIntensity.x;
- #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
- refractionIntensity *= (1.0 - alpha);
- // Put alpha back to 1;
- outParams.alpha = 1.0;
- #endif
- #endif
- #ifdef SS_TRANSLUCENCY
- float translucencyIntensity = vSubSurfaceIntensity.y;
- #endif
- #ifdef SS_SCATTERING
- float scatteringIntensity = vSubSurfaceIntensity.z;
- #endif
- #ifdef SS_THICKNESSANDMASK_TEXTURE
- float thickness = thicknessMap.r * vThicknessParam.y + vThicknessParam.x;
- #if DEBUGMODE > 0
- outParams.thicknessMap = thicknessMap;
- #endif
- #ifdef SS_MASK_FROM_THICKNESS_TEXTURE
- #ifdef SS_REFRACTION
- refractionIntensity *= thicknessMap.g;
- #endif
- #ifdef SS_TRANSLUCENCY
- translucencyIntensity *= thicknessMap.b;
- #endif
- #ifdef SS_SCATTERING
- scatteringIntensity *= thicknessMap.a;
- #endif
- #endif
- #else
- float thickness = vThicknessParam.y;
- #endif
- // _________________________________________________________________________________________
- // _____________________________ Translucency transmittance ________________________________
- // _________________________________________________________________________________________
- #ifdef SS_TRANSLUCENCY
- thickness = maxEps(thickness);
- vec3 transmittance = transmittanceBRDF_Burley(vTintColor.rgb, vDiffusionDistance, thickness);
- transmittance *= translucencyIntensity;
- outParams.transmittance = transmittance;
- #endif
- // _____________________________________________________________________________________
- // _____________________________ Refraction environment ________________________________
- // _____________________________________________________________________________________
- #ifdef SS_REFRACTION
- vec4 environmentRefraction = vec4(0., 0., 0., 0.);
- #ifdef ANISOTROPIC
- vec3 refractionVector = refract(-viewDirectionW, anisotropicOut.anisotropicNormal, vRefractionInfos.y);
- #else
- vec3 refractionVector = refract(-viewDirectionW, normalW, vRefractionInfos.y);
- #endif
- #ifdef SS_REFRACTIONMAP_OPPOSITEZ
- refractionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef SS_REFRACTIONMAP_3D
- refractionVector.y = refractionVector.y * vRefractionInfos.w;
- vec3 refractionCoords = refractionVector;
- refractionCoords = vec3(refractionMatrix * vec4(refractionCoords, 0));
- #else
- vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
- vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
- refractionCoords.y = 1.0 - refractionCoords.y;
- #endif
- #ifdef SS_LODINREFRACTIONALPHA
- float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
- #elif defined(SS_LINEARSPECULARREFRACTION)
- float refractionLOD = getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x, roughness);
- #else
- float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG);
- #endif
- #ifdef LODBASEDMICROSFURACE
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- refractionLOD = refractionLOD * vRefractionMicrosurfaceInfos.y + vRefractionMicrosurfaceInfos.z;
- #ifdef SS_LODINREFRACTIONALPHA
- // 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 automaticRefractionLOD = UNPACK_LOD(sampleRefraction(refractionSampler, refractionCoords).a);
- float requestedRefractionLOD = max(automaticRefractionLOD, refractionLOD);
- #else
- float requestedRefractionLOD = refractionLOD;
- #endif
- #ifdef REALTIME_FILTERING
- environmentRefraction = vec4(radiance(alphaG, refractionSampler, refractionCoords, vRefractionFilteringInfo), 1.0);
- #else
- environmentRefraction = sampleRefractionLod(refractionSampler, refractionCoords, requestedRefractionLOD);
- #endif
- #else
- float lodRefractionNormalized = saturate(refractionLOD / log2(vRefractionMicrosurfaceInfos.x));
- float lodRefractionNormalizedDoubled = lodRefractionNormalized * 2.0;
- vec4 environmentRefractionMid = sampleRefraction(refractionSampler, refractionCoords);
- if (lodRefractionNormalizedDoubled < 1.0){
- environmentRefraction = mix(
- sampleRefraction(refractionSamplerHigh, refractionCoords),
- environmentRefractionMid,
- lodRefractionNormalizedDoubled
- );
- } else {
- environmentRefraction = mix(
- environmentRefractionMid,
- sampleRefraction(refractionSamplerLow, refractionCoords),
- lodRefractionNormalizedDoubled - 1.0
- );
- }
- #endif
- #ifdef SS_RGBDREFRACTION
- environmentRefraction.rgb = fromRGBD(environmentRefraction);
- #endif
- #ifdef SS_GAMMAREFRACTION
- environmentRefraction.rgb = toLinearSpace(environmentRefraction.rgb);
- #endif
- // _____________________________ Levels _____________________________________
- environmentRefraction.rgb *= vRefractionInfos.x;
- #endif
- // _______________________________________________________________________________
- // _____________________________ Final Refraction ________________________________
- // _______________________________________________________________________________
- #ifdef SS_REFRACTION
- vec3 refractionTransmittance = vec3(refractionIntensity);
- #ifdef SS_THICKNESSANDMASK_TEXTURE
- vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
- // // Simulate Flat Surface
- // thickness /= dot(refractionVector, -normalW);
- // // Simulate Curved Surface
- // float NdotRefract = dot(normalW, refractionVector);
- // thickness *= -NdotRefract;
- refractionTransmittance *= cocaLambert(volumeAlbedo, thickness);
- #elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)
- // Tint the material with albedo.
- float maxChannel = max(max(surfaceAlbedo.r, surfaceAlbedo.g), surfaceAlbedo.b);
- vec3 volumeAlbedo = saturate(maxChannel * surfaceAlbedo);
- // Tint reflectance
- environmentRefraction.rgb *= volumeAlbedo;
- #else
- // Compute tint from min distance only.
- vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
- refractionTransmittance *= cocaLambert(volumeAlbedo, vThicknessParam.y);
- #endif
- // Decrease Albedo Contribution
- outParams.surfaceAlbedo = surfaceAlbedo * (1. - refractionIntensity);
- #ifdef REFLECTION
- // Decrease irradiance Contribution
- outParams.refractionFactorForIrradiance = (1. - refractionIntensity);
- //environmentIrradiance *= (1. - refractionIntensity);
- #endif
- // Add Multiple internal bounces.
- vec3 bounceSpecularEnvironmentReflectance = (2.0 * specularEnvironmentReflectance) / (1.0 + specularEnvironmentReflectance);
- outParams.specularEnvironmentReflectance = mix(bounceSpecularEnvironmentReflectance, specularEnvironmentReflectance, refractionIntensity);
- // In theory T = 1 - R.
- refractionTransmittance *= 1.0 - outParams.specularEnvironmentReflectance;
- #if DEBUGMODE > 0
- outParams.refractionTransmittance = refractionTransmittance;
- #endif
- outParams.finalRefraction = environmentRefraction.rgb * refractionTransmittance * vLightingIntensity.z;
- #if DEBUGMODE > 0
- outParams.environmentRefraction = environmentRefraction;
- #endif
- #endif
- // __________________________________________________________________________________
- // _______________________________ IBL Translucency ________________________________
- // __________________________________________________________________________________
- #if defined(REFLECTION) && defined(SS_TRANSLUCENCY)
- #if defined(NORMAL) && defined(USESPHERICALINVERTEX) || !defined(USESPHERICALFROMREFLECTIONMAP)
- vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
- #ifdef REFLECTIONMAP_OPPOSITEZ
- irradianceVector.z *= -1.0;
- #endif
- #ifdef INVERTCUBICMAP
- irradianceVector.y *= -1.0;
- #endif
- #else
- vec3 irradianceVector = irradianceVector_;
- #endif
- #if defined(USESPHERICALFROMREFLECTIONMAP)
- #if defined(REALTIME_FILTERING)
- vec3 refractionIrradiance = irradiance(reflectionSampler, -irradianceVector, vReflectionFilteringInfo);
- #else
- vec3 refractionIrradiance = computeEnvironmentIrradiance(-irradianceVector);
- #endif
- #elif defined(USEIRRADIANCEMAP)
- #ifdef REFLECTIONMAP_3D
- vec3 irradianceCoords = irradianceVector;
- #else
- vec2 irradianceCoords = irradianceVector.xy;
- #ifdef REFLECTIONMAP_PROJECTION
- irradianceCoords /= irradianceVector.z;
- #endif
- irradianceCoords.y = 1.0 - irradianceCoords.y;
- #endif
- vec4 refractionIrradiance = sampleReflection(irradianceSampler, -irradianceCoords);
- #ifdef RGBDREFLECTION
- refractionIrradiance.rgb = fromRGBD(refractionIrradiance);
- #endif
- #ifdef GAMMAREFLECTION
- refractionIrradiance.rgb = toLinearSpace(refractionIrradiance.rgb);
- #endif
- #else
- vec4 refractionIrradiance = vec4(0.);
- #endif
- refractionIrradiance.rgb *= transmittance;
- outParams.refractionIrradiance = refractionIrradiance.rgb;
- #endif
- }
- #endif
|