浏览代码

[gfx-shadows] First step toward adding tents pcf filters

Adding UI and placeholder shader implementation
/main
FlorentGuinier 8 年前
当前提交
980b67d3
共有 5 个文件被更改,包括 91 次插入24 次删除
  1. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  2. 51
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  3. 49
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
  4. 11
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  5. 3
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_PreIntegratedFGD.filterMode = FilterMode.Bilinear;
m_PreIntegratedFGD.wrapMode = TextureWrapMode.Clamp;
m_PreIntegratedFGD.hideFlags = HideFlags.DontSave;
m_PreIntegratedFGD.Create();
m_LtcData = new Texture2DArray(k_LtcLUTResolution, k_LtcLUTResolution, 3, TextureFormat.RGBAHalf, false /*mipmap*/, true /* linear */)

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


}
//
// 3x3 tent PCF sampling (4 taps)
//
float SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )
{
return 0.5;
}
float SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
return 0.5;
}
//
// 5x5 tent PCF sampling (9 taps)
//
float SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )
{
return 0.5;
}
float SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
return 0.5;
}
//
// 7x7 tent PCF sampling (16 taps)
//
float SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )
{
return 0.5;
}
float SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
return 0.5;
}
//
// 9 tap adaptive PCF sampling
//
float SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )

float3 z;
float4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )
return ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
else

float3 z;
float4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )
return ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
else

{
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_3X3: return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_5X5: return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_7X7: return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, true );

{
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_3X3: return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_5X5: return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_7X7: return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
default: return 1.0;
}
}

49
Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs


override protected void Register( GPUShadowType type, ShadowRegistry registry )
{
ShadowPrecision precision = m_ShadowmapBits == 32 ? ShadowPrecision.High : ShadowPrecision.Low;
m_SupportedAlgorithms.Reserve( 2 );
m_SupportedAlgorithms.Reserve( 5 );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.PCF, ShadowVariant.V2, precision ) );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.PCF, ShadowVariant.V3, precision ) );
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.PCF, ShadowVariant.V4, precision ) );
ShadowRegistry.VariantDelegate del = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
{

if( dataVariant == ShadowVariant.V1 )
m_DefPCF_FilterSize.Slider( ref dataBlock[1] );
};
registry.Register( type, precision, ShadowAlgorithm.PCF, "Percentage Closer Filtering (PCF)",
new ShadowVariant[]{ ShadowVariant.V0, ShadowVariant.V1 }, new string[]{"1 tap", "9 tap adaptive" }, new ShadowRegistry.VariantDelegate[] { del, del } );
registry.Register( type, precision, ShadowAlgorithm.PCF, "Percentage Closer Filtering (PCF)",
new ShadowVariant[]{ ShadowVariant.V0, ShadowVariant.V1, ShadowVariant.V2, ShadowVariant.V3, ShadowVariant.V4 },
new string[]{"1 tap", "9 tap adaptive", "tent 3x3 (4 taps)", "tent 5x5 (9 taps)", "tent 7x7 (16 taps)" },
new ShadowRegistry.VariantDelegate[] { del, del, del, del, del } );
if( algorithm != ShadowAlgorithm.PCF || (variant != ShadowVariant.V0 && variant != ShadowVariant.V1) )
if( algorithm != ShadowAlgorithm.PCF ||
(variant != ShadowVariant.V0 &&
variant != ShadowVariant.V1 &&
variant != ShadowVariant.V2 &&
variant != ShadowVariant.V3 &&
variant != ShadowVariant.V4))
return true;
const int k_BlockSize = 2;

bool multiFace= sr.shadowType != GPUShadowType.Spot;
const uint k_MaxShadowDatasPerLight = 7; // 1 shared ShadowData and up to 6 faces for point lights
entries.Reserve( k_MaxShadowDatasPerLight );
entries.Reserve( k_MaxShadowDatasPerLight );
float nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;

{
// For lights with multiple faces, the first shadow data contains
// For lights with multiple faces, the first shadow data contains
// per light information, so not all fields contain valid data.
// Shader code must make sure to read per face data from per face entries.
sd.texelSizeRcp = new Vector2( m_WidthRcp, m_HeightRcp );

{
case ShadowVariant.V0:
case ShadowVariant.V1:
case ShadowVariant.V2:
case ShadowVariant.V3:
case ShadowVariant.V4:
{
sp.Set( shadowData[0] | (SystemInfo.usesReversedZBuffer ? 1 : 0), shadowData[1], 0, 0 );
payload[payloadOffset] = sp;

for( uint i = 0; i < m_ActiveEntriesCount; ++i )
{
CachedEntry ce = m_EntryCache[i];
ShadowData sd = entries[ce.key.shadowDataIdx];
// update the shadow data with the actual result of the layouting step
sd.scaleOffset = new Vector4( ce.current.viewport.width * m_WidthRcp, ce.current.viewport.height * m_HeightRcp, ce.current.viewport.x * m_WidthRcp, ce.current.viewport.y * m_HeightRcp );

// shadow atlas layouting
CachedEntry ce = m_EntryCache[i];
Rect vp = ce.current.viewport;
if( curx + vp.width > xmax )
{
curx = 0;

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, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate vsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
{
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );

};
ShadowRegistry.VariantDelegate evsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate evsmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
{
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );

BlurSlider( ref dataBlock[4] );
};
ShadowRegistry.VariantDelegate msmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
ShadowRegistry.VariantDelegate msmDel = ( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock ) =>
{
CheckDataIntegrity( dataAlgorithm, dataVariant, dataPrecision, ref dataBlock );

if( supports_VSM )
{
m_SupportedAlgorithms.AddUniqueUnchecked( ShadowUtils.Pack( ShadowAlgorithm.VSM, ShadowVariant.V0, precision ) );
registry.Register( type, precision, ShadowAlgorithm.VSM, "Variance shadow map (VSM)",
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 )

if( i >= cnt || m_EntryCache[i].current.slice > rendertargetSlice )
return;
int kernelIdx = 2;
int currentKernel = 0;

float evsmExponent1 = ShadowUtils.Asfloat( shadowData[2] );
cb.SetComputeFloatParam( m_MomentBlurCS, "evsmExponent", evsmExponent1 );
kernelIdx = shadowData[4];
currentKernel = m_KernelEVSM_2[kernelIdx];
currentKernel = m_KernelEVSM_2[kernelIdx];
}
else
{

shadowRequestsCount = 0;
return;
}
// first sort the shadow casters according to some priority
PrioritizeShadowCasters( camera, lights, shadowRequestsCount, shadowRequests );

uint totalGranted;
PruneShadowCasters( camera, lights, ref requestedShadows, ref m_TmpRequests, out totalGranted );
// if there are no shadow casters at this point -> bail
if( totalGranted == 0 )
{

VisibleLight vl = lights[grantedRequests[i].index];
Light l = vl.light;
AdditionalLightData ald = l.GetComponent<AdditionalLightData>();
// set light specific values that are not related to the shadowmap
GPUShadowType shadowtype;
ShadowUtils.MapLightType( ald.archetype, vl.lightType, out shadowtype );

shadowIndices.AddUnchecked( (int) shadowDatas.Count() );
int smidx = 0;

11
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs


All = Point | Spot | Directional
};
public enum ShadowAlgorithm // 6 bits
{
PCF,

{
PCF_1tap = ShadowAlgorithm.PCF << 3 | ShadowVariant.V0,
PCF_9tap = ShadowAlgorithm.PCF << 3 | ShadowVariant.V1,
PCF_tent3x3 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V2,
PCF_tent5x5 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V3,
PCF_tent7x7 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V4,
VSM = ShadowAlgorithm.VSM << 3,
EVSM_2 = ShadowAlgorithm.EVSM << 3 | ShadowVariant.V0,
EVSM_4 = ShadowAlgorithm.EVSM << 3 | ShadowVariant.V1,

}
}
}
public void Draw( Light l )
{
AdditionalLightData ald = l.GetComponent<AdditionalLightData>();

int varsAvailable = e.variantsAvailable;
int[] varOptions = new int[varsAvailable];
GUIContent[] varDescs = new GUIContent[varsAvailable];
idx = 0;
for( int writeIdx = 0; writeIdx < varsAvailable; idx++ )
{

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--;
}

3
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl


//
#define GPUSHADOWALGORITHM_PCF_1TAP (0)
#define GPUSHADOWALGORITHM_PCF_9TAP (1)
#define GPUSHADOWALGORITHM_PCF_TENT_3X3 (2)
#define GPUSHADOWALGORITHM_PCF_TENT_5X5 (3)
#define GPUSHADOWALGORITHM_PCF_TENT_7X7 (4)
#define GPUSHADOWALGORITHM_VSM (8)
#define GPUSHADOWALGORITHM_EVSM_2 (16)
#define GPUSHADOWALGORITHM_EVSM_4 (17)

正在加载...
取消
保存