252 lines
9.6 KiB
Markdown
252 lines
9.6 KiB
Markdown
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
```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的传入位置
|
|||
|
比如AOUpsamplePS(c++中为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));
|
|||
|
}
|
|||
|
```
|