|
|
|
|
|
|
// Color pyramid (width, height, lodcount, Unused) |
|
|
|
float4 _GaussianPyramidColorMipSize; |
|
|
|
TEXTURE2D(_GaussianPyramidColorTexture); |
|
|
|
SAMPLER2D(sampler_GaussianPyramidColorTexture); |
|
|
|
SAMPLER2D(sampler_PyramidDepthTexture); |
|
|
|
SamplerState ltc_trilinear_clamp_sampler; |
|
|
|
// TODO: This one should be set into a constant Buffer at pass frequency (with _Screensize) |
|
|
|
TEXTURE2D(_PreIntegratedFGD); |
|
|
|
TEXTURE2D_ARRAY(_LtcData); // We pack the 3 Ltc data inside a texture array |
|
|
|
|
|
|
float3 refractedBackPointWS = float3(0.0, 0.0, 0.0); |
|
|
|
float opticalDepth = 0.0; |
|
|
|
|
|
|
|
uint2 depthSize = uint2(_PyramidDepthMipSize.xy); |
|
|
|
|
|
|
|
// For all refraction approximation, to calculate the refracted point in world space, |
|
|
|
// 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.) |
|
|
|
|
|
|
float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior); |
|
|
|
|
|
|
|
// Get the depth of the approximated back plane |
|
|
|
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r; |
|
|
|
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r; |
|
|
|
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams); |
|
|
|
|
|
|
|
// Distance from point to the back plane |
|
|
|
|
|
|
// So the light is refracted twice: in and out of the tangent sphere |
|
|
|
|
|
|
|
// Get the depth of the approximated back plane |
|
|
|
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r; |
|
|
|
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r; |
|
|
|
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams); |
|
|
|
|
|
|
|
// Distance from point to the back plane |
|
|
|
|
|
|
float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior); |
|
|
|
|
|
|
|
// Get the depth of the approximated back plane |
|
|
|
float pyramidDepth = SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, posInput.positionSS, 2.0).r; |
|
|
|
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r; |
|
|
|
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams); |
|
|
|
|
|
|
|
// Distance from point to the back plane |
|
|
|
|
|
|
// Calculate screen space coordinates of refracted point in back plane |
|
|
|
float4 refractedBackPointCS = mul(_ViewProjMatrix, float4(refractedBackPointWS, 1.0)); |
|
|
|
float2 refractedBackPointSS = ComputeScreenSpacePosition(refractedBackPointCS); |
|
|
|
float refractedBackPointDepth = LinearEyeDepth(SAMPLE_TEXTURE2D_LOD(_PyramidDepthTexture, sampler_PyramidDepthTexture, refractedBackPointSS, 0.0).r, _ZBufferParams); |
|
|
|
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, refractedBackPointSS * 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 |
|
|
|
|
|
|
{ |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, posInput.positionSS, 0.0).rgb; |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb; |
|
|
|
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness); |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, refractedBackPointSS.xy, mipLevel).rgb; |
|
|
|
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness, uint(_GaussianPyramidColorMipSize.z)); |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb; |
|
|
|
|
|
|
|
// Beer-Lamber law for absorption |
|
|
|
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth); |
|
|
|
|
|
|
// Use perfect flat transparency when we cannot fetch the correct pixel color for the refracted point |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, sampler_GaussianPyramidColorTexture, posInput.positionSS, 0.0).rgb; |
|
|
|
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|