浏览代码

Implement random rotations of the SSS kernel

/main
Evgenii Golubev 6 年前
当前提交
d8fdbbec
共有 3 个文件被更改,包括 19 次插入17 次删除
  1. 4
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Sampling/Fibonacci.hlsl
  2. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/DiffusionProfile/DiffusionProfileSettings.cs
  3. 28
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute

4
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Sampling/Fibonacci.hlsl


// 3 cycles on GCN if 'fibN1' and 'fibN2' are known at compile time.
// N.b.: According to Swinbank and Pusser [SP06], the uniformity of the distribution
// can be slightly improved by introducing an offset of 1/N to the Z (or R) coordinates.
return real2(i / fibN1 + (0.5/ fibN1), frac(i * (fibN2 / fibN1)));
return real2(i / fibN1 + (0.5 / fibN1), frac(i * (fibN2 / fibN1)));
}
#define GOLDEN_RATIO 1.6180339887498948482

{
return real2(i / n + (0.5/ n), frac(i * rcp(GOLDEN_RATIO)));
return real2(i / n + (0.5 / n), frac(i * rcp(GOLDEN_RATIO)));
}
static const uint k_FibonacciSeq[] = {

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/DiffusionProfile/DiffusionProfileSettings.cs


// Importance sample the near field kernel.
for (int i = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1f / n);
float p = (i + 0.5f) * (1.0f / n);
float r = DisneyProfileCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo

// Importance sample the far field kernel.
for (int i = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1f / n);
float p = (i + 0.5f) * (1.0f / n);
float r = DisneyProfileCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo

28
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute


// Tweak parameters.
#define SSS_BILATERAL_FILTER 1
#define SSS_USE_LDS_CACHE 1
#define SSS_TAA_INTEGRATION 1 // Smoother results at the cost of a tiny amount of flickering in under-sampled areas
#define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise.
#define SSS_ENABLE_NEAR_FIELD 0 // Greatly increases the number of samples. Comes at a high cost.
#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals.
#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE.

void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 centerCoord, int2 cacheOffset,
float3 shapeParam, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm,
float3 tangentX, float3 tangentY, float4x4 projMatrix,
float startAngle, float3 tangentX, float3 tangentY, float4x4 projMatrix,
float r = _FilterKernels[profileID][i][iR];
float r = _FilterKernels[profileID][i][iR];
#if (SSS_TAA_INTEGRATION != 0)
// Note that we repeat the pattern twice during the TAA cycle to reduce flickering.
float sinPsi = _TaaFrameRotation.x;
float cosPsi = _TaaFrameRotation.y;
// The angle 'psi' is loop-invariant. All the trigonometry is done at compile time.
// The angle 'psi' is loop-invariant.
float sinPsi = sin(startAngle);
float cosPsi = cos(startAngle);
// cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
// sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
float cosSum = cos(phi) * cosPsi - sin(phi) * sinPsi;

#else
float2 vec = r * float2(cos(phi), sin(phi));
#endif
// Compute the screen-space position and the squared distance (in mm) in the image plane.
int2 position; float xy2;

}
#endif
#if SSS_RANDOM_ROTATION
float startAngle = TWO_PI * GenerateHashedRandomFloat(asuint(centerPosVS));
#else
float startAngle = 0;
#endif
// Use more samples for SS regions larger than 5x5 pixels (rotated by 45 degrees).
bool useNearFieldKernel = SSS_ENABLE_NEAR_FIELD && maxDistInPixels > SSS_LOD_THRESHOLD;

// Integrate over the image or tangent plane in the view space.
EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset,
shapeParam, centerPosVS, mmPerUnit, pixelsPerMm,
tangentX, tangentY, projMatrix,
startAngle, tangentX, tangentY, projMatrix,
totalIrradiance, totalWeight);
}

// Integrate over the image or tangent plane in the view space.
EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset,
shapeParam, centerPosVS, mmPerUnit, pixelsPerMm,
tangentX, tangentY, projMatrix,
startAngle, tangentX, tangentY, projMatrix,
totalIrradiance, totalWeight);
}
正在加载...
取消
保存