vault backup: 2024-12-12 23:06:32
This commit is contained in:
parent
580a98ee1b
commit
442f4f363e
@ -218,7 +218,7 @@ void FSceneRenderer::InitDynamicShadows(FRHICommandListImmediate& RHICmdList, FG
|
|||||||
- **FProjectedShadowInfo::RenderTranslucencyDepths**
|
- **FProjectedShadowInfo::RenderTranslucencyDepths**
|
||||||
|
|
||||||
## RenderDepth
|
## RenderDepth
|
||||||
MeshDrawProcessor为***FShadowDepthPassMeshProcessor***。渲染的Shader为ShadowDepthPixelShader.usf
|
MeshDrawProcessor为***FShadowDepthPassMeshProcessor***。渲染的Shader为***ShadowDepthPixelShader.usf***
|
||||||
```c++
|
```c++
|
||||||
void FProjectedShadowInfo::RenderDepth(
|
void FProjectedShadowInfo::RenderDepth(
|
||||||
FRDGBuilder& GraphBuilder,
|
FRDGBuilder& GraphBuilder,
|
||||||
@ -438,7 +438,321 @@ bool FShadowDepthPassMeshProcessor::TryAddMeshBatch(const FMeshBatch& RESTRICT M
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Shader
|
||||||
|
VertexShader为:ShadowDepthVertexShader.usf,有4种变体:
|
||||||
|
- IMPLEMENT_SHADOW_DEPTH_SHADERMODE_SHADERS(VertexShadowDepth_PerspectiveCorrect);
|
||||||
|
- IMPLEMENT_SHADOW_DEPTH_SHADERMODE_SHADERS(VertexShadowDepth_OutputDepth);
|
||||||
|
- IMPLEMENT_SHADOW_DEPTH_SHADERMODE_SHADERS(VertexShadowDepth_OnePassPointLight);
|
||||||
|
- IMPLEMENT_SHADOW_DEPTH_SHADERMODE_SHADERS(VertexShadowDepth_VirtualShadowMap);
|
||||||
|
PixelShader为:***ShadowDepthPixelShader.usf***,有4种变体:
|
||||||
|
- IMPLEMENT_SHADOWDEPTHPASS_PIXELSHADER_TYPE(PixelShadowDepth_NonPerspectiveCorrect);
|
||||||
|
- IMPLEMENT_SHADOWDEPTHPASS_PIXELSHADER_TYPE(PixelShadowDepth_PerspectiveCorrect);
|
||||||
|
- IMPLEMENT_SHADOWDEPTHPASS_PIXELSHADER_TYPE(PixelShadowDepth_OnePassPointLight);
|
||||||
|
- IMPLEMENT_SHADOWDEPTHPASS_PIXELSHADER_TYPE(PixelShadowDepth_VirtualShadowMap);
|
||||||
|
|
||||||
|
使用对应的Shader逻辑位于GetShadowDepthPassShaders()。只有非方向光同时不是OnePass的状态下会使用**PerspectiveCorrect**。
|
||||||
|
```c++
|
||||||
|
void SetShadowDepthOutputs(
|
||||||
|
float4x4 WorldToClipMatrix,
|
||||||
|
float4x4 WorldToShadowMatrix,
|
||||||
|
float4 WorldPosition,
|
||||||
|
float3 WorldVertexNormal,
|
||||||
|
out float4 OutPosition,
|
||||||
|
out float ShadowDepth
|
||||||
|
#if PERSPECTIVE_CORRECT_DEPTH
|
||||||
|
, out float OutDepthBias
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
OutPosition = mul(WorldPosition, WorldToClipMatrix);
|
||||||
|
|
||||||
|
// Clamp the vertex to the near plane if it is in front of the near plane
|
||||||
|
// This has problems if some vertices of a triangle get clamped and others do not, also causes artifacts with non-ortho projections
|
||||||
|
if (PassStruct.bClampToNearPlane > 0 && OutPosition.z > OutPosition.w)
|
||||||
|
{
|
||||||
|
OutPosition.z = 0.999999f;
|
||||||
|
OutPosition.w = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
const float3 ViewDirection = -normalize(mul(WorldPosition, WorldToShadowMatrix).xyz);
|
||||||
|
const float3 ViewNormal = mul(float4(WorldVertexNormal,0), WorldToShadowMatrix).xyz;
|
||||||
|
const float NoL = abs(dot(ViewDirection, ViewNormal));
|
||||||
|
#else
|
||||||
|
const float NoL = abs(dot(
|
||||||
|
float3(WorldToShadowMatrix[0].z, WorldToShadowMatrix[1].z, WorldToShadowMatrix[2].z),
|
||||||
|
WorldVertexNormal));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const float MaxSlopeDepthBias = PassStruct.ShadowParams.z;
|
||||||
|
const float Slope = clamp(abs(NoL) > 0 ? sqrt(saturate(1 - NoL*NoL)) / NoL : MaxSlopeDepthBias, 0, MaxSlopeDepthBias);
|
||||||
|
|
||||||
|
const float SlopeDepthBias = PassStruct.ShadowParams.y;
|
||||||
|
const float SlopeBias = SlopeDepthBias * Slope;
|
||||||
|
|
||||||
|
const float ConstantDepthBias = PassStruct.ShadowParams.x;
|
||||||
|
const float DepthBias = SlopeBias + ConstantDepthBias;
|
||||||
|
|
||||||
|
#if PERSPECTIVE_CORRECT_DEPTH
|
||||||
|
ShadowDepth = OutPosition.z;
|
||||||
|
OutDepthBias = DepthBias;
|
||||||
|
#elif ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
ShadowDepth = 0;
|
||||||
|
//OutPosition.z += DepthBias;
|
||||||
|
#else
|
||||||
|
// Output linear, normalized depth
|
||||||
|
const float InvMaxSubjectDepth = PassStruct.ShadowParams.w;
|
||||||
|
#if PLATFORM_NEEDS_PRECISE_SHADOW_DEPTH
|
||||||
|
precise
|
||||||
|
#endif
|
||||||
|
float AdjustedDepth = ( 1 - OutPosition.z * InvMaxSubjectDepth ) + DepthBias;
|
||||||
|
ShadowDepth = AdjustedDepth;
|
||||||
|
OutPosition.z = AdjustedDepth;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main(
|
||||||
|
FVertexFactoryInput Input,
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
out FShadowDepthVSToPS OutParameters,
|
||||||
|
#else
|
||||||
|
out FShadowDepthVSToPS OutParameters,
|
||||||
|
#endif
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
out nointerpolation uint PackedPageInfo : TEXCOORD8,
|
||||||
|
#endif
|
||||||
|
out float4 OutPosition : SV_POSITION
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
, out uint LayerIndex : SV_RenderTargetArrayIndex
|
||||||
|
#endif
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
// OLA-TODO: this collides with instanced stereo, which thankfully is not used with shadow maps, so should be fine, presumably.
|
||||||
|
, out float4 OutVirtualSmPageClip : SV_ClipDistance
|
||||||
|
#endif // VIRTUAL_SM_ENABLED
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ResolvedView = ResolveView();
|
||||||
|
|
||||||
|
//计算FMaterialVertexParameters,最终获取顶点WorldPosition
|
||||||
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
||||||
|
float4 WorldPos = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
||||||
|
half3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
||||||
|
|
||||||
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPos.xyz, TangentToLocal);
|
||||||
|
const float3 WorldNormal = VertexFactoryGetWorldNormal(Input, VFIntermediates);
|
||||||
|
|
||||||
|
WorldPos.xyz += GetMaterialWorldPositionOffset(VertexParameters);
|
||||||
|
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
|
||||||
|
OutPosition = WorldPos;
|
||||||
|
|
||||||
|
#if INTERPOLATE_VF_ATTRIBUTES
|
||||||
|
// Masked materials need texture coords to clip
|
||||||
|
OutParameters.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if INTERPOLATE_POSITION
|
||||||
|
OutParameters.PixelPosition = WorldPos.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LayerIndex = bUseGpuSceneInstancing ? VertexFactoryGetViewIndex(VFIntermediates) : LayerId;
|
||||||
|
OutPosition = mul(WorldPos, PassStruct.ShadowViewProjectionMatrices[LayerIndex]);
|
||||||
|
|
||||||
|
#else
|
||||||
|
float Dummy;
|
||||||
|
|
||||||
|
SetShadowDepthOutputs(
|
||||||
|
PassStruct.ProjectionMatrix,
|
||||||
|
PassStruct.ViewMatrix,
|
||||||
|
WorldPos,
|
||||||
|
WorldNormal,
|
||||||
|
OutPosition,
|
||||||
|
#if !PERSPECTIVE_CORRECT_DEPTH
|
||||||
|
Dummy
|
||||||
|
#else
|
||||||
|
OutParameters.ShadowDepth,
|
||||||
|
OutParameters.DepthBias
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
#if INTERPOLATE_VF_ATTRIBUTES
|
||||||
|
// Masked materials need texture coords to clip
|
||||||
|
OutParameters.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if INTERPOLATE_POSITION
|
||||||
|
OutParameters.PixelPosition = WorldPos.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !PERSPECTIVE_CORRECT_DEPTH && !COMPILER_SUPPORTS_EMPTY_STRUCTS
|
||||||
|
OutParameters.Dummy = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
PackedPageInfo = 0;
|
||||||
|
|
||||||
|
OutVirtualSmPageClip = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
if (PassStruct.bRenderToVirtualShadowMap != 0)
|
||||||
|
{
|
||||||
|
// Get the offset from which we loaded the instance ID
|
||||||
|
uint InstanceIdIndex = VertexFactoryGetInstanceIdLoadIndex(VFIntermediates);
|
||||||
|
PackedPageInfo = InstanceCulling.PageInfoBuffer[InstanceIdIndex];
|
||||||
|
|
||||||
|
FPageInfo PageInfo = UnpackPageInfo(PackedPageInfo);
|
||||||
|
|
||||||
|
TransformToVirtualSmPage(OutPosition, OutVirtualSmPageClip, PageInfo, WorldPos.xyz);
|
||||||
|
}
|
||||||
|
#endif // VIRTUAL_SM_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
#if POSITION_ONLY
|
||||||
|
void PositionOnlyMain(
|
||||||
|
in FPositionAndNormalOnlyVertexFactoryInput Input,
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
out uint LayerIndex : SV_RenderTargetArrayIndex,
|
||||||
|
#endif
|
||||||
|
out FShadowDepthVSToPS OutParameters,
|
||||||
|
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
out nointerpolation uint PackedPageInfo : TEXCOORD8,
|
||||||
|
#endif
|
||||||
|
out float4 OutPosition : SV_POSITION
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
// OLA-TODO: this collides with instanced stereo, which thankfully is not used with shadow maps, so should be fine, presumably.
|
||||||
|
, out float4 OutVirtualSmPageClip : SV_ClipDistance
|
||||||
|
#endif // VIRTUAL_SM_ENABLED
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ResolvedView = ResolveView();
|
||||||
|
|
||||||
|
float4 WorldPos = VertexFactoryGetWorldPosition(Input);
|
||||||
|
|
||||||
|
#if INTERPOLATE_VF_ATTRIBUTES
|
||||||
|
OutParameters.FactoryInterpolants = (FVertexFactoryInterpolantsVSToPS)0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float3 WorldNormal = VertexFactoryGetWorldNormal(Input);
|
||||||
|
|
||||||
|
#if ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
LayerIndex = bUseGpuSceneInstancing ? VertexFactoryGetViewIndex(Input) : LayerId;
|
||||||
|
OutPosition = mul(WorldPos, PassStruct.ShadowViewProjectionMatrices[LayerIndex]);
|
||||||
|
|
||||||
|
#else // !ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
float ShadowDepth;
|
||||||
|
SetShadowDepthOutputs(
|
||||||
|
PassStruct.ProjectionMatrix,
|
||||||
|
PassStruct.ViewMatrix,
|
||||||
|
WorldPos,
|
||||||
|
WorldNormal,
|
||||||
|
OutPosition,
|
||||||
|
#if PERSPECTIVE_CORRECT_DEPTH
|
||||||
|
OutParameters.ShadowDepth,
|
||||||
|
OutParameters.DepthBias
|
||||||
|
#else
|
||||||
|
ShadowDepth
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
#if !PERSPECTIVE_CORRECT_DEPTH && !COMPILER_SUPPORTS_EMPTY_STRUCTS
|
||||||
|
OutParameters.Dummy = 0;
|
||||||
|
#endif
|
||||||
|
#endif // ONEPASS_POINTLIGHT_SHADOW
|
||||||
|
|
||||||
|
#if INTERPOLATE_POSITION
|
||||||
|
OutParameters.PixelPosition = WorldPos.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
PackedPageInfo = 0;
|
||||||
|
|
||||||
|
OutVirtualSmPageClip = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
if (PassStruct.bRenderToVirtualShadowMap != 0)
|
||||||
|
{
|
||||||
|
// Get the offset from which we loaded the instance ID
|
||||||
|
uint InstanceIdIndex = VertexFactoryGetInstanceIdLoadIndex(Input);
|
||||||
|
// TODO: Maybe offset index to local buffer for this? We may not want to use a global since most passes are not supporting this
|
||||||
|
// Or perhaps both are different, as they are managed somewhat differently anyway, maybe.
|
||||||
|
PackedPageInfo = InstanceCulling.PageInfoBuffer[InstanceIdIndex];
|
||||||
|
FPageInfo PageInfo = UnpackPageInfo(PackedPageInfo);
|
||||||
|
TransformToVirtualSmPage(OutPosition, OutVirtualSmPageClip, PageInfo, WorldPos.xyz);
|
||||||
|
}
|
||||||
|
#endif // VIRTUAL_SM_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // POSITION_ONLY
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```c++
|
||||||
|
void Main(
|
||||||
|
FShadowDepthVSToPS Inputs,
|
||||||
|
#if VIRTUAL_SM_ENABLED
|
||||||
|
nointerpolation uint PackedPageInfo : TEXCOORD8,
|
||||||
|
#endif
|
||||||
|
in float4 SvPosition : SV_Position // after all interpolators
|
||||||
|
#if PERSPECTIVE_CORRECT_DEPTH || COMPILER_METAL
|
||||||
|
,out float OutDepth : SV_DEPTH
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ResolvedView = ResolveView();
|
||||||
|
|
||||||
|
#if INTERPOLATE_VF_ATTRIBUTES
|
||||||
|
|
||||||
|
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Inputs.FactoryInterpolants, SvPosition);//取得材质中的PixelShader相关变量PixelMaterialInputs。
|
||||||
|
FPixelMaterialInputs PixelMaterialInputs;
|
||||||
|
#if INTERPOLATE_POSITION
|
||||||
|
{
|
||||||
|
float4 ScreenPosition = SvPositionToResolvedScreenPosition(SvPosition);
|
||||||
|
|
||||||
|
float3 TranslatedWorld = Inputs.PixelPosition.xyz;
|
||||||
|
|
||||||
|
CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, SvPosition, ScreenPosition, 1, TranslatedWorld, TranslatedWorld);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPosition, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Evaluate the mask for masked materials
|
||||||
|
GetMaterialClippingShadowDepth(MaterialParameters, PixelMaterialInputs);
|
||||||
|
#else
|
||||||
|
ClipLODTransition(SvPosition.xy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PERSPECTIVE_CORRECT_DEPTH
|
||||||
|
const float InvMaxSubjectDepth = PassStruct.ShadowParams.w;
|
||||||
|
Inputs.ShadowDepth = 1 - Inputs.ShadowDepth * InvMaxSubjectDepth;
|
||||||
|
Inputs.ShadowDepth += Inputs.DepthBias;
|
||||||
|
|
||||||
|
OutDepth = saturate(Inputs.ShadowDepth);
|
||||||
|
#elif COMPILER_METAL
|
||||||
|
// Metal fragment shader must not be empty,
|
||||||
|
// so output depth value explicitly if this shader permuation was not discarded
|
||||||
|
OutDepth = SvPosition.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_NON_NANITE_VSM && VIRTUAL_TEXTURE_TARGET
|
||||||
|
uint2 vAddress = (uint2)SvPosition.xy;
|
||||||
|
float DeviceZ = SvPosition.z;
|
||||||
|
|
||||||
|
FPageInfo PageInfo = UnpackPageInfo( PackedPageInfo );
|
||||||
|
FNaniteView NaniteView = UnpackNaniteView( PassStruct.PackedNaniteViews[ PageInfo.ViewId ] );
|
||||||
|
|
||||||
|
FShadowPhysicalPage Page = ShadowDecodePageTable( PassStruct.VirtualSmPageTable[ CalcPageOffset( NaniteView.TargetLayerIndex, NaniteView.TargetMipLevel, vAddress >> VSM_LOG2_PAGE_SIZE ) ] );
|
||||||
|
|
||||||
|
if( Page.bThisLODValid )
|
||||||
|
{
|
||||||
|
uint2 pAddress = Page.PhysicalAddress * VSM_PAGE_SIZE + (vAddress & VSM_PAGE_SIZE_MASK);
|
||||||
|
// If requested, render to the static page
|
||||||
|
const int ArrayIndex = PageInfo.bStaticPage ? GetVirtualShadowMapStaticArrayIndex() : 0;
|
||||||
|
InterlockedMax( PassStruct.OutDepthBufferArray[ uint3( pAddress, ArrayIndex ) ], asuint( DeviceZ ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
```
|
||||||
# Lights
|
# Lights
|
||||||
### Shader
|
### Shader
|
||||||
ShadowProjectionPixelShader.usf
|
ShadowProjectionPixelShader.usf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user