UE4引擎自定义ScreenPass和MRT输出

前言

在前面的博客 (UE4 4.27)插件添加GlobalShder 中我们定义了一个GlobalShader来对一张RT进行后处理, 那篇博客还自定义VertexShader, PixelShader, 顶点格式, 顶点数组等等,其实这个只是作为案例教学,实际上在UE4引擎里对一张纹(多张)纹理进行后处理已经有内置的RenderPass, 它是ScreenPass。UE4默认为我们定义了FScreenVS和配套DrawRectangle函数,我们只需要轻松编写自己PixelShader,就可以进行后处理。

ScreenPass和MRT同时输出灰度图和亮度调整图

这里MRT是MultiRenderTarget.

灰度图

这里我选用浮点算法。

亮度调整图

Color = Scale * Color

建立MRT的ScreenPass关键代码

FScreenVS + 自定义的PixelShaderPass, 另外就是FRHIRenderPassInfo的输入得指定FRHITexture数组

自定义的PixelShaderPass---DrawShader.usf


#include "/Engine/Public/Platform.ush"

Texture2D InTexture;
SamplerState InTextureSampler;

float4 MyColor;
float MyColorScale;

void MainPS(
	in float2 UV : TEXCOORD0,
	out float4 OutColor1 : SV_Target0,
	out float4 OutColor2 : SV_Target1)
{
	float4 TextureColor = InTexture.Sample(InTextureSampler, UV);
	float Gray = 0.3 * TextureColor.r + 0.59 * TextureColor.g + 0.11 * TextureColor.b;
	OutColor1 = float4(Gray, Gray, Gray, 1.0);
    OutColor2 = MyColor * TextureColor * MyColorScale;
}

RenderPass代码

static void DrawTestShaderToRenderTexture_RenderThread(
	FRHICommandListImmediate& RHICmdList,
	FTexture* InTextureResource,
	FTextureRenderTargetResource* OutGrayRTReource,
	FTextureRenderTargetResource* OutScaleRTReource,
	ERHIFeatureLevel::Type FeatureLevel,
	const FLinearColor& Color,
	float ColorScale)
{
	check(IsInRenderingThread());

	FRHITexture2D* OutGrayRTT = OutGrayRTReource->GetRenderTargetTexture();
	FRHITexture2D* OutScaleRTT = OutScaleRTReource->GetRenderTargetTexture();
	if (nullptr == OutGrayRTT || nullptr == OutScaleRTT)
		return;

	if (OutGrayRTT->GetSizeX() != OutScaleRTT->GetSizeX() || OutGrayRTT->GetSizeY() != OutScaleRTT->GetSizeY())
		return;

	FRHITexture* RTS[] = { OutGrayRTT, OutScaleRTT };
	IRendererModule* RendererModule = &FModuleManager::GetModuleChecked<IRendererModule>("Renderer");

	RHICmdList.Transition(FRHITransitionInfo(OutGrayRTT, ERHIAccess::SRVMask, ERHIAccess::RTV));
	RHICmdList.Transition(FRHITransitionInfo(OutScaleRTT, ERHIAccess::SRVMask, ERHIAccess::RTV));
	
	FRHIRenderPassInfo RPInfo(2, RTS, ERenderTargetActions::DontLoad_Store);
	RHICmdList.BeginRenderPass(RPInfo, TEXT("Render Test Shader To Texture"));
	{

		// Get Shaders
		FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(FeatureLevel);
		TShaderMapRef<FScreenVS> VertexShader(GlobalShaderMap);
		TShaderMapRef<FDrawPS> PixelShader(GlobalShaderMap);

		// Setup Pipeline state
		FGraphicsPipelineStateInitializer GraphicsPSOInit;
		RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
		GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
		GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
		GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();

		GraphicsPSOInit.PrimitiveType = PT_TriangleList;
		GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
		GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader();
		GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader();
		SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);

		// Upate viewport
		FIntPoint ViewportSize(OutGrayRTT->GetSizeX(), OutGrayRTT->GetSizeY());
		RHICmdList.SetViewport(0, 0, 0.0f, ViewportSize.X, ViewportSize.Y, 1.0f);

		// update shader uniform parameters
		PixelShader->SetParam(RHICmdList, InTextureResource, Color, ColorScale);


		RendererModule->DrawRectangle(RHICmdList, 0, 0, ViewportSize.X, ViewportSize.Y, 0, 0, 1, 1, ViewportSize, FIntPoint(1, 1), VertexShader);
	}
	RHICmdList.EndRenderPass();

	RHICmdList.Transition(FRHITransitionInfo(OutGrayRTT, ERHIAccess::RTV, ERHIAccess::SRVMask));
	RHICmdList.Transition(FRHITransitionInfo(OutScaleRTT, ERHIAccess::RTV, ERHIAccess::SRVMask));
}

显示效果

 

插件链接

https://download.csdn.net/download/qq_29523119/86008217

猜你喜欢

转载自blog.csdn.net/qq_29523119/article/details/125609865