浏览代码

Merge pull request #302 from EvgeniiG/upstream

Fix the SSS radius range bug and clean up the shader
/RenderPassXR_Sandbox
GitHub 7 年前
当前提交
6be507c7
共有 2 个文件被更改,包括 42 次插入53 次删除
  1. 59
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  2. 36
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl

59
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 unitDirection = float2(1, 0);
float scaledStepSize = scaledPixPerCm.y;
float2 unitDirection = float2(0, 1);
float2 unitDirection = float2(0, 1);
float2 scaledDirection = scaledPixPerCm * unitDirection;
float2 scaledDirection = pixelsPerCm * unitDirection;
#if (RBG_BILATERAL_WEIGHTS != 0)
#if RBG_BILATERAL_WEIGHTS
float3 halfRcpVariance = _HalfRcpWeightedVariances[profileID].rgb;
#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;

// 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)

[flatten]
if (any(sampleIrradiance))
{
#if SSS_BILATERAL
float zDistance = unitScale * sampleDepth - (unitScale * centerPosVS.z);
float zDistance = centimPerUnit * sampleDepth - (centimPerUnit * centerPosVS.z);
#endif
totalIrradiance += sampleWeight * sampleIrradiance;
totalWeight += sampleWeight;

36
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl


return N;
}
// Generates an orthonormal basis from a unit vector.
// Generates an orthonormal right-handed basis from a unit vector.
// Ref: http://marc-b-reynolds.github.io/quaternions/2016/07/06/Orthonormal.html
float3 upVector = abs(localZ.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0);
float3 localX = normalize(cross(upVector, localZ));
float3 localY = cross(localZ, localX);
return float3x3(localX, localY, localZ);
}
float x = localZ.x;
float y = localZ.y;
float z = localZ.z;
float sz = z >= 0 ? 1 : -1;
float a = 1 / (sz + z);
float ya = y * a;
float b = x * ya;
float c = x * sz;
// TODO: test
/*
// http://orbit.dtu.dk/files/57573287/onb_frisvad_jgt2012.pdf
void GetLocalFrame(float3 N, out float3 tangentX, out float3 tangentY)
{
if (N.z < -0.999) // Handle the singularity
{
tangentX = float3(0.0, -1.0, 0.0);
tangentY = float3(-1.0, 0.0, 0.0);
return ;
}
float3 localX = float3(c * x * a - 1, sz * b, c);
float3 localY = float3(b, y * ya - sz, y);
float a = 1.0 / (1.0 + N.z);
float b = -N.x * N.y * a;
tangentX = float3(1.0 - N.x * N.x * a , b, -N.x);
tangentY = float3(b, 1.0 - N.y * N.y * a, -N.y);
return float3x3(localX, localY, localZ);
*/
#endif // UNITY_COMMON_LIGHTING_INCLUDED
正在加载...
取消
保存