浏览代码
Merge pull request #342 from EvgeniiG/opt_sss
Merge pull request #342 from EvgeniiG/opt_sss
Port SSS to compute with an LDS texture cache/RenderPassXR_Sandbox
GitHub
7 年前
当前提交
f92ef9c5
共有 27 个文件被更改,包括 2927 次插入 和 401 次删除
-
161Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
-
3Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset
-
5Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
-
10Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
-
11Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CopyStencilBuffer.shader
-
224Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
-
154Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset
-
84Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
-
2Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/HDRenderPipelineResources.asset
-
2Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs
-
1Assets/ScriptableRenderPipeline/ShaderLibrary/API/D3D11.hlsl
-
1Assets/ScriptableRenderPipeline/ShaderLibrary/API/Metal.hlsl
-
1Assets/ScriptableRenderPipeline/ShaderLibrary/API/PSSL.hlsl
-
1Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
-
2Assets/TestScenes/HDTest/GraphicTest/SSS/Materials/SSSHead.mat
-
428Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute
-
10Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute.meta
-
72Assets/ScriptableRenderPipeline/ShaderLibrary/SpaceFillingCurves.hlsl
-
10Assets/ScriptableRenderPipeline/ShaderLibrary/SpaceFillingCurves.hlsl.meta
-
116Assets/TestScenes/HDTest/GraphicTest/SSS/ProfilingSkinSSSProfile.asset
-
9Assets/TestScenes/HDTest/GraphicTest/SSS/ProfilingSkinSSSProfile.asset.meta
-
1001Assets/TestScenes/HDTest/GraphicTest/SSS/Test - SSS model .prefab
-
10Assets/TestScenes/HDTest/GraphicTest/SSS/Test - SSS model .prefab.meta
-
1001Assets/TestScenes/HDTest/SSSProfiling.unity
-
9Assets/TestScenes/HDTest/SSSProfiling.unity.meta
-
0/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader.meta
-
0/Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
|
|||
// ===================== Performs integration of the Disney BSSRDF over a disk ===================== |
|||
|
|||
//-------------------------------------------------------------------------------------------------- |
|||
// Definitions |
|||
//-------------------------------------------------------------------------------------------------- |
|||
|
|||
// #pragma enable_d3d11_debug_symbols |
|||
|
|||
// Tweak parameters. |
|||
#define SSS_BILATERAL_FILTER 1 |
|||
#define SSS_USE_LDS_CACHE 1 |
|||
#define SSS_ENABLE_NEAR_FIELD 0 |
|||
#define SSS_SAMPLE_TEST_HTILE 0 |
|||
#define SSS_USE_TANGENT_PLANE 0 |
|||
#define SSS_CLAMP_ARTIFACT 0 |
|||
#define SSS_DEBUG_LOD 0 |
|||
#define SSS_DEBUG_NORMAL_VS 0 |
|||
|
|||
// Do not modify these. |
|||
#define SSS_PASS 1 |
|||
#define MILLIMETERS_PER_METER 1000 |
|||
#define CENTIMETERS_PER_METER 100 |
|||
#define GROUP_SIZE_1D 16 |
|||
#define GROUP_SIZE_2D (GROUP_SIZE_1D * GROUP_SIZE_1D) |
|||
#define TEXTURE_CACHE_BORDER 2 |
|||
#define TEXTURE_CACHE_SIZE_1D (GROUP_SIZE_1D + 2 * TEXTURE_CACHE_BORDER) |
|||
|
|||
//-------------------------------------------------------------------------------------------------- |
|||
// Included headers |
|||
//-------------------------------------------------------------------------------------------------- |
|||
|
|||
#include "../../../../ShaderLibrary/Common.hlsl" |
|||
#include "../../../../ShaderLibrary/SpaceFillingCurves.hlsl" |
|||
#include "../../../ShaderVariables.hlsl" |
|||
#define UNITY_MATERIAL_LIT |
|||
#include "../../../Material/Material.hlsl" |
|||
#include "../../../Lighting/LightDefinition.cs.hlsl" |
|||
|
|||
//-------------------------------------------------------------------------------------------------- |
|||
// Inputs & outputs |
|||
//-------------------------------------------------------------------------------------------------- |
|||
|
|||
float4 _WorldScales[SSS_N_PROFILES]; // Size of the world unit in meters (only the X component is used) |
|||
float4 _FilterKernels[SSS_N_PROFILES][SSS_N_SAMPLES_NEAR_FIELD]; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF |
|||
|
|||
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters |
|||
TEXTURE2D(_DepthTexture); // Z-buffer |
|||
TEXTURE2D(_StencilTexture); // DXGI_FORMAT_R8_UINT is not supported by Unity |
|||
TEXTURE2D(_HTile); // DXGI_FORMAT_R8_UINT is not supported by Unity |
|||
TEXTURE2D(_IrradianceSource); // Includes transmitted light |
|||
|
|||
// Contains the HDR color for non-SSS materials. |
|||
// In case of SSS, it only contains the specular lighting, which we additively blend with the SSS lighting. |
|||
RW_TEXTURE2D(float4, _CameraColorTexture); |
|||
|
|||
//-------------------------------------------------------------------------------------------------- |
|||
// Implementation |
|||
//-------------------------------------------------------------------------------------------------- |
|||
|
|||
// 6656 bytes used. It appears that the reserved LDS space must be a multiple of 512 bytes. |
|||
#if SSS_USE_LDS_CACHE |
|||
groupshared float4 textureCache[TEXTURE_CACHE_SIZE_1D * TEXTURE_CACHE_SIZE_1D]; // {irradiance, linearDepth} |
|||
#endif |
|||
groupshared bool processGroup; |
|||
|
|||
bool StencilTest(int2 pixelCoord, float stencilRef) |
|||
{ |
|||
bool passedStencilTest; |
|||
|
|||
#if SSS_SAMPLE_TEST_HTILE |
|||
int2 tileCoord = pixelCoord >> 3; // Divide by 8 |
|||
|
|||
// Perform the stencil test (reject at the tile rate). |
|||
passedStencilTest = stencilRef == LOAD_TEXTURE2D(_HTile, tileCoord).r; |
|||
|
|||
[branch] if (passedStencilTest) |
|||
#else |
|||
// It is extremely uncommon for individual samples to fail the HTile test. |
|||
// Unfortunately, our copy of HTile does not allow to accept at the tile rate. |
|||
// Therefore, we choose not to perform the HiS test here. |
|||
#endif |
|||
{ |
|||
// Unfortunately, our copy of HTile does not allow to accept at the tile rate. |
|||
// Therefore, we have to additionally perform the stencil test at the pixel rate. |
|||
passedStencilTest = stencilRef == LOAD_TEXTURE2D(_StencilTexture, pixelCoord).r; |
|||
} |
|||
|
|||
return passedStencilTest; |
|||
} |
|||
|
|||
#if SSS_USE_LDS_CACHE |
|||
float4 LoadSampleFromCacheMemory(int2 cacheCoord) |
|||
{ |
|||
return textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x)]; |
|||
} |
|||
#endif |
|||
|
|||
float4 LoadSampleFromVideoMemory(int2 pixelCoord) |
|||
{ |
|||
float3 irradiance = LOAD_TEXTURE2D(_IrradianceSource, pixelCoord).rgb; |
|||
float depth = LOAD_TEXTURE2D(_DepthTexture, pixelCoord).r; |
|||
|
|||
return float4(irradiance, LinearEyeDepth(depth, _ZBufferParams)); |
|||
} |
|||
|
|||
// Returns {irradiance, linearDepth}. |
|||
float4 LoadSample(int2 pixelCoord, int2 cacheAnchor) |
|||
{ |
|||
int2 cacheCoord = pixelCoord - cacheAnchor; |
|||
bool isInCache = max((uint)cacheCoord.x, (uint)cacheCoord.y) < TEXTURE_CACHE_SIZE_1D; |
|||
|
|||
#if SSS_USE_LDS_CACHE |
|||
[branch] if (isInCache) |
|||
{ |
|||
return LoadSampleFromCacheMemory(cacheCoord); |
|||
} |
|||
else |
|||
#endif |
|||
{ |
|||
float stencilRef = STENCILLIGHTINGUSAGE_SPLIT_LIGHTING; |
|||
|
|||
[branch] if (StencilTest(pixelCoord, stencilRef)) |
|||
{ |
|||
return LoadSampleFromVideoMemory(pixelCoord); |
|||
} |
|||
else |
|||
{ |
|||
return float4(0, 0, 0, 0); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal(). |
|||
// N.b.: the returned value is multiplied by 4. It is irrelevant due to weight renormalization. |
|||
float3 KernelValCircle(float r, float3 S) |
|||
{ |
|||
float3 expOneThird = exp(((-1.0 / 3.0) * r) * S); |
|||
return /* 0.25 * */ S * (expOneThird + expOneThird * expOneThird * expOneThird); |
|||
} |
|||
|
|||
// Computes F(r)/P(r), s.t. r = sqrt(xy^2 + z^2). |
|||
// Rescaling of the PDF is handled by 'totalWeight'. |
|||
float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, float rcpPdf) |
|||
{ |
|||
#if (SSS_BILATERAL_FILTER == 0) |
|||
z = 0; |
|||
#endif |
|||
|
|||
#if SSS_USE_TANGENT_PLANE |
|||
// Both 'xy2' and 'z' require conversion to millimeters. |
|||
float r = sqrt(xy2 + z * z) * mmPerUnit; |
|||
#else |
|||
// Only 'z' requires conversion to millimeters. |
|||
float r = sqrt(xy2 + (z * mmPerUnit) * (z * mmPerUnit)); |
|||
#endif |
|||
|
|||
#if SSS_CLAMP_ARTIFACT |
|||
return saturate(KernelValCircle(r, S) * rcpPdf); |
|||
#else |
|||
return KernelValCircle(r, S) * rcpPdf; |
|||
#endif |
|||
} |
|||
|
|||
void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 centerCoord, int2 cacheAnchor, |
|||
float3 shapeParam, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, |
|||
float3 tangentX, float3 tangentY, float4x4 projMatrix, |
|||
inout float3 totalIrradiance, inout float3 totalWeight) |
|||
{ |
|||
float r = _FilterKernels[profileID][i][iR]; |
|||
// The relative sample position is known at the compile time. |
|||
float phi = SampleDiskFibonacci(i, n).y; |
|||
float2 vec = r * float2(cos(phi), sin(phi)); |
|||
|
|||
// Compute the screen-space position and the squared distance (in mm) in the image plane. |
|||
int2 position; float xy2; |
|||
|
|||
#if SSS_USE_TANGENT_PLANE |
|||
float3 relPosVS = vec.x * tangentX + vec.y * tangentY; |
|||
float3 positionVS = centerPosVS + relPosVS; |
|||
float4 positionCS = mul(projMatrix, float4(positionVS, 1)); |
|||
float2 positionSS = ComputeScreenSpacePosition(positionCS); |
|||
|
|||
position = (int2)(positionSS * _ScreenSize.xy); |
|||
xy2 = dot(relPosVS.xy, relPosVS.xy); |
|||
#else |
|||
position = (int2)(centerCoord + vec * pixelsPerMm); |
|||
xy2 = r * r; |
|||
#endif |
|||
|
|||
float4 textureSample = LoadSample(position, cacheAnchor); |
|||
float3 irradiance = textureSample.rgb; |
|||
float linearDepth = textureSample.a; |
|||
|
|||
// Check the results of the stencil test. |
|||
if (linearDepth > 0) |
|||
{ |
|||
// Apply bilateral weighting. |
|||
float z = linearDepth - centerPosVS.z; |
|||
float p = _FilterKernels[profileID][i][iP]; |
|||
float3 w = ComputeBilateralWeight(xy2, z, mmPerUnit, shapeParam, p); |
|||
|
|||
totalIrradiance += w * irradiance; |
|||
totalWeight += w; |
|||
} |
|||
} |
|||
|
|||
#pragma kernel SubsurfaceScattering |
|||
|
|||
[numthreads(GROUP_SIZE_2D, 1, 1)] |
|||
void SubsurfaceScattering(uint2 groupId : SV_GroupID, |
|||
uint groupThreadId : SV_GroupThreadID) |
|||
{ |
|||
// Note: any factor of 64 is a suitable wave size for our algorithm. |
|||
uint waveIndex = groupThreadId / 64; |
|||
uint laneIndex = groupThreadId % 64; |
|||
uint quadIndex = laneIndex / 4; |
|||
|
|||
// Arrange threads in the Morton order to optimally match the memory layout of GCN tiles. |
|||
uint mortonCode = groupThreadId; |
|||
uint2 localCoord = DecodeMorton2D(mortonCode); |
|||
uint2 tileAnchor = groupId * GROUP_SIZE_1D; |
|||
uint2 pixelCoord = tileAnchor + localCoord; |
|||
int2 cacheAnchor = (int2)tileAnchor - TEXTURE_CACHE_BORDER; |
|||
uint2 cacheCoord = localCoord + TEXTURE_CACHE_BORDER; |
|||
float stencilRef = STENCILLIGHTINGUSAGE_SPLIT_LIGHTING; |
|||
|
|||
[branch] if (groupThreadId == 0) |
|||
{ |
|||
// Check whether the thread group needs to perform any work. |
|||
float s00 = LOAD_TEXTURE2D(_HTile, 2 * groupId + uint2(0, 0)).r; |
|||
float s10 = LOAD_TEXTURE2D(_HTile, 2 * groupId + uint2(1, 0)).r; |
|||
float s01 = LOAD_TEXTURE2D(_HTile, 2 * groupId + uint2(0, 1)).r; |
|||
float s11 = LOAD_TEXTURE2D(_HTile, 2 * groupId + uint2(1, 1)).r; |
|||
|
|||
// Perform the stencil test (reject at the tile rate). |
|||
processGroup = (stencilRef == s00 || stencilRef == s10 || stencilRef == s01 || stencilRef == s11); |
|||
} |
|||
|
|||
// Wait for the LDS. |
|||
GroupMemoryBarrierWithGroupSync(); |
|||
|
|||
[branch] if (!processGroup) { return; } |
|||
|
|||
float3 centerIrradiance = 0; |
|||
float centerDepth = 0; |
|||
float4 cachedValue = float4(0, 0, 0, 0); |
|||
|
|||
bool passedStencilTest = StencilTest((int2)pixelCoord, stencilRef); |
|||
|
|||
[branch] if (passedStencilTest) |
|||
{ |
|||
centerIrradiance = LOAD_TEXTURE2D(_IrradianceSource, pixelCoord).rgb; |
|||
centerDepth = LOAD_TEXTURE2D(_DepthTexture, pixelCoord).r; |
|||
cachedValue = float4(centerIrradiance, LinearEyeDepth(centerDepth, _ZBufferParams)); |
|||
} |
|||
|
|||
#if SSS_USE_LDS_CACHE |
|||
// Populate the central region of the LDS cache. |
|||
textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x)] = cachedValue; |
|||
|
|||
uint numBorderQuadsPerWave = TEXTURE_CACHE_SIZE_1D / 2 - 1; |
|||
uint halfCacheWidthInQuads = TEXTURE_CACHE_SIZE_1D / 4; |
|||
|
|||
[branch] if (quadIndex < numBorderQuadsPerWave) |
|||
{ |
|||
// Fetch another texel into the LDS. |
|||
uint2 startQuad = halfCacheWidthInQuads * uint2(waveIndex & 1, waveIndex >> 1); |
|||
|
|||
uint2 quadCoord; |
|||
|
|||
// The traversal order is such that the quad's X coordinate is monotonically increasing. |
|||
// Note: the compiler can heavily optimize the code below, as the switch is scalar, |
|||
// and there are very few unique values due to the symmetry. |
|||
switch (waveIndex) |
|||
{ |
|||
case 0: |
|||
quadCoord.x = max(0, (int)(quadIndex - (halfCacheWidthInQuads - 1))); |
|||
quadCoord.y = max(0, (int)((halfCacheWidthInQuads - 1) - quadIndex)); |
|||
break; |
|||
case 1: |
|||
quadCoord.x = min(quadIndex, halfCacheWidthInQuads - 1); |
|||
quadCoord.y = max(0, (int)(quadIndex - (halfCacheWidthInQuads - 1))); |
|||
break; |
|||
case 2: |
|||
quadCoord.x = max(0, (int)(quadIndex - (halfCacheWidthInQuads - 1))); |
|||
quadCoord.y = min(quadIndex, halfCacheWidthInQuads - 1); |
|||
break; |
|||
default: // 3 |
|||
quadCoord.x = min(quadIndex, halfCacheWidthInQuads - 1); |
|||
quadCoord.y = min(halfCacheWidthInQuads - 1, 2 * (halfCacheWidthInQuads - 1) - quadIndex); |
|||
break; |
|||
} |
|||
|
|||
uint2 cacheCoord2 = 2 * (startQuad + quadCoord) + uint2(laneIndex & 1, (laneIndex >> 1) & 1); |
|||
int2 pixelCoord2 = (int2)(tileAnchor + cacheCoord2) - TEXTURE_CACHE_BORDER; |
|||
float4 cachedValue2 = float4(0, 0, 0, 0); |
|||
|
|||
[branch] if (StencilTest(pixelCoord2, stencilRef)) |
|||
{ |
|||
cachedValue2 = LoadSampleFromVideoMemory(pixelCoord2); |
|||
} |
|||
|
|||
// Populate the border region of the LDS cache. |
|||
textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord2.y, cacheCoord2.x)] = cachedValue2; |
|||
} |
|||
|
|||
// Wait for the LDS. |
|||
GroupMemoryBarrierWithGroupSync(); |
|||
#endif |
|||
|
|||
bool isOffScreen = pixelCoord.x >= (uint)_ScreenSize.x || pixelCoord.y >= (uint)_ScreenSize.y; |
|||
|
|||
[branch] if (!passedStencilTest || isOffScreen) { return; } |
|||
|
|||
PositionInputs posInput = GetPositionInput(pixelCoord, _ScreenSize.zw); |
|||
|
|||
float3 unused; |
|||
|
|||
// The result of the stencil test allows us to statically determine the material type (SSS). |
|||
BSDFData bsdfData; |
|||
FETCH_GBUFFER(gbuffer, _GBufferTexture, pixelCoord); |
|||
DECODE_FROM_GBUFFER(gbuffer, MATERIALFEATUREFLAGS_LIT_SSS, bsdfData, unused); |
|||
|
|||
int profileID = bsdfData.subsurfaceProfile; |
|||
float distScale = bsdfData.subsurfaceRadius; |
|||
float3 shapeParam = _ShapeParams[profileID].rgb; |
|||
float maxDistance = _ShapeParams[profileID].a; |
|||
|
|||
// Reconstruct the view-space position corresponding to the central sample. |
|||
float2 centerPosSS = posInput.positionSS; |
|||
float2 cornerPosSS = centerPosSS + 0.5 * _ScreenSize.zw; |
|||
float3 centerPosVS = ComputeViewSpacePosition(centerPosSS, centerDepth, _InvProjMatrix); |
|||
float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, centerDepth, _InvProjMatrix); |
|||
|
|||
// Rescaling the filter is equivalent to inversely scaling the world. |
|||
float mmPerUnit = MILLIMETERS_PER_METER * (_WorldScales[profileID].x / distScale); |
|||
float unitsPerMm = rcp(mmPerUnit); |
|||
|
|||
// Compute the view-space dimensions of the pixel as a quad projected onto geometry. |
|||
float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy); |
|||
float2 pixelsPerMm = rcp(unitsPerPixel) * unitsPerMm; |
|||
|
|||
// 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. |
|||
// N.b.: our LoD selection algorithm is the same regardless of |
|||
// whether we integrate over the tangent plane or not, since we |
|||
// don't want the orientation of the tangent plane to create |
|||
// divergence of execution across the warp. |
|||
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y); |
|||
|
|||
[branch] if (distScale == 0 || maxDistInPixels < 1) |
|||
{ |
|||
#if SSS_DEBUG_LOD |
|||
_CameraColorTexture[pixelCoord] = float4(0, 0, 1, 1); |
|||
#else |
|||
_CameraColorTexture[pixelCoord] += float4(bsdfData.diffuseColor * centerIrradiance, 1); |
|||
#endif |
|||
return; |
|||
} |
|||
|
|||
float4x4 viewMatrix, projMatrix; |
|||
GetLeftHandedViewSpaceMatrices(viewMatrix, projMatrix); |
|||
|
|||
// Compute the tangent frame in view space. |
|||
float3 normalVS = mul((float3x3)viewMatrix, bsdfData.normalWS); |
|||
float3 tangentX = GetLocalFrame(normalVS)[0] * unitsPerMm; |
|||
float3 tangentY = GetLocalFrame(normalVS)[1] * unitsPerMm; |
|||
|
|||
#if SSS_DEBUG_NORMAL_VS |
|||
// We expect the view-space normal to be front-facing. |
|||
if (normalVS.z >= 0) |
|||
{ |
|||
_CameraColorTexture[pixelCoord] = float4(1, 1, 1, 1); |
|||
return; |
|||
} |
|||
#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; |
|||
|
|||
#if SSS_DEBUG_LOD |
|||
_CameraColorTexture[pixelCoord] = useNearFieldKernel ? float4(1, 0, 0, 1) : float4(0.5, 0.5, 0, 1); |
|||
return; |
|||
#endif |
|||
|
|||
// Compute the indices used to access the individual components of the float4 of the kernel. |
|||
uint iR = useNearFieldKernel ? 0 : 2; // radius |
|||
uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) |
|||
|
|||
float centerRadius = _FilterKernels[profileID][0][iR]; |
|||
float centerRcpPdf = _FilterKernels[profileID][0][iP]; |
|||
float3 centerWeight = KernelValCircle(centerRadius, shapeParam) * centerRcpPdf; |
|||
|
|||
// Accumulate filtered irradiance and bilateral weights (for renormalization). |
|||
float3 totalIrradiance = centerWeight * centerIrradiance; |
|||
float3 totalWeight = centerWeight; |
|||
|
|||
int i, n; // Declare once to avoid the warning from the Unity shader compiler. |
|||
|
|||
[unroll] |
|||
for (i = 1, n = SSS_N_SAMPLES_FAR_FIELD; i < n; i++) |
|||
{ |
|||
// Integrate over the image or tangent plane in the view space. |
|||
EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheAnchor, |
|||
shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, |
|||
tangentX, tangentY, projMatrix, |
|||
totalIrradiance, totalWeight); |
|||
} |
|||
|
|||
[branch] if (!useNearFieldKernel) |
|||
{ |
|||
_CameraColorTexture[pixelCoord] += float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1); |
|||
return; |
|||
} |
|||
|
|||
[unroll] |
|||
for (i = SSS_N_SAMPLES_FAR_FIELD, n = SSS_N_SAMPLES_NEAR_FIELD; i < n; i++) |
|||
{ |
|||
// Integrate over the image or tangent plane in the view space. |
|||
EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheAnchor, |
|||
shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, |
|||
tangentX, tangentY, projMatrix, |
|||
totalIrradiance, totalWeight); |
|||
} |
|||
|
|||
_CameraColorTexture[pixelCoord] += float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1); |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b06a7993621def248addd55d0fe931b1 |
|||
timeCreated: 1500310187 |
|||
licenseType: Pro |
|||
ComputeShaderImporter: |
|||
externalObjects: {} |
|||
currentAPIMask: 4 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
#ifndef UNITY_SPACE_FILLING_CURVES_INCLUDED |
|||
#define UNITY_SPACE_FILLING_CURVES_INCLUDED |
|||
|
|||
// "Insert" a 0 bit after each of the 16 low bits of x. |
|||
// Ref: https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ |
|||
uint Part1By1(uint x) |
|||
{ |
|||
x &= 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210 |
|||
x = (x ^ (x << 8)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210 |
|||
x = (x ^ (x << 4)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210 |
|||
x = (x ^ (x << 2)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10 |
|||
x = (x ^ (x << 1)) & 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 |
|||
return x; |
|||
} |
|||
|
|||
// "Insert" two 0 bits after each of the 10 low bits of x/ |
|||
// Ref: https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ |
|||
uint Part1By2(uint x) |
|||
{ |
|||
x &= 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210 |
|||
x = (x ^ (x << 16)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210 |
|||
x = (x ^ (x << 8)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210 |
|||
x = (x ^ (x << 4)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10 |
|||
x = (x ^ (x << 2)) & 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 |
|||
return x; |
|||
} |
|||
|
|||
// Inverse of Part1By1 - "delete" all odd-indexed bits/ |
|||
// Ref: https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ |
|||
uint Compact1By1(uint x) |
|||
{ |
|||
x &= 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 |
|||
x = (x ^ (x >> 1)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10 |
|||
x = (x ^ (x >> 2)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210 |
|||
x = (x ^ (x >> 4)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210 |
|||
x = (x ^ (x >> 8)) & 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210 |
|||
return x; |
|||
} |
|||
|
|||
// Inverse of Part1By2 - "delete" all bits not at positions divisible by 3/ |
|||
// Ref: https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ |
|||
uint Compact1By2(uint x) |
|||
{ |
|||
x &= 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 |
|||
x = (x ^ (x >> 2)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10 |
|||
x = (x ^ (x >> 4)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210 |
|||
x = (x ^ (x >> 8)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210 |
|||
x = (x ^ (x >> 16)) & 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210 |
|||
return x; |
|||
} |
|||
|
|||
uint EncodeMorton2D(uint2 coord) |
|||
{ |
|||
return (Part1By1(coord.y) << 1) + Part1By1(coord.x); |
|||
} |
|||
|
|||
uint EncodeMorton3D(uint3 coord) |
|||
{ |
|||
return (Part1By2(coord.z) << 2) + (Part1By2(coord.y) << 1) + Part1By2(coord.x); |
|||
} |
|||
|
|||
uint2 DecodeMorton2D(uint code) |
|||
{ |
|||
return uint2(Compact1By1(code >> 0), Compact1By1(code >> 1)); |
|||
} |
|||
|
|||
uint3 DecodeMorton3D(uint code) |
|||
{ |
|||
return uint3(Compact1By2(code >> 0), Compact1By2(code >> 1), Compact1By2(code >> 2)); |
|||
} |
|||
|
|||
#endif // UNITY_SPACE_FILLING_CURVES_INCLUDED |
|
|||
fileFormatVersion: 2 |
|||
guid: 063144fddd2c1be41b9d09dec6314fc7 |
|||
timeCreated: 1500391830 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
externalObjects: {} |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!114 &11400000 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_PrefabParentObject: {fileID: 0} |
|||
m_PrefabInternal: {fileID: 0} |
|||
m_GameObject: {fileID: 0} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3} |
|||
m_Name: ProfilingSkinSSSProfile |
|||
m_EditorClassIdentifier: |
|||
scatteringDistance: {r: 0.758, g: 0.321, b: 0.201, a: 1} |
|||
transmissionTint: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1} |
|||
texturingMode: 0 |
|||
transmissionMode: 0 |
|||
thicknessRemap: {x: 0, y: 12.031147} |
|||
worldScale: 1 |
|||
settingsIndex: 4 |
|||
m_ShapeParam: {x: 1.3192612, y: 3.1152647, z: 4.9751244} |
|||
m_MaxRadius: 10.03481 |
|||
m_FilterKernelNearField: |
|||
- {x: 0.013865918, y: 1.5345725} |
|||
- {x: 0.04211352, y: 1.5729346} |
|||
- {x: 0.07107388, y: 1.6130018} |
|||
- {x: 0.100779116, y: 1.6548817} |
|||
- {x: 0.13126306, y: 1.6986896} |
|||
- {x: 0.16256203, y: 1.7445502} |
|||
- {x: 0.1947145, y: 1.7925992} |
|||
- {x: 0.22776169, y: 1.8429838} |
|||
- {x: 0.26174724, y: 1.8958628} |
|||
- {x: 0.29671827, y: 1.9514104} |
|||
- {x: 0.33272493, y: 2.0098157} |
|||
- {x: 0.369821, y: 2.0712852} |
|||
- {x: 0.40806437, y: 2.1360447} |
|||
- {x: 0.44751683, y: 2.2043417} |
|||
- {x: 0.48824534, y: 2.276447} |
|||
- {x: 0.5303216, y: 2.3526597} |
|||
- {x: 0.5738235, y: 2.433308} |
|||
- {x: 0.61883456, y: 2.5187542} |
|||
- {x: 0.665446, y: 2.609401} |
|||
- {x: 0.713756, y: 2.7056925} |
|||
- {x: 0.763872, y: 2.808125} |
|||
- {x: 0.8159103, y: 2.91725} |
|||
- {x: 0.8699981, y: 3.0336854} |
|||
- {x: 0.9262747, y: 3.1581244} |
|||
- {x: 0.98489225, y: 3.2913465} |
|||
- {x: 1.0460185, y: 3.434234} |
|||
- {x: 1.1098381, y: 3.5877857} |
|||
- {x: 1.1765549, y: 3.7531407} |
|||
- {x: 1.2463952, y: 3.9316032} |
|||
- {x: 1.319611, y: 4.124672} |
|||
- {x: 1.3964823, y: 4.3340797} |
|||
- {x: 1.4773248, y: 4.561845} |
|||
- {x: 1.5624928, y: 4.810328} |
|||
- {x: 1.6523882, y: 5.082317} |
|||
- {x: 1.747467, y: 5.381122} |
|||
- {x: 1.8482518, y: 5.710715} |
|||
- {x: 1.9553448, y: 6.0759025} |
|||
- {x: 2.069445, y: 6.482568} |
|||
- {x: 2.1913698, y: 6.9379897} |
|||
- {x: 2.3220856, y: 7.4513016} |
|||
- {x: 2.4627466, y: 8.0341215} |
|||
- {x: 2.614747, y: 8.701484} |
|||
- {x: 2.7797952, y: 9.473195} |
|||
- {x: 2.9600194, y: 10.375936} |
|||
- {x: 3.1581159, y: 11.446505} |
|||
- {x: 3.3775842, y: 12.737201} |
|||
- {x: 3.6230793, y: 14.324919} |
|||
- {x: 3.9009922, y: 16.327562} |
|||
- {x: 4.220452, y: 18.935623} |
|||
- {x: 4.5951686, y: 22.478209} |
|||
- {x: 5.047148, y: 27.57712} |
|||
- {x: 5.615129, y: 35.564823} |
|||
- {x: 6.3776174, y: 49.90625} |
|||
- {x: 7.5374603, y: 83.30668} |
|||
- {x: 10.03481, y: 250.11497} |
|||
m_FilterKernelFarField: |
|||
- {x: 0.03667902, y: 1.5654991} |
|||
- {x: 0.11374626, y: 1.6734134} |
|||
- {x: 0.19626758, y: 1.7949444} |
|||
- {x: 0.28494877, y: 1.9325867} |
|||
- {x: 0.38062802, y: 2.0894418} |
|||
- {x: 0.48430943, y: 2.2694077} |
|||
- {x: 0.59720695, y: 2.4774427} |
|||
- {x: 0.72080237, y: 2.7199378} |
|||
- {x: 0.8569269, y: 3.005264} |
|||
- {x: 1.007873, y: 3.3445888} |
|||
- {x: 1.1765549, y: 3.7531407} |
|||
- {x: 1.3667475, y: 4.252257} |
|||
- {x: 1.5834517, y: 4.872841} |
|||
- {x: 1.8334827, y: 5.6615734} |
|||
- {x: 2.126473, y: 6.692844} |
|||
- {x: 2.4767098, y: 8.093767} |
|||
- {x: 2.9068332, y: 10.102725} |
|||
- {x: 3.4562516, y: 13.228675} |
|||
- {x: 4.2041187, y: 18.793621} |
|||
- {x: 5.3538504, y: 31.646347} |
|||
- {x: 7.84603, y: 95.44374} |
|||
scatterDistance1: {r: 0.3, g: 0.2, b: 0.2, a: 0} |
|||
scatterDistance2: {r: 0.6, g: 0.2, b: 0.2, a: 0} |
|||
lerpWeight: 0.5 |
|||
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 12.5, z: 12.5, w: 2.4691355} |
|||
m_FilterKernelBasic: |
|||
- {x: 0.09090909, y: 0.21162307, z: 0.21162307, w: -0.000000048879357} |
|||
- {x: 0.09090909, y: 0.18990478, z: 0.18990478, w: -0.11381993} |
|||
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: -0.23580086} |
|||
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: -0.37865555} |
|||
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: -0.57677805} |
|||
- {x: 0.09090909, y: 2.9458339e-10, z: 2.9458339e-10, w: -1.3907351} |
|||
- {x: 0.09090909, y: 0.18990476, z: 0.18990476, w: 0.11382001} |
|||
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: 0.23580086} |
|||
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: 0.37865555} |
|||
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: 0.57677805} |
|||
- {x: 0.09090909, y: 2.9456845e-10, z: 2.9456845e-10, w: 1.3907368} |
|
|||
fileFormatVersion: 2 |
|||
guid: aa5f2cc1c22cad043a617e9e9548b1b9 |
|||
timeCreated: 1493291209 |
|||
licenseType: Pro |
|||
NativeFormatImporter: |
|||
mainObjectFileID: 11400000 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
Assets/TestScenes/HDTest/GraphicTest/SSS/Test - SSS model .prefab
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: ef1a9eb2ee53a8f44bf5543cfe520dc7 |
|||
timeCreated: 1500646713 |
|||
licenseType: Pro |
|||
NativeFormatImporter: |
|||
externalObjects: {} |
|||
mainObjectFileID: 100100000 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
Assets/TestScenes/HDTest/SSSProfiling.unity
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: 3ae49a004ada4ea4486096f6ed8c5d46 |
|||
timeCreated: 1500647185 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue