浏览代码

Modified moment based shadow maps to always use [0;1] z.

/RenderPassXR_Sandbox
uygar 7 年前
当前提交
beaf6e75
共有 4 个文件被更改,包括 35 次插入18 次删除
  1. 4
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  2. 10
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  3. 13
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl
  4. 26
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl

4
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


{
bpp_16 = 1 << 0,
channels_2 = 1 << 1,
reversed_z = 1 << 2
}
protected readonly Flags m_Flags;

readonly ValRange m_DefEVSM_PosExponent_16 = new ValRange( "Positive Exponent" , 1.0f, 1.0f , 5.54f , 1.0f );
readonly ValRange m_DefEVSM_NegExponent_16 = new ValRange( "Negative Exponent" , 1.0f, 1.0f , 5.54f , 1.0f );
readonly ValRange m_DefMSM_LightLeakBias = new ValRange( "Light leak bias" , 0.0f, 0.5f , 0.99f , 1.0f );
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.3f , 1.0f , 0.0001f);
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.0f , 1.0f , 0.0001f);
readonly ValRange m_DefMSM_DepthBias = new ValRange( "Depth Bias" , 0.0f, 0.1f , 1.0f , 0.1f );
public static RenderTextureFormat GetFormat( bool use_16_BitsPerChannel, bool use_2_Channels, bool use_MSM )

{
m_Flags |= (base.m_ShadowmapFormat == RenderTextureFormat.ARGBHalf || base.m_ShadowmapFormat == RenderTextureFormat.RGHalf || base.m_ShadowmapFormat == RenderTextureFormat.ARGB64) ? Flags.bpp_16 : 0;
m_Flags |= (base.m_ShadowmapFormat == RenderTextureFormat.RGFloat || base.m_ShadowmapFormat == RenderTextureFormat.RGHalf) ? Flags.channels_2 : 0;
m_Flags |= SystemInfo.usesReversedZBuffer ? Flags.reversed_z : 0;
m_Shadowmap.enableRandomWrite = true;
m_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now

10
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#endif
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;

static const int kReversed_z = 4; // depth buffer contains reversed z
#if (SHADOW_MOMENT_ALGORITHM == VSM)
# define SHADOW_MOMENTS 2

const int4 validSrc = int4( srcRect.xy, srcRect.xy + srcRect.zw - 1 );
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + srcRect.xy;
int2 ldsIdx = groupThreadId.xy;
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
// calculate an average moment over all samples for a given pixel and load the result into LDS
uint iw, ih, is;

#if MAX_MSAA > 1
for( is = 0; is < sampleCnt; is++ )
{
float depth = depthTex.Load( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ).x;
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
avgMoments = DepthToMoments( depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x );
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x;
avgMoments = DepthToMoments( reverse_z ? (1.0-depth) : depth );
#endif
moments[ldsIdx.y][ldsIdx.x] = avgMoments;

13
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl


float mD = depth - moments.x;
float p = variance / (variance + mD * mD);
#if UNITY_REVERSED_Z
p = saturate( (p - lightLeakBias) / (1.0f - lightLeakBias) );
return max( p, depth >= moments.x );
#else
#endif
}
// helper for EVSM

float quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1]) / ((z[2] - switchVal[1]) * (z[0] - z[1]));
float attenuation = saturate( switchVal[2] + switchVal[3] * quotient );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
#endif
}
float ShadowMoments_SolveDelta4MSM( float3 z, float4 b, float lightLeakBias)

float w1Factor = (z[0] > zFree) ? 1.0 : 0.0;
float attenuation = saturate( (b[1] - b[0] + (b[2] - b[0] - (zFree + 1.0) * (b[1] - b[0])) * (zFree - w1Factor - z[0]) / (z[0] * (z[0] - zFree))) / (zFree - w1Factor) + 1.0 - b[0] );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
#endif
}

26
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl


//
float SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;

float SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;

//
float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;

float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
{
#if UNITY_REVERSED_Z
float depth = 1.0 - tcs.z;
#else
#endif
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;

float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
#if UNITY_REVERSED_Z
float depth = (1.0 - tcs.z) + depthBias;
#else
#endif
payloadOffset++;
float4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );

float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
float depth = tcs.z + depthBias;
#if UNITY_REVERSED_Z
float depth = (1.0 - tcs.z) + depthBias;
#else
float depth = tcs.z + depthBias;
#endif
payloadOffset++;
float4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );

正在加载...
取消
保存