BlueRoseNote/03-UnrealEngine/Rendering/Shader/Effect/PostProcess 后处理材质笔记.md
2023-06-29 11:55:02 +08:00

252 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

```c++
// Manually clamp scene texture UV as if using a clamp sampler.
MaterialFloat2 ClampSceneTextureUV(MaterialFloat2 BufferUV, const uint SceneTextureId)
{
float4 MinMax = GetSceneTextureUVMinMax(SceneTextureId);
return clamp(BufferUV, MinMax.xy, MinMax.zw);
}
```
## 相关函数的HLSL代码
```c++
float GetPixelDepth(FMaterialVertexParameters Parameters)
{
FLATTEN
if (View.ViewToClip[3][3] < 1.0f)
{
// Perspective
return GetScreenPosition(Parameters).w;
}
else
{
// Ortho
return ConvertFromDeviceZ(GetScreenPosition(Parameters).z);
}
}
float GetPixelDepth(FMaterialPixelParameters Parameters)
{
FLATTEN
if (View.ViewToClip[3][3] < 1.0f)
{
// Perspective
return GetScreenPosition(Parameters).w;
}
else
{
// Ortho
return ConvertFromDeviceZ(GetScreenPosition(Parameters).z);
}
}
float2 GetSceneTextureUV(FMaterialVertexParameters Parameters)
{
return ScreenAlignedPosition(GetScreenPosition(Parameters));
}
float2 GetSceneTextureUV(FMaterialPixelParameters Parameters)
{
return SvPositionToBufferUV(Parameters.SvPosition);
}
float2 GetViewportUV(FMaterialVertexParameters Parameters)
{
#if POST_PROCESS_MATERIAL
return Parameters.WorldPosition.xy;
#else
return BufferUVToViewportUV(GetSceneTextureUV(Parameters));
#endif
}
float2 GetPixelPosition(FMaterialVertexParameters Parameters)
{
return GetViewportUV(Parameters) * View.ViewSizeAndInvSize.xy;
}
#if POST_PROCESS_MATERIAL
float2 GetPixelPosition(FMaterialPixelParameters Parameters)
{
return Parameters.SvPosition.xy - float2(PostProcessOutput_ViewportMin);
}
float2 GetViewportUV(FMaterialPixelParameters Parameters)
{
return GetPixelPosition(Parameters) * PostProcessOutput_ViewportSizeInverse;
}
#else
float2 GetPixelPosition(FMaterialPixelParameters Parameters)
{
return Parameters.SvPosition.xy - float2(View.ViewRectMin.xy);
}
float2 GetViewportUV(FMaterialPixelParameters Parameters)
{
return SvPositionToViewportUV(Parameters.SvPosition);
}
```
## 本质上是调用了SceneTextureLookup
float4 SceneTextureLookup(float2 UV, int SceneTextureIndex, bool bFiltered)
{
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV, false);
switch(SceneTextureIndex)
{
// order needs to match to ESceneTextureId
case PPI_SceneColor:
return float4(CalcSceneColor(UV), 0);
case PPI_SceneDepth:
return ScreenSpaceData.GBuffer.Depth;
case PPI_DiffuseColor:
return float4(ScreenSpaceData.GBuffer.DiffuseColor, 0);
case PPI_SpecularColor:
return float4(ScreenSpaceData.GBuffer.SpecularColor, 0);
case PPI_SubsurfaceColor:
return IsSubsurfaceModel(ScreenSpaceData.GBuffer.ShadingModelID) ? float4( ExtractSubsurfaceColor(ScreenSpaceData.GBuffer), ScreenSpaceData.GBuffer.CustomData.a ) : ScreenSpaceData.GBuffer.CustomData;
case PPI_BaseColor:
return float4(ScreenSpaceData.GBuffer.BaseColor, 0);
case PPI_Specular:
return ScreenSpaceData.GBuffer.Specular;
case PPI_Metallic:
return ScreenSpaceData.GBuffer.Metallic;
case PPI_WorldNormal:
return float4(ScreenSpaceData.GBuffer.WorldNormal, 0);
case PPI_SeparateTranslucency:
return float4(1, 1, 1, 1); // todo
case PPI_Opacity:
return ScreenSpaceData.GBuffer.CustomData.a;
case PPI_Roughness:
return ScreenSpaceData.GBuffer.Roughness;
case PPI_MaterialAO:
return ScreenSpaceData.GBuffer.GBufferAO;
case PPI_CustomDepth:
return ScreenSpaceData.GBuffer.CustomDepth;
case PPI_PostProcessInput0:
return Texture2DSample(PostProcessInput_0_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_0_SharedSampler, UV);
case PPI_PostProcessInput1:
return Texture2DSample(PostProcessInput_1_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_1_SharedSampler, UV);
case PPI_PostProcessInput2:
return Texture2DSample(PostProcessInput_2_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_2_SharedSampler, UV);
case PPI_PostProcessInput3:
return Texture2DSample(PostProcessInput_3_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_3_SharedSampler, UV);
case PPI_PostProcessInput4:
return Texture2DSample(PostProcessInput_4_Texture, bFiltered ? PostProcessInput_BilinearSampler : PostProcessInput_4_SharedSampler, UV);
case PPI_DecalMask:
return 0; // material compiler will return an error
case PPI_ShadingModelColor:
return float4(GetShadingModelColor(ScreenSpaceData.GBuffer.ShadingModelID), 1);
case PPI_ShadingModelID:
return float4(ScreenSpaceData.GBuffer.ShadingModelID, 0, 0, 0);
case PPI_AmbientOcclusion:
return ScreenSpaceData.AmbientOcclusion;
case PPI_CustomStencil:
return ScreenSpaceData.GBuffer.CustomStencil;
case PPI_StoredBaseColor:
return float4(ScreenSpaceData.GBuffer.StoredBaseColor, 0);
case PPI_StoredSpecular:
return float4(ScreenSpaceData.GBuffer.StoredSpecular.rrr, 0);
case PPI_WorldTangent:
return float4(ScreenSpaceData.GBuffer.WorldTangent, 0);
case PPI_Anisotropy:
return ScreenSpaceData.GBuffer.Anisotropy;
default:
return float4(0, 0, 0, 0);
}
}
##
FScreenSpaceData GetScreenSpaceData(float2 UV, bool bGetNormalizedNormal = true)
{
FScreenSpaceData Out;
Out.GBuffer = GetGBufferData(UV, bGetNormalizedNormal);
float4 ScreenSpaceAO = Texture2DSampleLevel(SceneTexturesStruct.ScreenSpaceAOTexture, SceneTexturesStruct_ScreenSpaceAOTextureSampler, UV, 0);
Out.AmbientOcclusion = ScreenSpaceAO.r;
return Out;
}
## GetGBufferData使用的GBufferXTexture的传入位置
比如AOUpsamplePSc++中为FDistanceFieldAOUpsamplePS就带有FSceneTextureUniformParameters, SceneTextures。都是由对应的渲染函数的TRDGUniformBufferRef<FSceneTextureUniformParameters> SceneTexturesUniformBuffer形参传入。
```c#
FGBufferData GetGBufferData(float2 UV, bool bGetNormalizedNormal = true)
{
float4 GBufferA = Texture2DSampleLevel(SceneTexturesStruct.GBufferATexture, SceneTexturesStruct_GBufferATextureSampler, UV, 0);
float4 GBufferB = Texture2DSampleLevel(SceneTexturesStruct.GBufferBTexture, SceneTexturesStruct_GBufferBTextureSampler, UV, 0);
float4 GBufferC = Texture2DSampleLevel(SceneTexturesStruct.GBufferCTexture, SceneTexturesStruct_GBufferCTextureSampler, UV, 0);
float4 GBufferD = Texture2DSampleLevel(SceneTexturesStruct.GBufferDTexture, SceneTexturesStruct_GBufferDTextureSampler, UV, 0);
float CustomNativeDepth = Texture2DSampleLevel(SceneTexturesStruct.CustomDepthTexture, SceneTexturesStruct_CustomDepthTextureSampler, UV, 0).r;
int2 IntUV = (int2)trunc(UV * View.BufferSizeAndInvSize.xy);
uint CustomStencil = SceneTexturesStruct.CustomStencilTexture.Load(int3(IntUV, 0)) STENCIL_COMPONENT_SWIZZLE;
#if ALLOW_STATIC_LIGHTING
float4 GBufferE = Texture2DSampleLevel(SceneTexturesStruct.GBufferETexture, SceneTexturesStruct_GBufferETextureSampler, UV, 0);
#else
float4 GBufferE = 1;
#endif
float4 GBufferF = Texture2DSampleLevel(SceneTexturesStruct.GBufferFTexture, SceneTexturesStruct_GBufferFTextureSampler, UV, 0);
#if WRITES_VELOCITY_TO_GBUFFER
float4 GBufferVelocity = Texture2DSampleLevel(SceneTexturesStruct.GBufferVelocityTexture, SceneTexturesStruct_GBufferVelocityTextureSampler, UV, 0);
#else
float4 GBufferVelocity = 0;
#endif
float SceneDepth = CalcSceneDepth(UV);
//FGBufferData DecodeGBufferData()通过解码GBuffer之后返回FGBufferData 结构体
return DecodeGBufferData(GBufferA, GBufferB, GBufferC, GBufferD, GBufferE, GBufferF, GBufferVelocity, CustomNativeDepth, CustomStencil, SceneDepth, bGetNormalizedNormal, CheckerFromSceneColorUV(UV));
}
```
## GetGBufferDataFromSceneTextures中使用的GBufferXTexture的传入位置
SingleLayerWaterCompositePS中使用了GetGBufferDataFromSceneTextures()来获取GBuffer这个数据是在SingleLayerWaterRendering.cpp中传入的。传入的变量FSingleLayerWaterCommonShaderParameters->FSceneTextureParameters SceneTextures中带有GBufferABCEDF与Depth、Stencil、Velocity贴图。
```c++
Texture2D SceneDepthTexture;
Texture2D<uint2> SceneStencilTexture;
Texture2D GBufferATexture;
Texture2D GBufferBTexture;
Texture2D GBufferCTexture;
Texture2D GBufferDTexture;
Texture2D GBufferETexture;
Texture2D GBufferVelocityTexture;
Texture2D GBufferFTexture;
Texture2D<uint> SceneLightingChannels;
FGBufferData GetGBufferDataFromSceneTextures(float2 UV, bool bGetNormalizedNormal = true)
{
float4 GBufferA = GBufferATexture.SampleLevel(GBufferATextureSampler, UV, 0);
float4 GBufferB = GBufferBTexture.SampleLevel(GBufferBTextureSampler, UV, 0);
float4 GBufferC = GBufferCTexture.SampleLevel(GBufferCTextureSampler, UV, 0);
float4 GBufferD = GBufferDTexture.SampleLevel(GBufferDTextureSampler, UV, 0);
float4 GBufferE = GBufferETexture.SampleLevel(GBufferETextureSampler, UV, 0);
float4 GBufferF = GBufferFTexture.SampleLevel(GBufferFTextureSampler, UV, 0);
float4 GBufferVelocity = GBufferVelocityTexture.SampleLevel(GBufferVelocityTextureSampler, UV, 0);
uint CustomStencil = 0;
float CustomNativeDepth = 0;
float DeviceZ = SampleDeviceZFromSceneTextures(UV);
float SceneDepth = ConvertFromDeviceZ(DeviceZ);
//FGBufferData DecodeGBufferData()通过解码GBuffer之后返回FGBufferData 结构体
return DecodeGBufferData(GBufferA, GBufferB, GBufferC, GBufferD, GBufferE, GBufferF, GBufferVelocity, CustomNativeDepth, CustomStencil, SceneDepth, bGetNormalizedNormal, CheckerFromSceneColorUV(UV));
}
```