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

9.6 KiB
Raw Blame History

// 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代码

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 SceneTexturesUniformBuffer形参传入。

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贴图。

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