Copy SceneDepth Information in FSceneViewExtension

I am trying to copy the SceneDepthTexture within My custom SceneViewExtension

Here are the settings

void FVDRadarSceneViewExtension::PrePostProcessPass_RenderThread(
	FRDGBuilder& graphBuilder, const FSceneView& view, const FPostProcessingInputs& inputs)
{
	QUICK_SCOPE_CYCLE_COUNTER(STAT_FRadarSceneViewExtension_PrePostProcessPass_RenderThread);
	checkSlow(View.bIsViewInfo);
	check(view.bIsViewInfo);
	inputs. Validate();

	check(view.bIsViewInfo);
	inputs.Validate();

	// Get the sensor's view direction
	if (!cameraComponent.IsValid()) return;
	const FIntRect viewport = static_cast<const FViewInfo&>(view).ViewRect;

	// can't do dynamic_cast because FViewInfo doesn't have any virtual functions.
	FScreenPassTexture sceneColor((*inputs.SceneTextures)->SceneColorTexture, viewport);
	FScreenPassTexture sceneDepth((*inputs.SceneTextures)->SceneDepthTexture, viewport);

	FSceneTextureShaderParameters scene = GetSceneTextureShaderParameters(view);
	const FGlobalShaderMap* globalShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
	
	const FScreenPassTextureViewport sceneDepthTextureViewport(sceneDepth);
	const FScreenPassTextureViewportParameters sceneDepthTextureViewportParams =
		GetTextureViewportParameters(sceneDepthTextureViewport);
	
	FScreenPassRenderTarget SceneDepthCopyRenderTarget;
	SceneDepthCopyRenderTarget.Texture = graphBuilder.CreateTexture(sceneDepth.Texture->Desc, TEXT("Scene Depth"));
	
	check(globalShaderMap);
	RDG_EVENT_SCOPE(graphBuilder, "Copy Depth");
	// First Pass (This exist is to hold the previous render target texture)
	// FScreenPassRenderTarget depthRenderTarget;
	// FRDGTextureDesc depthTextureDesc;
	// depthTextureDesc.Reset();
	// depthTextureDesc.Dimension = ETextureDimension::Texture2D;
	// depthTextureDesc.Flags |= ETextureCreateFlags::RenderTargetable | ETextureCreateFlags::DepthStencilTargetable
	// 	| ETextureCreateFlags::ShaderResource;
	// depthTextureDesc.Format = PF_DepthStencil;
	// depthTextureDesc.Extent = sceneDepth.Texture->Desc.Extent;
	
	TShaderMapRef<UpdateDepthShader> copyDepthShader(globalShaderMap);
	UpdateDepthShader::FParameters* copyDepthParam = graphBuilder.AllocParameters<UpdateDepthShader::FParameters>();
	copyDepthParam->CameraDepthTexture = (*inputs.SceneTextures)->SceneDepthTexture;
	copyDepthParam->CameraDepthSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();

	FCommonShaderParameters commonShaderParameters;
	commonShaderParameters.ViewUniformBuffer = view.ViewUniformBuffer;
	copyDepthParam->SceneColor = (*inputs.SceneTextures)->SceneColorTexture;
	copyDepthParam->ViewParams = sceneDepthTextureViewportParams;
	copyDepthParam->CommonParameters = commonShaderParameters;
	copyDepthParam->RenderTargets[0] = SceneDepthCopyRenderTarget.GetRenderTargetBinding();
	// updateDepthParam->RenderTargets.DepthStencil = FDepthStencilBinding(
	// 	sceneDepth.Texture, ERenderTargetLoadAction::ENoAction, FExclusiveDepthStencil::DepthWrite_StencilWrite);
	
	FPixelShaderUtils::AddFullscreenPass(graphBuilder, globalShaderMap, FRDGEventName(TEXT("Copy Depth")),
		copyDepthShader, copyDepthParam, viewport);

	AddCopyTexturePass(graphBuilder, sceneDepth.Texture, SceneDepthCopyRenderTarget.Texture);
	previousRenderTargetTexture = SceneDepthCopyRenderTarget.Texture;
}

Here is the shader code.

SCREEN_PASS_TEXTURE_VIEWPORT(ViewParams)
Texture2D CameraDepthTexture;
SamplerState CameraDepthSampler;
Texture2D SceneColor;

void MainPS(float4 SvPosition : SV_POSITION, out float Depth : SV_Depth)
{
	float2 uv = PosToUV(SvPosition.xy);
	const int2 pixelPos = int2(SvPosition.xy);

	const float sceneDeviceZ = CameraDepthTexture.Load(int3(pixelPos, 0)).r;
	const float sceneDepth = ConvertFromDeviceZ(sceneDeviceZ);

	// 0 .. 1
	// half Near = CalcUnfocusedPercentCustomBound(sceneDepth, 1, 0);
	// half Far = CalcUnfocusedPercentCustomBound(sceneDepth, 0, 1);

	// const float deviceZ = CameraDepthTexture.Load(int3(pixelPos, 0)).r;
	// float4(frac(ConvertFromDeviceZ(deviceZ) * 0.0001f), 0, 0, 1);
	// DepthTexture = Texture2DSample(CameraDepthTexture, CameraDepthSampler, uv);
	// CameraDepthTexture.Load(int3(pixelPos, 0));
	// depthTexture = SceneDepth;
	// OutColor = float4(2 * frac(ConvertFromDeviceZ(sceneDeviceZ) * 0.0001f), 0, 0, 1);
	// depthTexture = float4(frac(ConvertFromDeviceZ(deviceZ) * 0.0001f), 0, 0, 1);

	Depth = CameraDepthTexture.Load(int3(pixelPos, 0)).r;
}

and it seems like this pass doesn’t show in the RenderDoc. The purpose of having the previousRenderTargetTexture is to hold the past scenedepth

I found the solution that you can create CopyShader by following

SCREEN_PASS_TEXTURE_VIEWPORT(ViewParams)
Texture2D CameraDepthTexture;
void MainPS(float4 SvPosition : SV_POSITION, out float depth : SV_Depth)
{
	const int2 pixelPos = int2(SvPosition.xy);
	depth = CameraDepthTexture.Load(int3(pixelPos, 0)).r;
}

then, you can do

FPixelShaderUtils::AddFullscreenPass(
		graphBuilder, globalShaderMap, FRDGEventName(TEXT("Copy Depth")), copyDepthShader, copyDepthParam, viewport);

	AddCopyTexturePass(graphBuilder, sceneDepth.Texture, SceneDepthCopyRenderTarget.Texture);
2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.