BlueRoseNote/03-UnrealEngine/Rendering/Shader/Effect/PostProcess 后处理材质笔记.md

252 lines
9.6 KiB
Markdown
Raw Normal View History

2023-06-29 11:55:02 +08:00
```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));
}
```