浏览代码

Fix the bug with the radius scale in SSS

/RenderPassXR_Sandbox
Evgenii Golubev 8 年前
当前提交
d752b30a
共有 1 个文件被更改,包括 26 次插入29 次删除
  1. 55
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader

55
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


}
// Computes F(x)/P(x), s.t. x = sqrt(r^2 + t^2).
float3 ComputeBilateralWeight(float3 S, float r, float t, float rcpDistScale, float rcpPdf)
float3 ComputeBilateralWeight(float3 S, float r, float t, float rcpPdf)
// Reducing the integration distance is equivalent to stretching the integration axis.
float3 val = KernelValCircle(sqrt(r * r + t * t) * rcpDistScale, S);
float3 val = KernelValCircle(sqrt(r * r + t * t), S);
// Rescaling of the PDF is handled via 'totalWeight'.
// Rescaling of the PDF is handled by 'totalWeight'.
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
{ \
float r = kernel[profileID][i][0]; \
/* The relative sample position is known at compile time. */ \

float2 position = centerPosUnSS + vec * scaledPixPerMm; \
float2 position = centerPosUnSS + vec * pixelsPerMm; \
float3 irradiance = LOAD_TEXTURE2D(_IrradianceSource, position).rgb; \
\
/* TODO: see if making this a [branch] improves performance. */ \

float d = LinearEyeDepth(z, _ZBufferParams); \
float t = millimPerUnit * d - (millimPerUnit * centerDepthVS); \
float p = kernel[profileID][i][1]; \
float3 w = ComputeBilateralWeight(shapeParam, r, t, rcpDistScale, p); \
float3 w = ComputeBilateralWeight(shapeParam, r, t, p); \
\
totalIrradiance += w * irradiance; \
totalWeight += w; \

}
#define SSS_LOOP(n, kernel, profileID, shapeParam, centerPosUnSS, centerDepthVS, \
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
{ \
float centerRcpPdf = kernel[profileID][0][1]; \
float3 centerWeight = KernelValCircle(0, shapeParam) * centerRcpPdf; \

for (uint i = 1; i < n; i++) \
{ \
SSS_ITER(i, n, kernel, profileID, shapeParam, centerPosUnSS, centerDepthVS, \
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
} \
}

float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, centerDepth, _InvProjMatrix);
// Compute the view-space dimensions of the pixel as a quad projected onto geometry.
float2 unitsPerPixel = 2 * (cornerPosVS.xy - centerPosVS.xy);
float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy);
float metersPerUnit = _WorldScales[profileID];
float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerMm = distScale * rcp(millimPerUnit * unitsPerPixel);
// Rescaling the filter is equivalent to inversely scaling the world.
float metersPerUnit = _WorldScales[profileID] / distScale;
float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 pixelsPerMm = rcp(millimPerUnit * unitsPerPixel);
// Take the first (central) sample.
// TODO: copy its neighborhood into LDS.

float maxDistInPixels = maxDistance * max(scaledPixPerMm.x, scaledPixPerMm.y);
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y);
[branch]
if (distScale == 0 || maxDistInPixels < 1)
{

#else
SSS_LOOP(SSS_N_SAMPLES_FAR_FIELD, _FilterKernelsFarField,
profileID, shapeParam, centerPosition, centerPosVS.z,
millimPerUnit, scaledPixPerMm, rcp(distScale),
totalIrradiance, totalWeight)
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight)
#endif
}
else

#else
SSS_LOOP(SSS_N_SAMPLES_NEAR_FIELD, _FilterKernelsNearField,
profileID, shapeParam, centerPosition, centerPosVS.z,
millimPerUnit, scaledPixPerMm, rcp(distScale),
totalIrradiance, totalWeight)
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight)
float metersPerUnit = _WorldScales[profileID] * SSS_BASIC_DISTANCE_SCALE;
float centimPerUnit = CENTIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerCm = distScale * rcp(centimPerUnit * unitsPerPixel);
float unitScale = centimPerUnit / distScale;
// Rescaling the filter is equivalent to inversely scaling the world.
float metersPerUnit = _WorldScales[profileID] / distScale * SSS_BASIC_DISTANCE_SCALE;
float centimPerUnit = CENTIMETERS_PER_METER * metersPerUnit;
float2 pixelsPerCm = rcp(centimPerUnit * unitsPerPixel);
float scaledStepSize = scaledPixPerCm.x;
float2 unitDirection = float2(1, 0);
float2 unitDir = float2(1, 0);
float scaledStepSize = scaledPixPerCm.y;
float2 unitDirection = float2(0, 1);
float2 unitDir = float2(0, 1);
float2 scaledDirection = scaledPixPerCm * unitDirection;
float2 scaledDirection = pixelsPerCm * unitDir;
float phi = 0; // Random rotation; unused for now
float2x2 rotationMatrix = float2x2(cos(phi), -sin(phi), sin(phi), cos(phi));
float2 rotatedDirection = mul(rotationMatrix, scaledDirection);

// We perform point sampling. Therefore, we can avoid the cost
// of filtering if we stay within the bounds of the current pixel.
// We use the value of 1 instead of 0.5 as an optimization.
float maxDistInPixels = scaledStepSize * maxDistance;
float maxDistInPixels = maxDistance * max(pixelsPerCm.x, pixelsPerCm.y);
[branch]
if (distScale == 0 || maxDistInPixels < 1)

// Ref #2: Separable SSS, Supplementary Materials, Section E.
float rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
float sampleDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float zDistance = unitScale * sampleDepth - (unitScale * centerPosVS.z);
float zDistance = centimPerUnit * sampleDepth - (centimPerUnit * centerPosVS.z);
sampleWeight *= exp(-zDistance * zDistance * halfRcpVariance);
#endif

正在加载...
取消
保存