#include "SimpleColor.h"
#include "Runtime/RenderCore/Public/PixelShaderUtils.h"
#include "Containers/DynamicRHIResourceArray.h"
// 基础的静态顶点缓冲
class FSimpleScreenVertexBuffer : public FVertexBuffer
{
public:
// 为渲染资源初始化RHI
void InitRHI()
{
// FFilterVertex 表示顶点数据是用来过滤纹理的, VERTEXBUFFER_ALIGNMENT 是内存分配时的对齐方式
TResourceArray<FFilterVertex, VERTEXBUFFER_ALIGNMENT> Vertices;
Vertices.SetNumUninitialized(6);
Vertices[0].Position = FVector4(-1, 1, 0, 1);
Vertices[0].UV = FVector2D(0, 0);
Vertices[1].Position = FVector4(1, 1, 0, 1);
Vertices[1].UV = FVector2D(1, 0);
Vertices[2].Position = FVector4(-1, -1, 0, 1);
Vertices[2].UV = FVector2D(0, 1);
Vertices[3].Position = FVector4(1, -1, 0, 1);
Vertices[3].UV = FVector2D(1, 1);
// 创建顶点缓冲区, 用上方创建的初始数据填充该缓冲
FRHIResourceCreateInfo CreateInfo(&Vertices);
VertexBufferRHI = RHICreateVertexBuffer(Vertices.GetResourceDataSize(), BUF_Static, CreateInfo);
}
};
// 声明一个顶点缓冲
TGlobalResource<FSimpleScreenVertexBuffer> GSimpleScreenVertexBuffer;
// 基础的顶点着色器
class FSimpleColorVS : public FGlobalShader
{
public:
DECLARE_GLOBAL_SHADER(FSimpleColorVS);
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return true;
}
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
FSimpleColorVS() {}
FSimpleColorVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) : FGlobalShader(Initializer) {}
};
// 像素着色器,参数作为cpp和HLSL的桥梁
class FSimpleColorPS : public FGlobalShader
{
public:
DECLARE_GLOBAL_SHADER(FSimpleColorPS);
SHADER_USE_PARAMETER_STRUCT(FSimpleColorPS, FGlobalShader);
// 和游戏线程的参数一一对应
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER(FVector4, InputColor)
END_SHADER_PARAMETER_STRUCT()
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
}
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
};
// 告诉引擎创建着色器以及着色器的入口位置
// 着色器类型 着色器路径 着色器函数名 类型
IMPLEMENT_GLOBAL_SHADER(FSimpleColorVS, "/CustomShaders/PixelShader.usf", "MainVertexShader", SF_Vertex);
IMPLEMENT_GLOBAL_SHADER(FSimpleColorPS, "/CustomShaders/PixelShader.usf", "MainPixelShader", SF_Pixel);
void FSimpleColor::DrawToRenderTarget_RenderThread(FRHICommandListImmediate& RHICmdList, const FShaderUsageParameters& DrawParameters, FTextureRHIRef UserRenderTarget)
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_CustomGlobalShaderPlugin_PixelShader); // 为UE4前端收集CPU分析数据
SCOPED_DRAW_EVENT(RHICmdList, CustomGlobalShaderPlugin_Pixel); // 为分析GPU活动添加的元数据,可以用RenderDoc这种工具查看
FRHIRenderPassInfo RenderPassInfo(DrawParameters.RenderTarget->GetRenderTargetResource()->GetRenderTargetTexture(), ERenderTargetActions::Clear_Store);
RHICmdList.BeginRenderPass(RenderPassInfo, TEXT("CustomGlobalShaderPlugin_OutputToRenderTarget"));
auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
TShaderMapRef<FSimpleColorVS> VertexShader(ShaderMap);
TShaderMapRef<FSimpleColorPS> PixelShader(ShaderMap);
// 设置图形管线状态
FGraphicsPipelineStateInitializer GraphicsPSOInit;
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
GraphicsPSOInit.PrimitiveType = PT_TriangleStrip;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
// 设置像素着色器颜色,将游戏线程的参数传进来
FSimpleColorPS::FParameters PassParameters;
PassParameters.InputColor = FVector4(DrawParameters.InputColor.R, DrawParameters.InputColor.G, DrawParameters.InputColor.B, DrawParameters.InputColor.A) / 255.0f;
// 提交参数到RHI命令列表
SetShaderParameters(RHICmdList, *PixelShader, PixelShader->GetPixelShader(), PassParameters);
// 绘制
RHICmdList.SetStreamSource(0, GSimpleScreenVertexBuffer.VertexBufferRHI, 0);
RHICmdList.DrawPrimitive(0, 2, 1);
// 完成渲染目标
RHICmdList.CopyToResolveTarget(DrawParameters.RenderTarget->GetRenderTargetResource()->GetRenderTargetTexture(), DrawParameters.RenderTarget->GetRenderTargetResource()->TextureRHI, FResolveParams());
RHICmdList.EndRenderPass();
}
评论0