|
|
|
|
|
|
|
|
|
|
// Rough refraction texture |
|
|
|
// Color pyramid (width, height, lodcount, Unused) |
|
|
|
TEXTURE2D(_GaussianPyramidColorTexture); |
|
|
|
TEXTURE2D(_ColorPyramidTexture); |
|
|
|
TEXTURE2D(_PyramidDepthTexture); |
|
|
|
TEXTURE2D(_DepthPyramidTexture); |
|
|
|
float4 _GaussianPyramidColorMipSize; // (x,y) = PyramidToScreenScale, z = lodCount |
|
|
|
float4 _PyramidDepthMipSize; |
|
|
|
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size |
|
|
|
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size |
|
|
|
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused |
|
|
|
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused |
|
|
|
CBUFFER_END |
|
|
|
|
|
|
|
// Ambient occlusion texture |
|
|
|
|
|
|
// we approximate the scene as a plane (back plane) with normal -V at the depth hit point. |
|
|
|
// (We avoid to raymarch the depth texture to get the refracted point.) |
|
|
|
|
|
|
|
uint2 depthSize = uint2(_PyramidDepthMipSize.xy); |
|
|
|
uint2 depthSize = uint2(_DepthPyramidSize.xy); |
|
|
|
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInputs.positionNDC * (depthSize >> 2), 2).r; |
|
|
|
float pyramidDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, posInputs.positionNDC * (depthSize >> 2), 2).r; |
|
|
|
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams); |
|
|
|
|
|
|
|
// Distance from point to the back plane |
|
|
|
|
|
|
preLightData.transparentTransmittance = exp(-bsdfData.absorptionCoefficient * refraction.dist); |
|
|
|
// Empirical remap to try to match a bit the refraction probe blurring for the fallback |
|
|
|
// Use IblPerceptualRoughness so we can handle approx of clear coat. |
|
|
|
preLightData.transparentSSMipLevel = sqrt(preLightData.iblPerceptualRoughness) * uint(_GaussianPyramidColorMipSize.z); |
|
|
|
preLightData.transparentSSMipLevel = sqrt(preLightData.iblPerceptualRoughness) * uint(_ColorPyramidScale.z); |
|
|
|
#endif |
|
|
|
|
|
|
|
return preLightData; |
|
|
|
|
|
|
|
|
|
|
// Calculate screen space coordinates of refracted point in back plane |
|
|
|
float2 refractedBackPointNDC = ComputeNormalizedDeviceCoordinates(refractedBackPointWS, UNITY_MATRIX_VP); |
|
|
|
uint2 depthSize = uint2(_PyramidDepthMipSize.xy); |
|
|
|
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, refractedBackPointNDC * depthSize, 0).r, _ZBufferParams); |
|
|
|
uint2 depthSize = uint2(_DepthPyramidSize.xy); |
|
|
|
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, refractedBackPointNDC * depthSize, 0).r, _ZBufferParams); |
|
|
|
|
|
|
|
// Exit if texel is out of color buffer |
|
|
|
// Or if the texel is from an object in front of the object |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Map the roughness to the correct mip map level of the color pyramid |
|
|
|
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointNDC * _GaussianPyramidColorMipSize.xy, preLightData.transparentSSMipLevel).rgb; |
|
|
|
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, refractedBackPointNDC * _ColorPyramidScale.xy, preLightData.transparentSSMipLevel).rgb; |
|
|
|
|
|
|
|
// Beer-Lamber law for absorption |
|
|
|
lighting.specularTransmitted *= preLightData.transparentTransmittance; |
|
|
|