浏览代码

HDRenderPipeline: Add reference mode for SSS

/RenderPassXR_Sandbox
Sebastien Lagarde 8 年前
当前提交
0373fa24
共有 4 个文件被更改,包括 326 次插入25 次删除
  1. 123
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  2. 108
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset
  3. 120
      Assets/TestScenes/HDTest/GraphicTest/SSS/perry_normal.png.meta

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


#pragma vertex Vert
#pragma fragment Frag
#define SSS_REFERENCE 1 // Enable reference mode for debugging
#define SSS_PASS 1
#define SSS_BILATERAL 1
#define SSS_DEBUG 0

return /* 0.25 * */ S * (expOneThird + expOneThird * expOneThird * expOneThird);
}
#if SSS_REFERENCE
// In reference mode we compute importance sampling separately for (R, G, B)
float KernelValCircle(float r, float s)
{
float expOneThird = exp(((-1.0 / 3.0) * r) * s);
return 0.25 * s * (expOneThird + expOneThird * expOneThird * expOneThird);
}
// All funciton below are similar to C# version
float KernelPdf(float r, float s)
{
float expOneThird = exp(((-1.0 / 3.0) * r) * s);
return 0.25 * s * (expOneThird + expOneThird * expOneThird * expOneThird);
}
float KernelCdf(float r, float s)
{
return 1.0 - 0.25 * exp(-r * s) - 0.75f * exp(-r * s * (1.0 / 3.0));
}
float KernelCdfDerivative1(float r, float s)
{
return 0.25 * s * exp(-r * s) * (1.0f + exp(r * s * (2.0 / 3.0)));
}
float KernelCdfDerivative2(float r, float s)
{
return (-1.0 / 12.0) * s * s * exp(-r * s) * (3.0 + exp(r * s * (2.0 / 3.0)));
}
// The CDF is not analytically invertible, so we use Halley's Method of root finding.
// { f(r, s, p) = CDF(r, s) - p = 0 } with the initial guess { r = (10^p - 1) / s }.
float KernelCdfInverse(float p, float s)
{
// Supply the initial guess.
float r = (pow(10.0, p) - 1.0) / s;
float t = FLT_MAX;
while (true)
{
float f0 = KernelCdf(r, s) - p;
float f1 = KernelCdfDerivative1(r, s);
float f2 = KernelCdfDerivative2(r, s);
float dr = f0 / (f1 * (1.0 - f0 * f2 / (2.0 * f1 * f1)));
if (abs(dr) < t)
{
r = r - dr;
t = abs(dr);
}
else
{
// Converged to the best result.
break;
}
}
return r;
}
#endif // #if SSS_REFERENCE
// 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 shapeParam = _SurfaceShapeParams[profileID].rgb;
float maxDistance = _SurfaceShapeParams[profileID].a;
// Calculate the size of a pixel in unity unit on the screen. This will allow to be take into account, perspective, FOV, aspect ratio and have a constant effects.
// Reconstruct the view-space position.
float2 centerPosSS = posInput.positionSS;
float2 cornerPosSS = centerPosSS + 0.5 * _ScreenSize.zw;

float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerMm = distScale * rcp(millimPerUnit * unitsPerPixel);
float2 centerPosition = posInput.unPositionSS;
#if SSS_REFERENCE
float3 totalIrradiance = 0.0;
float3 totalWeight = 0.0;
// Add some jittering on Hammersley2d
float2 randNum = InitRandom(centerPosSS.xy * 0.5 + 0.5);
/* Perform integration over the screen-aligned plane in the view space. */
/* TODO: it would be more accurate to use the tangent plane instead. */
uint sampleCount = 1000;
float rcpDistScale = rcp(distScale);
float3 maxRadius;
maxRadius.x = KernelCdfInverse(1, shapeParam.x);
maxRadius.y = KernelCdfInverse(1, shapeParam.y);
maxRadius.z = KernelCdfInverse(1, shapeParam.z);
for (uint i = 0; i < sampleCount; ++i)
{
float2 u = Hammersley2d(i, sampleCount);
u = frac(u + randNum);
float3 r = maxRadius * u.x;
float phi = TWO_PI * u.y;
float irradiance[3];
float w[3];
for (int j = 0; j < 3; j++)
{
float2 vec = r[j] * float2(cos(phi), sin(phi));
float2 position = centerPosition + vec * scaledPixPerMm;
float3 value = LOAD_TEXTURE2D(_IrradianceSource, position).rgb;
irradiance[j] = value[j];
float z = LOAD_TEXTURE2D(_MainDepthTexture, position).r;
float d = LinearEyeDepth(z, _ZBufferParams);
float t = millimPerUnit * d - (millimPerUnit * centerPosVS.z);
// Reducing the integration distance is equivalent to stretching the integration axis.
w[j] = KernelValCircle(sqrt(r[j] * r[j] + t * t) * rcpDistScale, shapeParam[j]);
}
totalIrradiance += float3(w[0], w[1], w[2]) * float3(irradiance[0], irradiance[1], irradiance[2]);
totalWeight += float3(w[0], w[1], w[2]);
}
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
#else
float2 centerPosition = posInput.unPositionSS;
float maxDistInPixels = maxDistance * max(scaledPixPerMm.x, scaledPixPerMm.y);
float maxDistInPixels = maxDistance * max(scaledPixPerMm.x, scaledPixPerMm.y);
// We perform point sampling. Therefore, we can avoid the cost
// of filtering if we stay within the bounds of the current pixel.

}
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
#endif
}
ENDHLSL
}

108
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset


m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: SkinSSSProfile
m_EditorClassIdentifier:
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
scatteringDistance: {r: 1.1376, g: 0.48000002, b: 0.311, a: 1}
volumeAlbedo: {r: 1, g: 1, b: 1, a: 1}
lenVolMeanFreePath: 0.5
enableTransmission: 0
enableThinObject: 0
tintColor: {r: 1, g: 1, b: 1, a: 1}
transmissionMode: 0
worldScale: 1
m_FilterKernel:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.00000001629312}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.034422863}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.07085508}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.112142384}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.16452742}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.25364923}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.03442289}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.07085508}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11214242}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.16452742}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.2536493}
m_HalfRcpVariances:
- {x: 49.999992, y: 49.999992, z: 49.999992}
- {x: 12.499998, y: 12.499998, z: 12.499998}
m_HalfRcpWeightedVariances: {x: 22.222221, y: 22.222221, z: 22.222221, w: 22.222221}
m_SurfaceShapeParam: {x: 0.87904364, y: 2.0833333, z: 3.215434}
m_VolumeShapeParam: {x: 2.08, y: 2.08, z: 2.08}
m_KernelSize: 12.695085
m_FilterKernelNearField:
- {x: 0, y: 2.2752}
- {x: 0.04187585, y: 2.3315494}
- {x: 0.084798716, y: 2.3903832}
- {x: 0.12881488, y: 2.4518554}
- {x: 0.17397404, y: 2.5161326}
- {x: 0.22032872, y: 2.583395}
- {x: 0.267935, y: 2.6538382}
- {x: 0.3168525, y: 2.7276735}
- {x: 0.36714503, y: 2.8051307}
- {x: 0.41888067, y: 2.8864596}
- {x: 0.4721323, y: 2.9719322}
- {x: 0.52697784, y: 3.0618453}
- {x: 0.583501, y: 3.1565225}
- {x: 0.6417915, y: 3.2563193}
- {x: 0.70194584, y: 3.3616228}
- {x: 0.76406825, y: 3.4728618}
- {x: 0.8282707, y: 3.5905046}
- {x: 0.89467406, y: 3.7150698}
- {x: 0.9634095, y: 3.8471303}
- {x: 1.0346189, y: 3.9873197}
- {x: 1.1084564, y: 4.136343}
- {x: 1.1850897, y: 4.294986}
- {x: 1.2647012, y: 4.464123}
- {x: 1.3474909, y: 4.644736}
- {x: 1.4336771, y: 4.837929}
- {x: 1.5234994, y: 5.044944}
- {x: 1.6172218, y: 5.267191}
- {x: 1.7151353, y: 5.5062685}
- {x: 1.8175629, y: 5.764007}
- {x: 1.9248614, y: 6.0425}
- {x: 2.03743, y: 6.3441663}
- {x: 2.1557157, y: 6.6718116}
- {x: 2.2802188, y: 7.028707}
- {x: 2.4115057, y: 7.4186993}
- {x: 2.5502179, y: 7.8463435}
- {x: 2.697088, y: 8.317072}
- {x: 2.8529575, y: 8.8374405}
- {x: 3.0187979, y: 9.415412}
- {x: 3.1957443, y: 10.0608}
- {x: 3.3851275, y: 10.785814}
- {x: 3.5885308, y: 11.6058855}
- {x: 3.8078547, y: 12.540808}
- {x: 4.045411, y: 13.616411}
- {x: 4.3040547, y: 14.867097}
- {x: 4.5873733, y: 16.339737}
- {x: 4.8999653, y: 18.099928}
- {x: 5.24786, y: 20.24236}
- {x: 5.6392126, y: 22.909132}
- {x: 6.085423, y: 26.323515}
- {x: 6.603162, y: 30.857708}
- {x: 7.2182465, y: 37.181835}
- {x: 7.973892, y: 46.63635}
- {x: 8.951069, y: 62.349247}
- {x: 10.331516, y: 93.70535}
- {x: 12.695085, y: 187.63008}
m_FilterKernelFarField:
- {x: 0, y: 2.2752}
- {x: 0.1119148, y: 2.428116}
- {x: 0.23154786, y: 2.599871}
- {x: 0.35987368, y: 2.7938344}
- {x: 0.4980454, y: 3.014175}
- {x: 0.64743865, y: 3.2661045}
- {x: 0.8097081, y: 3.5562098}
- {x: 0.98686373, y: 3.8929236}
- {x: 1.1813745, y: 4.287201}
- {x: 1.3963094, y: 4.753515}
- {x: 1.6355395, y: 5.3113794}
- {x: 1.9040304, y: 5.9877467}
- {x: 2.208282, y: 6.8209767}
- {x: 2.5570207, y: 7.8677344}
- {x: 2.962344, y: 9.215794}
- {x: 3.4417362, y: 11.009651}
- {x: 4.021929, y: 13.507053}
- {x: 4.7471194, y: 17.22073}
- {x: 5.69928, y: 23.344505}
- {x: 7.061074, y: 35.459232}
- {x: 9.4131155, y: 71.47749}

120
Assets/TestScenes/HDTest/GraphicTest/SSS/perry_normal.png.meta


fileFormatVersion: 2
guid: 1394e1f9623277f4a896da13c142cf51
timeCreated: 1497214968
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 1
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: tvOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Windows Store Apps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存