UE5.5 Global Shader : SvPositionToTranslatedWorld not work

IAmNoBody2we
Thu, 16 Jan 2025 08:52:51 +0000
C++

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?

3 posts - 2 participants