浏览代码

Added MSAA support to moment based shadowmaps. Also made some optimizations to the blur compute shader.

/Add-support-for-light-specular-color-tint
uygar 7 年前
当前提交
b90724d4
共有 5 个文件被更改,包括 185 次插入102 次删除
  1. 254
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  2. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl
  3. 25
      ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  4. 4
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs

254
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#define EVSM_4 2
#define MSM 3
#define THREADS 16
#define MAX_BLUR_SIZE 17
#define MAX_BLUR_SIZE (THREADS+1)
#pragma kernel main_VSM_3 KERNEL_MAIN=main_VSM_3 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_VSM_5 KERNEL_MAIN=main_VSM_5 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=5

#pragma kernel main_MSM_15 KERNEL_MAIN=main_MSM_15 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_MSM_17 KERNEL_MAIN=main_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=17
#pragma kernel main_MSAA_VSM_3 KERNEL_MAIN=main_MSAA_VSM_3 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_VSM_5 KERNEL_MAIN=main_MSAA_VSM_5 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_VSM_7 KERNEL_MAIN=main_MSAA_VSM_7 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_VSM_9 KERNEL_MAIN=main_MSAA_VSM_9 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_VSM_11 KERNEL_MAIN=main_MSAA_VSM_11 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_VSM_13 KERNEL_MAIN=main_MSAA_VSM_13 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_VSM_15 KERNEL_MAIN=main_MSAA_VSM_15 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_VSM_17 KERNEL_MAIN=main_MSAA_VSM_17 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_EVSM_2_3 KERNEL_MAIN=main_MSAA_EVSM_2_3 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_EVSM_2_5 KERNEL_MAIN=main_MSAA_EVSM_2_5 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_EVSM_2_7 KERNEL_MAIN=main_MSAA_EVSM_2_7 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_EVSM_2_9 KERNEL_MAIN=main_MSAA_EVSM_2_9 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_EVSM_2_11 KERNEL_MAIN=main_MSAA_EVSM_2_11 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_EVSM_2_13 KERNEL_MAIN=main_MSAA_EVSM_2_13 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_EVSM_2_15 KERNEL_MAIN=main_MSAA_EVSM_2_15 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_EVSM_2_17 KERNEL_MAIN=main_MSAA_EVSM_2_17 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_EVSM_4_3 KERNEL_MAIN=main_MSAA_EVSM_4_3 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_EVSM_4_5 KERNEL_MAIN=main_MSAA_EVSM_4_5 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_EVSM_4_7 KERNEL_MAIN=main_MSAA_EVSM_4_7 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_EVSM_4_9 KERNEL_MAIN=main_MSAA_EVSM_4_9 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_EVSM_4_11 KERNEL_MAIN=main_MSAA_EVSM_4_11 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_EVSM_4_13 KERNEL_MAIN=main_MSAA_EVSM_4_13 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_EVSM_4_15 KERNEL_MAIN=main_MSAA_EVSM_4_15 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_EVSM_4_17 KERNEL_MAIN=main_MSAA_EVSM_4_17 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_MSM_3 KERNEL_MAIN=main_MSAA_MSM_3 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_MSM_5 KERNEL_MAIN=main_MSAA_MSM_5 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_MSM_7 KERNEL_MAIN=main_MSAA_MSM_7 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_MSM_9 KERNEL_MAIN=main_MSAA_MSM_9 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_MSM_11 KERNEL_MAIN=main_MSAA_MSM_11 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_MSM_13 KERNEL_MAIN=main_MSAA_MSM_13 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_MSM_15 KERNEL_MAIN=main_MSAA_MSM_15 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_MSM_17 KERNEL_MAIN=main_MSAA_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=17
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_SIZE (THREADS + BLUR_BORDER + BLUR_BORDER)
#if MAX_MSAA == 1
Texture2D<float> depthTex;
#if MAX_MSAA > 1
Texture2DMS<float> depthTex;
Texture2DMS<float> depthTex;
Texture2D<float> depthTex;
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
uniform uint4 srcRect; // .xy = offset, .zw = width/height
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;
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;
static const int kBits_16 = 1; // 16 bits per channel
static const int kChannels_2 = 2; // 2 channels per pixel

# define SHADOW_MOMENTS 2
float2 DepthToMoments( float depth )
{
return float2( depth, depth * depth );

float2 moments = ShadowMoments_WarpDepth( depth, evsmExponents );
return float4( moments.xy, moments.xy * moments.xy );
}
[branch]
return ShadowMoments_Encode16MSM( depth );
return ShadowMoments_Encode16MSM( depth );
else
{
float dsq = depth * depth;

#endif
#define moment_t MERGE_NAME( float, SHADOW_MOMENTS )
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_STRIDE (THREADS + BLUR_BORDER + BLUR_BORDER)
#define moment_t MERGE_NAME( float, SHADOW_MOMENTS )
groupshared moment_t moments[LDS_SIZE][LDS_SIZE];
groupshared float moments1[THREADS * LDS_STRIDE]; // contains the blurred first moment
groupshared float moments2[THREADS * LDS_STRIDE]; // contains the blurred second moment
groupshared float moments3[THREADS * LDS_STRIDE]; // contains the blurred third moment
groupshared float moments4[THREADS * LDS_STRIDE]; // contains the blurred fourth moment
groupshared float sampleWeights[MAX_MSAA];
groupshared float sumWeights;
int getLDSIdx( int2 pos, int stride )
{
// interleave two consecutive rows to avoid bank conflicts
return (pos.y >> 1) * (stride << 1) + (pos.x << 1) + (pos.y & 1);
}
void writeToShared( moment_t val, int2 pos, int stride )
{
int idx = getLDSIdx( pos, stride );
moments1[idx] = val.x;
moments2[idx] = val.y;
#if SHADOW_MOMENTS == 4
moments3[idx] = val.z;
moments4[idx] = val.w;
#endif
}
moment_t readFromShared( int2 pos, int stride )
{
int idx = getLDSIdx( pos, stride );
moment_t res;
res.x = moments1[idx];
res.y = moments2[idx];
#if SHADOW_MOMENTS == 4
res.z = moments3[idx];
res.w = moments4[idx];
#endif
return res;
}
void KERNEL_MAIN(uint3 dispatchId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID)
void KERNEL_MAIN( uint3 dispatchId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID )
uint i, j; // because the compiler scopes like its 1999.
depthTex.GetDimensions(width, height, sampleCnt);
sampleCnt = Clamp(0, MAX_MSAA, sampleCnt);
depthTex.GetDimensions( width, height, sampleCnt );
sampleCnt = Clamp( sampleCnt, 2, MAX_MSAA );
float sumWeights = 0;
float sampleWeights[MAX_MSAA];
for (i = 0; i < sampleCnt; i++)
if( groupThreadId.x < sampleCnt )
float2 spos = depthTex.GetSamplePosition( i );
sampleWeights[i] = sampleCntRcp; // TODO: find a better weight filter
sumWeights += sampleWeights[i];
float2 spos = depthTex.GetSamplePosition( groupThreadId.x );
sampleWeights[groupThreadId.x] = sampleCntRcp;
sumWeights = 1.0 / sumWeights;
if( groupThreadId.x == 0 )
{
float sum = 0.0;
for( uint i = 0; i < sampleCnt; i++ )
sum += sampleWeights[i];
sumWeights = 1.0 / sum;
}
#endif
// load moments into LDS

// the data in 4 blocks.
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
const int2 ldsSize = int2( LDS_SIZE, LDS_SIZE );
const int2 threadsCnt = int2( THREADS, THREADS );
const int4 validSrc = int4( srcRect.xy, srcRect.xy + srcRect.zw - 1 );
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + srcRect.xy;
const int2 validSrc = (int2) (srcRect.xy + srcRect.zw - 1);
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + (int2) srcRect.xy;
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
moment_t hblurredMoments[2];
// calculate an average moment over all samples for a given pixel and load the result into LDS
uint iw, ih, is;
for( ih = 0; ih < 2; ih++ )
for( int ih = 0; ih < 2; ih++ )
[branch]
if (ldsIdx.y >= ldsSize.y)
continue;
for( iw = 0; iw < 2; iw++ )
for( int iw = 0; iw < 2; iw++ )
[branch]
if (ldsIdx.x >= ldsSize.x)
continue;
moment_t avgMoments = 0.0;
#if MAX_MSAA > 1
for( is = 0; is < sampleCnt; is++ )
if( ldsIdx.x < LDS_STRIDE )
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
moment_t moments = DepthToMoments( depth );
avgMoments += sampleWeights[is] * moments;
}
avgMoments *= sumWeights;
#if MAX_MSAA > 1
moment_t avgMoments = 0.0;
[loop]
for( uint is = 0; is < sampleCnt; is++ )
{
float depth = depthTex.Load( min( srcIdx, validSrc ), is ).x;
depth = reverse_z ? (1.0 - depth) : depth;
# if SHADOW_MOMENT_ALGORITHM == MSM
// We're pancaking triangles to znear in the depth pass so depth and subsequently all moments can end up being zero.
// The solver ShadowMoments_SolveMSM then ends up calculating infinities and nands, which produces different results
// on different vendors' GPUs. So we're adding a small safety margin here.
depth = Clamp( depth, 0.001, 0.999 );
# endif
avgMoments += sampleWeights[is] * DepthToMoments( depth );
}
avgMoments *= sumWeights;
writeToShared( avgMoments, int2( ldsIdx.x, groupThreadId.y ), LDS_STRIDE );
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x;
avgMoments = DepthToMoments( reverse_z ? (1.0-depth) : depth );
float depth = depthTex.Load( int3( min( srcIdx, validSrc ), 0 ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
# if SHADOW_MOMENT_ALGORITHM == MSM
// We're pancaking triangles to znear in the depth pass so depth and subsequently all moments can end up being zero.
// The solver ShadowMoments_SolveMSM then ends up calculating infinities and nands, which produces different results
// on different vendors' GPUs. So we're adding a small safety margin here.
depth = Clamp( depth, 0.001, 0.999 );
# endif
writeToShared( DepthToMoments( depth ), int2( ldsIdx.x, groupThreadId.y ), LDS_STRIDE );
moments[ldsIdx.y][ldsIdx.x] = avgMoments;
ldsIdx.x += THREADS;
srcIdx.x += THREADS;
}
}
ldsIdx.x += threadsCnt.x;
srcIdx.x += threadsCnt.x;
GroupMemoryBarrierWithGroupSync();
hblurredMoments[ih] = 0;
int2 idx = { groupThreadId.x + blurBorder, groupThreadId.y };
[loop]
for( int blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoments[ih] += readFromShared( int2( idx.x + blurOffset, idx.y ), LDS_STRIDE ) * blurWeights[abs( blurOffset )];
GroupMemoryBarrierWithGroupSync();
ldsIdx.y += threadsCnt.y;
srcIdx.y += threadsCnt.y;
srcIdx.y += THREADS;
// sync across all threads so LDS contains the moments for each pixel that we need for the blur
GroupMemoryBarrierWithGroupSync();
// update LDS with horizontally blurred values
writeToShared( hblurredMoments[0], groupThreadId.xy, THREADS );
if( (groupThreadId.y + THREADS) < LDS_STRIDE )
writeToShared( hblurredMoments[1], int2( groupThreadId.x, groupThreadId.y + THREADS ), THREADS );
// first pass blurs horizontally
ldsIdx = groupThreadId.xy + int2( blurBorder, 0 );
moment_t hblurredMoment = 0.0, hblurredMoment2 = 0.0;
int blurOffset;
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoment += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs( blurOffset )];
}
ldsIdx.y += threadsCnt.y;
[branch]
if( ldsIdx.y < ldsSize.y )
{
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoment2 += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs(blurOffset)];
}
}
// make sure all reads/writes are done
// sync threads
// replace LDS values with the horizontally blurred values
moments[groupThreadId.y][ldsIdx.x] = hblurredMoment;
[branch]
if( ldsIdx.y < ldsSize.y )
moments[ldsIdx.y][ldsIdx.x] = hblurredMoment2;
GroupMemoryBarrierWithGroupSync();
ldsIdx = groupThreadId.xy + blurBorder.xx;
ldsIdx = (int2) groupThreadId.xy + int2( 0, blurBorder );
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
[unroll]
for( int blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
vblurredMoment += moments[ldsIdx.y + blurOffset][ldsIdx.x] * blurWeights[abs( blurOffset )];
vblurredMoment += readFromShared( int2( ldsIdx.x, ldsIdx.y + blurOffset ), THREADS ) * blurWeights[abs(blurOffset)];
dispatchId.z = dstRect.z;
dispatchId.z = dstRect.z;
outputTex[dispatchId] = vblurredMoment;
}
}

2
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl


return mul( moments, mat );
}
// Note: Don't call this with all moments being equal or 0.0, otherwise this code degenerates into lots of +/-inf calculations
// which don't behave quite the same on all hardware.
void ShadowMoments_SolveMSM( float4 moments, float depth, float momentBias, out float3 z, out float4 b )
{
// Bias input data to avoid artifacts

25
ScriptableRenderPipeline/Core/Shadow/Shadow.cs


protected const int k_BlurKernelDefSize = (7 - k_BlurKernelMinSize) / 2;
protected const int k_BlurKernelMaxSize = 17;
protected const int k_BlurKernelCount = k_BlurKernelMaxSize / 2;
protected const int k_MaxSampleCount = 8;
protected ComputeShader m_MomentBlurCS;
protected int[] m_KernelVSM = new int[k_BlurKernelCount];
protected int[] m_KernelEVSM_2 = new int[k_BlurKernelCount];

return use_2_Channels ? RenderTextureFormat.RGFloat : RenderTextureFormat.ARGBFloat;
}
}
public ShadowVariance( ref AtlasInit init ) : base( ref init )
public ShadowVariance( ref AtlasInit init, int sampleCount ) : base( ref init )
m_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now
m_SampleCount = sampleCount <= 0 ? 1 : (sampleCount > k_MaxSampleCount ? k_MaxSampleCount : sampleCount);
m_MomentBlurCS = Resources.Load<ComputeShader>( "ShadowBlurMoments" );
if( m_MomentBlurCS )

m_KernelVSM[i] = m_MomentBlurCS.FindKernel( "main_VSM_" + blurSize );
m_KernelEVSM_2[i] = m_MomentBlurCS.FindKernel( "main_EVSM_2_" + blurSize );
m_KernelEVSM_4[i] = m_MomentBlurCS.FindKernel( "main_EVSM_4_" + blurSize );
m_KernelMSM[i] = m_MomentBlurCS.FindKernel( "main_MSM_" + blurSize );
m_KernelVSM[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "VSM_" + blurSize );
m_KernelEVSM_2[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "EVSM_2_" + blurSize );
m_KernelEVSM_4[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "EVSM_4_" + blurSize );
m_KernelMSM[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "MSM_" + blurSize );
m_BlurWeights[i] = new float[2+i];
FillBlurWeights( i );

m_BlurWeights[i][j] *= weightSum;
}
}
public ShadowVariance( ref AtlasInit init ) : this( ref init, 1 ) {}
override protected void CreateShadowmap( RenderTexture shadowmap )
{

override protected void PreUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice )
{
cb.SetRenderTarget( m_ShadowmapId, 0, (CubemapFace) 0, (int) rendertargetSlice );
cb.GetTemporaryRT( m_TempDepthId, (int) m_Width, (int) m_Height, (int) m_ShadowmapBits, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Default, m_SampleCount );
RenderTextureDescriptor desc = new RenderTextureDescriptor( (int) m_Width, (int) m_Height, RenderTextureFormat.Shadowmap, (int) m_ShadowmapBits );
desc.autoGenerateMips = false;
desc.enableRandomWrite = false;
desc.msaaSamples = m_SampleCount;
desc.shadowSamplingMode = ShadowSamplingMode.RawDepth;
desc.useMipMap = false;
desc.bindMS = true;
cb.GetTemporaryRT( m_TempDepthId, desc );
cb.SetRenderTarget( new RenderTargetIdentifier( m_TempDepthId ) );
cb.ClearRenderTarget( true, true, m_ClearColor );
}

4
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl


//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
// directional
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5 // all cascades
#define SHADOW_DISPATCH_DIR_ALG_0 GPUSHADOWALGORITHM_PCF_TENT_7X7 // 1st cascade
#define SHADOW_DISPATCH_DIR_ALG_1 GPUSHADOWALGORITHM_PCF_TENT_5X5 // 2nd cascade

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


bool useGlobalOverrides = true;
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V3, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetShadowLightTypeDelegate(HDShadowLightType);

正在加载...
取消
保存