Unreal Engine Version 5.5
I am developing a global shader injected into the beginning of PostProcess phase in rendering pipeline.
In /Engine/Shaders/Common.usf
, there are three methods
SvPositionToScreenPosition
SvPositionToTranslatedWorld
SvPositionToResolvedTranslatedWorld
void MainPS( float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0)
{
//float4 ScreenPos = SvPositionToScreenPosition(SvPosition); // [-1, 1]
float3 WorldPos = SvPositionToTranslatedWorld(SvPosition);
if (isnan(WorldPos.x) || isinf(WorldPos.y))
{
OutColor = float4(1.0, 0.0, 0.0, 1.0); // Red indicates invalid values
}
else
{
OutColor = float4(WorldPos.x / 100000, WorldPos.y / 100000, WorldPos.z / 100000, 1.0);
}
}
From my test, SvPositionToScreenPosition
works fine, while SvPositionToTranslatedWorld
and SvPositionToResolvedTranslatedWorld
produce invalid values. I can see the whole screen is red.
By looking in the source code of SvPositionToTranslatedWorld
, it internally depends on View
// Used for post process shaders which don't need to resolve the view
float3 SvPositionToTranslatedWorld(float4 SvPosition)
{
float4 HomWorldPos = mul(float4(SvPosition.xyz, 1), View.SVPositionToTranslatedWorld);
return HomWorldPos.xyz / HomWorldPos.w;
}
So I added View
in the shader, and set it with InView.ViewUniformBuffer
as below. That does not work.
class FOcclusionFreeShaderPS : public FGlobalShader {
public:
DECLARE_SHADER_TYPE(FOcclusionFreeShaderPS, Global, );
SHADER_USE_PARAMETER_STRUCT(FOcclusionFreeShaderPS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, InputSampler)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
};
void FSplitSceneViewExtension::PrePostProcessPass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& InView, const FPostProcessingInputs& Inputs)
{
if( InView.PlayerIndex == 0 )
{
const FIntRect ViewPort = static_cast<const FViewInfo&>(InView).ViewRect;
FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); //GetShader for certain feature level
RDG_EVENT_SCOPE(GraphBuilder, "OcclusionFree");
FRHISamplerState* PointClampSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
Inputs.Validate();
TShaderMapRef<FOcclusionFreeShaderPS> GlobalShaderPS(GlobalShaderMap);
FOcclusionFreeShaderPS::FParameters* GlobalShaderParameters = GraphBuilder.AllocParameters<FOcclusionFreeShaderPS::FParameters>();
// ...
GlobalShaderParameters->View = InView.ViewUniformBuffer;
GlobalShaderParameters->RenderTargets[0] = FRenderTargetBinding(SceneColor.Texture, ERenderTargetLoadAction::ELoad); //(FRDGTexture, ELoadAction)
FPixelShaderUtils::AddFullscreenPass( GraphBuilder, GlobalShaderMap, FRDGEventName(TEXT("FOcclusionFreeShaderPS")), GlobalShaderPS, GlobalShaderParameters, ViewPort);
}
}
Please where is the problem? how to solve it?