浏览代码

Added support for choosing a precision for shadow variants. There are two settings, Low and High, which currently select between 16 bits per channel and 32 bits per channel shadow maps.

Merged directional and point/spot lights into the same atlas again. Added two additional atlases to support 16 bpp VSM style shadow maps.
Added new dropdown to AdditionalLightData to select precision if available.
/main
uygar 7 年前
当前提交
699822c3
共有 11 个文件被更改,包括 360 次插入165 次删除
  1. 6
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  2. 23
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  3. 14
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Resources/ShadowBlurMoments.compute
  4. 224
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs
  5. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl
  6. 100
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs
  7. 35
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl
  8. 20
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowMoments.hlsl
  9. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl
  10. 20
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs
  11. 67
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs

6
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


[HideInInspector, SerializeField] private int shadowAlgorithm;
[HideInInspector, SerializeField] private int shadowVariant;
[HideInInspector, SerializeField] private int shadowPrecision;
public void GetShadowAlgorithm( out int algorithm, out int variant ) { algorithm = shadowAlgorithm; variant = shadowVariant; }
public void SetShadowAlgorithm( int algorithm, int variant, int format, int[] data )
public void GetShadowAlgorithm( out int algorithm, out int variant, out int precision ) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm( int algorithm, int variant, int precision, int format, int[] data )
shadowPrecision = precision;
shadowData.format = format;
shadowData.data = data;

23
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


atlasInit.baseInit.comparisonSamplerState = ComparisonSamplerState.Default();
atlasInit.baseInit.clearColor = new Vector4( 0.0f, 0.0f, 0.0f, 0.0f );
atlasInit.baseInit.maxPayloadCount = 0;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional | ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
var atlasInit2 = atlasInit;
atlasInit2.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
varianceInit.baseInit.shadowmapFormat = RenderTextureFormat.ARGBFloat;
varianceInit.baseInit.shadowmapFormat = ShadowVariance.GetFormat( false, false, true );
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowVariance( ref varianceInit ), new ShadowExp.ShadowAtlas( ref atlasInit ), new ShadowExp.ShadowAtlas( ref atlasInit2 ) };
//m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowAtlas( ref atlasInit ), new ShadowExp.ShadowAtlas( ref atlasInit2 ) };
var varianceInit2 = varianceInit;
varianceInit2.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, true, false );
var varianceInit3 = varianceInit;
varianceInit3.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, false, true );
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowVariance( ref varianceInit ), new ShadowExp.ShadowVariance( ref varianceInit2 ), new ShadowExp.ShadowVariance( ref varianceInit3 ), new ShadowExp.ShadowAtlas( ref atlasInit ) };
ShadowContext.SyncDel syncer = (ShadowContext sc) =>
{

uint offset, count;
RenderTargetIdentifier[] tex;
sc.GetTex2DArrays( out tex, out offset, out count );
cb.SetGlobalTexture( "_ShadowmapExp_Dir_VSM", tex[0] );
cb.SetGlobalTexture( "_ShadowmapExp_Dir", tex[1] );
cb.SetGlobalTexture( "_ShadowmapExp_PointSpot", tex[2] );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_0", tex[0] );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_1", tex[1] );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_2", tex[2] );
cb.SetGlobalTexture( "_ShadowmapExp_PCF" , tex[3] );
// TODO: Currently samplers are hard coded in ShadowContext.hlsl, so we can't really set them here
};

14
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Resources/ShadowBlurMoments.compute


#endif
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = unused
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp
static const int kBits_16 = 1; // 16 bits per channel
static const int kChannels_2 = 2; // 2 channels per pixel
#if (SHADOW_MOMENT_ALGORITHM == VSM)
# define SHADOW_MOMENTS 2

# define SHADOW_MOMENTS 4
float4 DepthToMoments( float depth )
{
float dsq = depth * depth;
return float4( depth, dsq, depth * dsq, dsq * dsq );
[branch]
if( (dstRect.w & kBits_16) != 0 )
return ShadowMoments_Encode16MSM( depth );
else
{
float dsq = depth * depth;
return float4( depth, dsq, depth * dsq, dsq * dsq );
}
}
#else
# error "No valid shadow moment algorithm has been set to the define SHADOW_MOMENT_ALGORITHM."

224
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs


override protected void Register( GPUShadowType type, ShadowRegistry registry )
{
ShadowPrecision precision = m_ShadowmapBits == 32 ? ShadowPrecision.High : ShadowPrecision.Low;
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.PCF_1tap );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.PCF_9tap );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.PCF, ShadowVariant.V0, precision ) );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.PCF, ShadowVariant.V1, precision ) );
ShadowRegistry.VariantDelegate del = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate del = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
CheckDataIntegrity( dataAlgorithm, dataVariant, ref dataBlock );
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );
registry.Register( type, ShadowAlgorithm.PCF, "Percentage Closer Filtering (PCF)",
registry.Register( type, precision, ShadowAlgorithm.PCF, "Percentage Closer Filtering (PCF)",
virtual protected bool CheckDataIntegrity( ShadowAlgorithm algorithm, ShadowVariant variant, ref int[] dataBlock )
virtual protected bool CheckDataIntegrity( ShadowAlgorithm algorithm, ShadowVariant variant, ShadowPrecision precision, ref int[] dataBlock )
{
if( algorithm != ShadowAlgorithm.PCF || (variant != ShadowVariant.V0 && variant != ShadowVariant.V1) )
return true;

float nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;
GPUShadowAlgorithm sanitizedAlgo = ShadowUtils.ClearPrecision( sr.shadowAlgorithm );
if( multiFace )
{
// For lights with multiple faces, the first shadow data contains

sd.PackShadowType( sr.shadowType, sr.shadowAlgorithm );
sd.PackShadowType( sr.shadowType, sanitizedAlgo );
sd.payloadOffset = payload.Count();
entries.AddUnchecked( sd );
key.shadowDataIdx++;

sd.scaleOffset = new Vector4( ce.current.viewport.width * m_WidthRcp, ce.current.viewport.height * m_HeightRcp, ce.current.viewport.x, ce.current.viewport.y );
sd.texelSizeRcp = new Vector2( m_WidthRcp, m_HeightRcp );
sd.PackShadowmapId( m_TexSlot, m_SampSlot, ce.current.slice );
sd.PackShadowType( sr.shadowType, sr.shadowAlgorithm );
sd.PackShadowType( sr.shadowType, sanitizedAlgo );
sd.payloadOffset = originalPayloadCount;
entries.AddUnchecked( sd );

payload[payloadOffset] = sp;
}
}
ShadowAlgorithm algo; ShadowVariant vari;
ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari );
if( algo == ShadowAlgorithm.PCF )
ShadowAlgorithm algo; ShadowVariant vari; ShadowPrecision prec;
ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari, out prec );
if( algo == ShadowAlgorithm.PCF )
{
AdditionalLightData ald = light.light.GetComponent<AdditionalLightData>();
if( !ald )

int[] shadowData = ald.GetShadowData( out shadowDataFormat );
if( !CheckDataIntegrity( algo, vari, ref shadowData ) )
if( !CheckDataIntegrity( algo, vari, prec, ref shadowData ) )
ald.SetShadowAlgorithm( (int)algo, (int)vari, shadowDataFormat, shadowData );
ald.SetShadowAlgorithm( (int)algo, (int)vari, (int) prec, shadowDataFormat, shadowData );
switch( sr.shadowAlgorithm )
switch( vari )
case GPUShadowAlgorithm.PCF_1tap:
case GPUShadowAlgorithm.PCF_9tap:
case ShadowVariant.V0:
case ShadowVariant.V1:
{
sp.Set( shadowData[0] | (SystemInfo.usesReversedZBuffer ? 1 : 0), shadowData[1], 0, 0 );
payload[payloadOffset] = sp;

protected float[][] m_BlurWeights = new float[k_BlurKernelCount][];
protected int m_SampleCount;
[Flags]
protected enum Flags
{
bpp_16 = 1 << 0,
channels_2 = 1 << 1,
}
protected readonly Flags m_Flags;
readonly ValRange m_DefEVSM_PosExponent = new ValRange( "Positive Exponent" , 1.0f, 1.0f , 42.0f , 1.0f );
readonly ValRange m_DefEVSM_NegExponent = new ValRange( "Negative Exponent" , 1.0f, 1.0f , 42.0f , 1.0f );
readonly ValRange m_DefEVSM_PosExponent_32 = new ValRange( "Positive Exponent" , 1.0f, 1.0f , 42.0f , 1.0f );
readonly ValRange m_DefEVSM_NegExponent_32 = new ValRange( "Negative Exponent" , 1.0f, 1.0f , 42.0f , 1.0f );
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_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.3f , 1.0f , 0.00003f);
readonly ValRange m_DefMSM_MomentBias = new ValRange( "Moment Bias" , 0.0f, 0.3f , 1.0f , 0.0001f);
public static RenderTextureFormat GetFormat( bool use_16_BitsPerChannel, bool use_2_Channels, bool use_MSM )
{
Debug.Assert( !use_2_Channels || !use_MSM ); // MSM always requires 4 channels
if( use_16_BitsPerChannel )
{
return use_2_Channels ? RenderTextureFormat.RGHalf : (use_MSM ? RenderTextureFormat.ARGB64 : RenderTextureFormat.ARGBHalf);
}
else
{
return use_2_Channels ? RenderTextureFormat.RGFloat : RenderTextureFormat.ARGBFloat;
}
}
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_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now
m_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now
m_MomentBlurCS = Resources.Load<ComputeShader>( "ShadowBlurMoments" );
if( m_MomentBlurCS )

override protected void Register( GPUShadowType type, ShadowRegistry registry )
{
m_SupportedAlgorithms.Reserve( 5 );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.VSM );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.EVSM_2 );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.EVSM_4 );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.MSM_Ham );
m_SupportedAlgorithms.AddUnchecked( GPUShadowAlgorithm.MSM_Haus );
bool supports_VSM = m_ShadowmapFormat != RenderTextureFormat.ARGB64;
bool supports_EVSM_2 = m_ShadowmapFormat != RenderTextureFormat.ARGB64;
bool supports_EVSM_4 = m_ShadowmapFormat != RenderTextureFormat.ARGB64 && (m_Flags & Flags.channels_2) == 0;
bool supports_MSM = (m_Flags & Flags.channels_2) == 0 && ((m_Flags & Flags.bpp_16) == 0 || m_ShadowmapFormat == RenderTextureFormat.ARGB64);
ShadowRegistry.VariantDelegate vsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate vsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
CheckDataIntegrity( dataAlgorithm, dataVariant, ref dataBlock );
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );
m_DefVSM_LightLeakBias.Slider( ref dataBlock[0] );
m_DefVSM_VarianceBias.Slider( ref dataBlock[1] );

ShadowRegistry.VariantDelegate evsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate evsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
CheckDataIntegrity( dataAlgorithm, dataVariant, ref dataBlock );
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );
m_DefEVSM_PosExponent.Slider( ref dataBlock[2] );
if( (m_Flags & Flags.bpp_16) != 0 )
m_DefEVSM_PosExponent_16.Slider( ref dataBlock[2] );
else
m_DefEVSM_PosExponent_32.Slider( ref dataBlock[2] );
m_DefEVSM_NegExponent.Slider( ref dataBlock[3] );
if( (m_Flags & Flags.bpp_16) != 0 )
m_DefEVSM_NegExponent_16.Slider( ref dataBlock[3] );
else
m_DefEVSM_NegExponent_32.Slider( ref dataBlock[3] );
ShadowRegistry.VariantDelegate msmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate msmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
CheckDataIntegrity( dataAlgorithm, dataVariant, ref dataBlock );
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );
m_DefMSM_LightLeakBias.Slider( ref dataBlock[0] );
m_DefMSM_MomentBias.Slider( ref dataBlock[1] );

registry.Register( type, ShadowAlgorithm.VSM, "Variance shadow map (VSM)",
new ShadowVariant[] { ShadowVariant.V0 }, new string[] { "2 moments" }, new ShadowRegistry.VariantDelegate[] { vsmDel } );
registry.Register( type, ShadowAlgorithm.EVSM, "Exponential variance shadow map (EVSM)",
new ShadowVariant[] { ShadowVariant.V0, ShadowVariant.V1 }, new string[] { "2 moments", "4 moments" }, new ShadowRegistry.VariantDelegate[] { evsmDel, evsmDel } );
registry.Register( type, ShadowAlgorithm.MSM, "Momentum shadow map (MSM)",
new ShadowVariant[] { ShadowVariant.V0, ShadowVariant.V1 }, new string[] { "Hamburg", "Hausdorff" }, new ShadowRegistry.VariantDelegate[] { msmDel, msmDel } );
ShadowPrecision precision = (m_Flags & Flags.bpp_16) == 0 ? ShadowPrecision.High : ShadowPrecision.Low;
m_SupportedAlgorithms.Reserve( 5 );
if( supports_VSM )
{
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.VSM, ShadowVariant.V0, precision ) );
registry.Register( type, precision, ShadowAlgorithm.VSM, "Variance shadow map (VSM)",
new ShadowVariant[] { ShadowVariant.V0 }, new string[] { "2 moments" }, new ShadowRegistry.VariantDelegate[] { vsmDel } );
}
if( supports_EVSM_2 && !supports_EVSM_4 )
{
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.EVSM, ShadowVariant.V0, precision ) );
registry.Register( type, precision, ShadowAlgorithm.EVSM, "Exponential variance shadow map (EVSM)",
new ShadowVariant[] { ShadowVariant.V0 }, new string[] { "2 moments" }, new ShadowRegistry.VariantDelegate[] { evsmDel } );
}
if( supports_EVSM_4 )
{
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.EVSM, ShadowVariant.V0, precision ) );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.EVSM, ShadowVariant.V1, precision ) );
registry.Register( type, precision, ShadowAlgorithm.EVSM, "Exponential variance shadow map (EVSM)",
new ShadowVariant[] { ShadowVariant.V0, ShadowVariant.V1 }, new string[] { "2 moments", "4 moments" }, new ShadowRegistry.VariantDelegate[] { evsmDel, evsmDel } );
}
if( supports_MSM )
{
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.MSM, ShadowVariant.V0, precision ) );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.MSM, ShadowVariant.V1, precision ) );
registry.Register( type, precision, ShadowAlgorithm.MSM, "Moment shadow map (MSM)",
new ShadowVariant[] { ShadowVariant.V0, ShadowVariant.V1 }, new string[] { "Hamburg", "Hausdorff" }, new ShadowRegistry.VariantDelegate[] { msmDel, msmDel } );
}
override protected bool CheckDataIntegrity( ShadowAlgorithm algorithm, ShadowVariant variant, ref int[] dataBlock )
override protected bool CheckDataIntegrity( ShadowAlgorithm algorithm, ShadowVariant variant, ShadowPrecision precision, ref int[] dataBlock )
{
switch( algorithm )
{

dataBlock = new int[k_BlockSize];
dataBlock[0] = m_DefEVSM_LightLeakBias.Default();
dataBlock[1] = m_DefEVSM_VarianceBias.Default();
dataBlock[2] = m_DefEVSM_PosExponent.Default();
dataBlock[3] = m_DefEVSM_NegExponent.Default();
dataBlock[2] = (m_Flags & Flags.bpp_16) != 0 ? m_DefEVSM_PosExponent_16.Default() : m_DefEVSM_PosExponent_32.Default();
dataBlock[3] = (m_Flags & Flags.bpp_16) != 0 ? m_DefEVSM_NegExponent_16.Default() : m_DefEVSM_NegExponent_32.Default();
dataBlock[4] = k_BlurKernelDefSize;
return false;
}

}
return true;
}
default: return base.CheckDataIntegrity( algorithm, variant, ref dataBlock );
default: return base.CheckDataIntegrity( algorithm, variant, precision, ref dataBlock );
}
}

uint cnt = base.ReservePayload( sr );
switch( sr.shadowAlgorithm )
switch( ShadowUtils.ExtractAlgorithm( sr.shadowAlgorithm ) )
case GPUShadowAlgorithm.VSM : return cnt + 1;
case GPUShadowAlgorithm.EVSM_2 :
case GPUShadowAlgorithm.EVSM_4 : return cnt + 1;
case GPUShadowAlgorithm.MSM_Ham :
case GPUShadowAlgorithm.MSM_Haus: return cnt + 1;
case ShadowAlgorithm.VSM : return cnt + 1;
case ShadowAlgorithm.EVSM: return cnt + 1;
case ShadowAlgorithm.MSM : return cnt + 1;
default: return cnt;
}
}

ShadowAlgorithm algo;
ShadowVariant vari;
ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari );
CheckDataIntegrity( algo, vari, ref shadowData );
ShadowPrecision prec;
ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari, out prec );
CheckDataIntegrity( algo, vari, prec, ref shadowData );
switch (sr.shadowAlgorithm)
switch( ShadowUtils.ExtractAlgorithm( sr.shadowAlgorithm ) )
case GPUShadowAlgorithm.VSM:
case ShadowAlgorithm.VSM:
{
sp.p0 = shadowData[0];
sp.p1 = shadowData[1];

break;
case GPUShadowAlgorithm.EVSM_2:
case GPUShadowAlgorithm.EVSM_4:
case ShadowAlgorithm.EVSM:
{
sp.p0 = shadowData[0];
sp.p1 = shadowData[1];

payloadOffset++;
}
break;
case GPUShadowAlgorithm.MSM_Ham:
case GPUShadowAlgorithm.MSM_Haus:
case ShadowAlgorithm.MSM:
sp.Set( shadowData[0], shadowData[1], shadowData[2] | (SystemInfo.usesReversedZBuffer ? 1 : 0), 0 );
sp.Set( shadowData[0], shadowData[1], shadowData[2] | (SystemInfo.usesReversedZBuffer ? 1 : 0), (m_Flags & Flags.bpp_16) != 0 ? 0x3f800000 : 0 );
payload[payloadOffset] = sp;
payloadOffset++;
}

int shadowDataFormat;
int[] shadowData = ald.GetShadowData( out shadowDataFormat );
switch( m_EntryCache[i].current.shadowAlgo )
ShadowAlgorithm algo;
ShadowVariant vari;
ShadowPrecision prec;
ShadowUtils.Unpack( m_EntryCache[i].current.shadowAlgo, out algo, out vari, out prec );
switch( algo )
case GPUShadowAlgorithm.VSM:
case ShadowAlgorithm.VSM:
case GPUShadowAlgorithm.EVSM_2:
case ShadowAlgorithm.EVSM:
Debug.Assert( (GPUShadowAlgorithm) shadowDataFormat == GPUShadowAlgorithm.EVSM_2 );
float evsmExponent1 = ShadowUtils.Asfloat( shadowData[2] );
cb.SetComputeFloatParam( m_MomentBlurCS, "evsmExponent", evsmExponent1 );
kernelIdx = shadowData[4];
currentKernel = m_KernelEVSM_2[kernelIdx];
if( vari == ShadowVariant.V0 )
{
float evsmExponent1 = ShadowUtils.Asfloat( shadowData[2] );
cb.SetComputeFloatParam( m_MomentBlurCS, "evsmExponent", evsmExponent1 );
kernelIdx = shadowData[4];
currentKernel = m_KernelEVSM_2[kernelIdx];
}
else
{
float evsmExponent1 = ShadowUtils.Asfloat( shadowData[2] );
float evsmExponent2 = ShadowUtils.Asfloat( shadowData[3] );
cb.SetComputeFloatParams( m_MomentBlurCS, "evsmExponents", new float[] { evsmExponent1, evsmExponent2 } );
kernelIdx = shadowData[4];
currentKernel = m_KernelEVSM_4[kernelIdx];
}
case GPUShadowAlgorithm.EVSM_4:
{
Debug.Assert( (GPUShadowAlgorithm) shadowDataFormat == GPUShadowAlgorithm.EVSM_4 );
float evsmExponent1 = ShadowUtils.Asfloat( shadowData[2] );
float evsmExponent2 = ShadowUtils.Asfloat( shadowData[3] );
cb.SetComputeFloatParams( m_MomentBlurCS, "evsmExponents", new float[] { evsmExponent1, evsmExponent2 } );
kernelIdx = shadowData[4];
currentKernel = m_KernelEVSM_4[kernelIdx];
}
break;
case GPUShadowAlgorithm.MSM_Ham :
case GPUShadowAlgorithm.MSM_Haus:
case ShadowAlgorithm.MSM :
default: Debug.LogError( "Unknown shadow algorithm selected for momentum type shadow maps." ); break;
default: Debug.LogError( "Unknown shadow algorithm selected for moment type shadow maps." ); break;
cb.SetComputeIntParams( m_MomentBlurCS, "dstRect", new int[] { (int) r.x, (int) r.y, (int) rendertargetSlice } );
cb.SetComputeIntParams( m_MomentBlurCS, "dstRect", new int[] { (int) r.x, (int) r.y, (int) rendertargetSlice, (int) m_Flags } );
cb.SetComputeFloatParams( m_MomentBlurCS, "blurWeightsStorage", m_BlurWeights[kernelIdx] );
cb.DispatchCompute( m_MomentBlurCS, currentKernel, ((int) r.width) / k_MomentBlurThreadsPerWorkgroup, (int) r.height / k_MomentBlurThreadsPerWorkgroup, 1 );
i++;

sreq.facemask = (uint) (1 << facecount) - 1;
sreq.shadowType = shadowType;
int sa, sv;
vl.light.GetComponent<AdditionalLightData>().GetShadowAlgorithm( out sa, out sv );
sreq.shadowAlgorithm = ShadowUtils.Pack( (ShadowAlgorithm) sa, (ShadowVariant) sv );
int sa, sv, sp;
vl.light.GetComponent<AdditionalLightData>().GetShadowAlgorithm( out sa, out sv, out sp );
sreq.shadowAlgorithm = ShadowUtils.Pack( (ShadowAlgorithm) sa, (ShadowVariant) sv, (ShadowPrecision) sp );
totalRequestCount += (uint) facecount;
requestsGranted.AddUnchecked( sreq );
totalSlots--;

int smidx = 0;
while( smidx < k_MaxShadowmapPerType )
{
if( m_ShadowmapsPerType[(int)shadowtype,smidx].Reserve( frameId, ref sd, grantedRequests[i], (uint) ald.shadowResolution, (uint) ald.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights ) )
if( m_ShadowmapsPerType[(int)shadowtype,smidx] != null && m_ShadowmapsPerType[(int)shadowtype,smidx].Reserve( frameId, ref sd, grantedRequests[i], (uint) ald.shadowResolution, (uint) ald.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights ) )
break;
smidx++;
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl


// This file is empty on purpose. Projects can put their custom shadow algorithms in here so they get automatically included by Shadow.hlsl.
float EvalShadow_CascadedMomentum( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
float EvalShadow_CascadedMoment( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];

}
}
float EvalShadow_CascadedMomentum( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float EvalShadow_CascadedMoment( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return EvalShadow_CascadedMomentum( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_CascadedMoment( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

100
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs


V7
}
public enum ShadowPrecision // 1 bits
{
Low,
High
}
[GenerateHLSL]
public enum GPUShadowAlgorithm // 9 bits
{

{
public const int k_ShadowAlgorithm = 64;
public const int k_ShadowVariant = 8;
public const int k_ShadowPrecision = 2;
public const int k_GPUShadowType = 3;
}
public struct Bits

public const int k_GPUShadowAlgorithm = k_ShadowAlgorithm + k_ShadowVariant;
public const int k_ShadowPrecision = 1;
public const int k_GPUShadowAlgorithm = k_ShadowAlgorithm + k_ShadowVariant + k_ShadowPrecision;
public const int k_GPUShadowType = 4;
}

public const int k_ShadowVariant = (1 << Bits.k_ShadowVariant ) - 1;
public const int k_ShadowPrecision = (1 << Bits.k_ShadowPrecision ) - 1;
public const int k_GPUShadowAlgorithm = (1 << Bits.k_GPUShadowAlgorithm ) - 1;
public const int k_GPUShadowType = (1 << Bits.k_GPUShadowType ) - 1;
}

public class ShadowRegistry
{
public delegate void VariantDelegate( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ref int[] dataContainer );
public delegate void VariantDelegate( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataContainer );
struct Dels
{
public VariantDelegate low;
public VariantDelegate high;
}
public string algorithmDesc;
public int variantsAvailable;
public string[] variantDescs;
public VariantDelegate[] variantDels;
public string algorithmDesc;
public int variantsAvailable;
public string[] variantDescs;
public Dels[] variantDels;
Dictionary<ShadowAlgorithm, Entry>[] m_Entries = new Dictionary<ShadowAlgorithm, Entry>[ShadowConstants.Counts.k_GPUShadowType]
{ new Dictionary<ShadowAlgorithm, Entry>(),
new Dictionary<ShadowAlgorithm, Entry>(),

d.Clear();
}
public void Register( GPUShadowType type, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
public void Register( GPUShadowType type, ShadowPrecision precision, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
Register( m_Entries[(int)type], algorithm, algorithmDescriptor, variants, variantDescriptors, variantDelegates );
Register( m_Entries[(int)type], precision, algorithm, algorithmDescriptor, variants, variantDescriptors, variantDelegates );
}
private bool Validate( string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )

}
return true;
}
private void Register( Dictionary<ShadowAlgorithm, Entry> dict, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
private void Register( Dictionary<ShadowAlgorithm, Entry> dict, ShadowPrecision precision, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
{
if( !dict.ContainsKey( algorithm ) )
{

e.variantDescs = new string[ShadowConstants.Counts.k_ShadowVariant];
e.variantDels = new VariantDelegate[ShadowConstants.Counts.k_ShadowVariant];
e.variantDels = new Dels[ShadowConstants.Counts.k_ShadowVariant];
e.variantDescs[(uint) variants[i]] = variantDescriptors[i];
e.variantDels[(uint) variants[i]] = variantDelegates[i];
e.variantDescs[(uint) variants[i]] = variantDescriptors[i];
if( precision == ShadowPrecision.Low )
e.variantDels[(uint) variants[i]].low = variantDelegates[i];
else
e.variantDels[(uint) variants[i]].high = variantDelegates[i];
}
dict.Add( algorithm, e );
}

if( string.IsNullOrEmpty( entry.variantDescs[(uint) variants[i]] ) )
{
entry.variantsAvailable++;
entry.variantDescs[(uint) variants[i]] = variantDescriptors[i];
entry.variantDels[(uint) variants[i]] = variantDelegates[i];
entry.variantDescs[(uint) variants[i]] = variantDescriptors[i];
entry.variantDels[(uint) variants[i]].low = precision == ShadowPrecision.Low ? variantDelegates[i] : null;
entry.variantDels[(uint) variants[i]].high = precision == ShadowPrecision.High ? variantDelegates[i] : null;
}
else if( precision == ShadowPrecision.Low && entry.variantDels[(uint)variants[i]].low == null )
{
entry.variantDels[(uint)variants[i]].low = variantDelegates[i];
}
else if( precision == ShadowPrecision.High && entry.variantDels[(uint)variants[i]].high == null )
{
entry.variantDels[(uint)variants[i]].high = variantDelegates[i];
Debug.Log( "Tried to register variant " + variants[i] + " for algorithm " + algorithm + ", but this variant is already registered. Skipping registration." );
Debug.Log( "Tried to register variant " + variants[i] + " for algorithm " + algorithm + " with precision " + precision + ", but this variant is already registered. Skipping registration." );
}
}
}

int shadowAlgorithm;
int shadowVariant;
ald.GetShadowAlgorithm( out shadowAlgorithm, out shadowVariant );
int shadowPrecision;
ald.GetShadowAlgorithm( out shadowAlgorithm, out shadowVariant, out shadowPrecision );
DrawWidgets( l, shadowType, (ShadowAlgorithm) shadowAlgorithm, (ShadowVariant) shadowVariant );
DrawWidgets( l, shadowType, (ShadowAlgorithm) shadowAlgorithm, (ShadowVariant) shadowVariant, (ShadowPrecision) shadowPrecision );
void DrawWidgets( Light l, GPUShadowType shadowType, ShadowAlgorithm shadowAlgorithm, ShadowVariant shadowVariant )
void DrawWidgets( Light l, GPUShadowType shadowType, ShadowAlgorithm shadowAlgorithm, ShadowVariant shadowVariant, ShadowPrecision shadowPrecision )
{
var dict = m_Entries[(int)shadowType];
int[] algoOptions = new int[dict.Count];

idx = 0;
for( int writeIdx = 0; writeIdx < varsAvailable; idx++ )
{
if( e.variantDels[idx] != null )
if( e.variantDels[idx].low != null || e.variantDels[idx].high != null )
{
varOptions[writeIdx] = idx;
varDescs[writeIdx] = new GUIContent( e.variantDescs[idx] );

UnityEditor.EditorGUILayout.BeginHorizontal();
shadowVariant = (ShadowVariant) UnityEditor.EditorGUILayout.IntPopup( new GUIContent( "Variant" ), (int) shadowVariant, varDescs, varOptions );
shadowVariant = (ShadowVariant) UnityEditor.EditorGUILayout.IntPopup( new GUIContent( "Variant + Precision" ), (int) shadowVariant, varDescs, varOptions );
if( e.variantDels[(int)shadowVariant].low != null && e.variantDels[(int)shadowVariant].high != null )
{
GUIContent[] precDescs = new GUIContent[] { new GUIContent( "Low" ), new GUIContent( "High" ) };
int[] precOptions = new int[] { 0, 1 };
shadowPrecision = (ShadowPrecision)UnityEditor.EditorGUILayout.IntPopup((int)shadowPrecision, precDescs, precOptions, GUILayout.MaxWidth(65));
}
else
{
using( new UnityEditor.EditorGUI.DisabledScope() )
{
GUIContent[] precDescs = new GUIContent[] { new GUIContent( e.variantDels[(int)shadowVariant].low == null ? "High" : "Low" ) };
int[] precOptions = new int[] { e.variantDels[(int)shadowVariant].low == null ? 1 : 0 };
UnityEditor.EditorGUILayout.IntPopup(precOptions[0], precDescs, precOptions, GUILayout.MaxWidth(65));
shadowPrecision = (ShadowPrecision) precOptions[0];
}
}
GPUShadowAlgorithm packedAlgo = ShadowUtils.Pack( shadowAlgorithm, shadowVariant );
GPUShadowAlgorithm packedAlgo = ShadowUtils.Pack( shadowAlgorithm, shadowVariant, shadowPrecision );
int[] shadowData = null;
if( !GUILayout.Button( "Reset", GUILayout.MaxWidth( 80.0f ) ) )
shadowData = ald.GetShadowData( (int) packedAlgo );

e.variantDels[(int) shadowVariant]( l, shadowAlgorithm, shadowVariant, ref shadowData );
ald.SetShadowAlgorithm( (int) shadowAlgorithm, (int) shadowVariant, (int) packedAlgo, shadowData );
if( shadowPrecision == ShadowPrecision.Low )
e.variantDels[(int) shadowVariant].low( l, shadowAlgorithm, shadowVariant, shadowPrecision, ref shadowData );
else
e.variantDels[(int) shadowVariant].high( l, shadowAlgorithm, shadowVariant, shadowPrecision, ref shadowData );
ald.SetShadowAlgorithm( (int) shadowAlgorithm, (int) shadowVariant, (int) shadowPrecision, (int) packedAlgo, shadowData );
UnityEditor.EditorGUI.indentLevel--;
}

public void PackShadowType( GPUShadowType type, GPUShadowAlgorithm algorithm )
{
shadowType = (uint)type << 9 | (uint) algorithm;
shadowType = (uint)type << ShadowConstants.Bits.k_GPUShadowAlgorithm | (uint) algorithm;
}
};

protected readonly float m_HeightRcp;
protected readonly uint m_MaxPayloadCount;
protected readonly ShadowSupport m_ShadowSupport;
protected uint m_ShadowId;
protected CullResults m_CullResults; // TODO: Temporary, due to CullResults dependency in ShadowUtils' matrix extraction code. Remove this member once that dependency is gone.
public struct BaseInit

m_HeightRcp = 1.0f / initializer.height;
m_MaxPayloadCount = initializer.maxPayloadCount;
m_ShadowSupport = initializer.shadowSupport;
m_ShadowId = 0;
if( IsNativeDepth() && m_Slices > 1 )
{

public ShadowSupport QueryShadowSupport() { return m_ShadowSupport; }
public uint GetMaxPayload() { return m_MaxPayloadCount; }
public void AssignId( uint shadowId ) { m_ShadowId = shadowId; }
public void Assign( CullResults cullResults ) { m_CullResults = cullResults; } // TODO: Remove when m_CullResults is removed again
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );

35
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl


// This can be custom for each project and needs to be in sync with the ShadowMgr
#define SHADOWCONTEXT_MAX_TEX2DARRAY 3
#define SHADOWCONTEXT_MAX_TEX2DARRAY 4
#define SHADOWCONTEXT_MAX_SAMPLER 1
#define SHADOWCONTEXT_MAX_COMPSAMPLER 2
#define SHADOWCONTEXT_MAX_SAMPLER 3
#define SHADOWCONTEXT_MAX_COMPSAMPLER 1
TEXTURE2D_ARRAY(_ShadowmapExp_Dir_VSM);
SAMPLER2D(sampler_ShadowmapExp_Dir_VSM);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_0);
SAMPLER2D(sampler_ShadowmapExp_VSM_0);
TEXTURE2D_ARRAY(_ShadowmapExp_Dir);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_Dir);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_1);
SAMPLER2D(sampler_ShadowmapExp_VSM_1);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_2);
SAMPLER2D(sampler_ShadowmapExp_VSM_2);
TEXTURE2D_ARRAY(_ShadowmapExp_PointSpot);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PointSpot);
TEXTURE2D_ARRAY(_ShadowmapExp_PCF);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PCF);
StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;

ShadowContext sc;
sc.shadowDatas = _ShadowDatasExp;
sc.payloads = _ShadowPayloads;
sc.tex2DArray[0] = _ShadowmapExp_Dir_VSM;
sc.tex2DArray[1] = _ShadowmapExp_Dir;
sc.tex2DArray[2] = _ShadowmapExp_PointSpot;
sc.samplers[0] = sampler_ShadowmapExp_Dir_VSM;
sc.compSamplers[0] = sampler_ShadowmapExp_Dir;
sc.compSamplers[1] = sampler_ShadowmapExp_PointSpot;
sc.tex2DArray[0] = _ShadowmapExp_VSM_0;
sc.tex2DArray[1] = _ShadowmapExp_VSM_1;
sc.tex2DArray[2] = _ShadowmapExp_VSM_2;
sc.tex2DArray[3] = _ShadowmapExp_PCF;
sc.samplers[0] = sampler_ShadowmapExp_VSM_0;
sc.samplers[1] = sampler_ShadowmapExp_VSM_1;
sc.samplers[2] = sampler_ShadowmapExp_VSM_2;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
return sc;
}

20
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowMoments.hlsl


{
float dsq = depth * depth;
float4 moments = { depth, dsq, depth * dsq, dsq * dsq };
float4x4 mat = { - 2.07224649f , 13.7948857237f, 0.105877704f , 9.7924062118f,
32.23703778f , -59.4683975703f, -1.9077466311f, -33.7652110555f,
-68.571074599f , 82.0359750338f, 9.3496555107f, 47.9456096605f,
39.3703274134f, -35.364903257f , -6.6543490743f, -23.9728048165f };
float4x4 mat = { - 2.07224649 , 13.7948857237, 0.105877704 , 9.7924062118,
32.23703778 , -59.4683975703, -1.9077466311, -33.7652110555,
-68.571074599 , 82.0359750338, 9.3496555107, 47.9456096605,
39.3703274134, -35.364903257 , -6.6543490743, -23.9728048165 };
optimized[0] += 0.035955884801f;
optimized[0] += 0.035955884801;
return optimized;
}

moments[0] -= 0.035955884801f;
float4x4 mat = { 0.2227744146f, 0.1549679261f, 0.1451988946f, 0.163127443f,
0.0771972861f, 0.1394629426f, 0.2120202157f, 0.2591432266f,
0.7926986636f, 0.7963415838f, 0.7258694464f, 0.6539092497f,
0.0319417555f, -0.1722823173f, -0.2758014811f, -0.3376131734f };
moments[0] -= 0.035955884801;
float4x4 mat = { 0.2227744146, 0.1549679261, 0.1451988946, 0.163127443,
0.0771972861, 0.1394629426, 0.2120202157, 0.2591432266,
0.7926986636, 0.7963415838, 0.7258694464, 0.6539092497,
0.0319417555, -0.1722823173, -0.2758014811, -0.3376131734 };
return mul( moments, mat );
}

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl


//
float SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx, bool useHamburger )
{
float3 params = asfloat( shadowContext.payloads[payloadOffset].xyz );
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float bpp16 = params.w;
if( bpp16 != 0.0 )
moments = ShadowMoments_Decode16MSM( moments );
float3 z;
float4 b;

float SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
{
float3 params = asfloat( shadowContext.payloads[payloadOffset].xyz );
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float bpp16 = params.w;
if( bpp16 != 0.0 )
moments = ShadowMoments_Decode16MSM( moments );
float3 z;
float4 b;

20
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs


case LightType.Area : gputype = GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return false; // area lights by themselves can't be mapped to any GPU type
}
}
public static GPUShadowAlgorithm Pack( ShadowAlgorithm algo, ShadowVariant vari )
public static GPUShadowAlgorithm Pack( ShadowAlgorithm algo, ShadowVariant vari, ShadowPrecision prec )
return (GPUShadowAlgorithm) (((int) algo << ShadowExp.ShadowConstants.Bits.k_ShadowVariant) | (int)vari);
int precshift = ShadowExp.ShadowConstants.Bits.k_ShadowVariant + ShadowExp.ShadowConstants.Bits.k_ShadowAlgorithm;
int algoshift = ShadowExp.ShadowConstants.Bits.k_ShadowVariant;
return (GPUShadowAlgorithm) ( (int) prec << precshift | ((int) algo << algoshift) | (int)vari);
public static ShadowAlgorithm ExtractAlgorithm( GPUShadowAlgorithm gpuAlgo ) { return (ShadowAlgorithm) (((int)gpuAlgo >> ShadowExp.ShadowConstants.Bits.k_ShadowVariant) & ShadowExp.ShadowConstants.Masks.k_ShadowAlgorithm ); }
public static ShadowVariant ExtractVariant( GPUShadowAlgorithm gpuAlgo ) { return (ShadowVariant ) ( (int)gpuAlgo & ShadowExp.ShadowConstants.Masks.k_ShadowVariant ); }
public static void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari )
public static ShadowAlgorithm ExtractAlgorithm( GPUShadowAlgorithm gpuAlgo ) { return (ShadowAlgorithm) ( ShadowExp.ShadowConstants.Masks.k_ShadowAlgorithm & ((int)gpuAlgo >> ShadowExp.ShadowConstants.Bits.k_ShadowVariant) ); }
public static ShadowVariant ExtractVariant( GPUShadowAlgorithm gpuAlgo ) { return (ShadowVariant ) ( ShadowExp.ShadowConstants.Masks.k_ShadowVariant & (int)gpuAlgo ); }
public static ShadowPrecision ExtractPrecision( GPUShadowAlgorithm gpuAlgo ) { return (ShadowPrecision) ( ShadowExp.ShadowConstants.Masks.k_ShadowPrecision & ((int)gpuAlgo >> (ShadowExp.ShadowConstants.Bits.k_ShadowVariant + ShadowExp.ShadowConstants.Bits.k_ShadowAlgorithm)) ); }
public static void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari, out ShadowPrecision prec )
prec = ExtractPrecision( gpuAlgo );
}
public static GPUShadowAlgorithm ClearPrecision( GPUShadowAlgorithm gpuAlgo )
{
var algo = ExtractAlgorithm( gpuAlgo );
var vari = ExtractVariant( gpuAlgo );
return Pack( algo, vari, ShadowPrecision.Low );
}
public static float Asfloat( uint val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static float Asfloat( int val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }

67
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs


}
// Add obj and reallocate if necessary. Returns the index where the object was added.
public uint Add(T obj)
public uint Add( T obj )
{
Reserve( 1 );
uint idx = m_count;

return AddUnchecked( ref vec );
}
// Adds the object if it does not exist in the container, yet
public uint AddUnique( T obj )
{
Reserve( 1 );
return AddUniqueUnchecked( obj );
}
public uint AddUnique( T[] objs, uint count )
{
Reserve( count );
return AddUniqueUnchecked( objs, count );
}
public uint AddUnique( ref VectorArray<T> vec )
{
Reserve( vec.Count() );
return AddUniqueUnchecked( ref vec );
}
public uint AddUnchecked(T obj)
public uint AddUnchecked( T obj )
{
uint idx = m_count;
this[idx] = obj;

m_count += cnt;
return idx;
}
// Adds the object if it does not exist in the container, yet
public uint AddUniqueUnchecked( T obj )
{
if( !Contains( obj ) )
return Add( obj );
return k_InvalidIdx;
}
public uint AddUniqueUnchecked( T[] objs, uint count )
{
uint res = k_InvalidIdx;
for( uint i = 0; i < count; ++i )
{
uint tmp = AddUniqueUnchecked( objs[i] );
res = res <= tmp ? res : tmp;
}
return res;
}
public uint AddUniqueUnchecked( ref VectorArray<T> vec )
{
uint res = k_InvalidIdx;
for( uint i = 0, cnt = vec.Count(); i < cnt; ++i )
{
uint tmp = AddUniqueUnchecked( vec[i] );
res = res <= tmp ? res : tmp;
}
return res;
}
// Purge count number of elements from the end of the array.
public void Purge( uint count )

idx = k_InvalidIdx;
return false;
}
// Returns true if the container already contains the element
public bool Contains( T designator )
{
uint idx;
return FindFirst( out idx, ref designator );
}
// Returns true if the container already contains the element
public bool Contains<U>( U designator, Comparator<U> compareDelegate )
{
uint idx;
return FindFirst( out idx, ref designator, compareDelegate );
}
// Returns a vector representing a subrange. Contents are shared, not duplicated.
public VectorArray<T> Subrange( uint offset, uint count )
{

正在加载...
取消
保存