UE5 中在全局着色器的数据更新流程

解释:

全局着色器(Global Shaders)是不通过材质编辑器创建的着色器。相反,全局着色器使用C++创建,它们在固定的几何体上运行,并且无需与材质或网格体结合。
有些算法材质中实现比较复杂,但是C++却很简单

着色器类型

  1. vs顶点着色器(Vertex Shader)
  2. ps像素着色器(Pixel Shader)
  3. gs几何体着色器(Geometry Shader)
  4. hs凸包着色器(Hull Shader)
  5. ds域着色器(Domain Shader)
  6. cs计算着色器(Computer Shader)

目的:

材质参数更新不需要通过材质节点,而是直接通过C++直接更新.ush文件中的参数内容

流程

1. 创建插件
2. 路径映射
3. 编写着色器文件.ush和对应C++结构体
4. 申明全局着色器类型
5. 在C++申明、绑定着色器参数,和赋值
6. 实现像素着色器和顶点着色器
7. GPU中数据更新

创建插件:

1. 创建插件
2. 在.build.cs中添加渲染模块
PublicIncludePaths.AddRange(
			new string[] {
				// ... add public include paths required here ...
				"Foo/Public"
            }
			);
				
		
		PrivateIncludePaths.AddRange(
			new string[] {
                "Foo/Private",
				// ... add other private include paths required here ...
			}
			);
PublicDependencyModuleNames.AddRange(
    new string[]
    {
        "Core",
        "RenderCore",
        "RHI"
            // ... add other public dependencies that you statically link with here ...
        }
);

路径映射

在插件启动函数中添加
TEXT("/Plugin/Foo") 不能写成 TEXT("/Plugin/Foo/")
// Copyright Epic Games, Inc. All Rights Reserved.

#include "Foo.h"
#include "Modules/ModuleManager.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Paths.h"

#define LOCTEXT_NAMESPACE "FFooModule"

void FFooModule::StartupModule()
{
	//FString FooShaderDir = FPaths::Combine(FPaths::ProjectPluginsDir(),TEXT("Foo/"), TEXT("Shaders"));
	FString FooShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin("Foo")->GetBaseDir(), TEXT("Shaders"));

	AddShaderSourceDirectoryMapping(TEXT("/Plugin/Foo"), FooShaderDir);
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}

void FFooModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FFooModule, Foo)
路径映射注意事项
假设实际文件夹路径:Plugins/Foo/Shaders/Private/MyTest.usf
IMPLEMENT_SHADER_TYPE 和 IMPLEMENT_GLOBAL_SHADER写法不一样,否则编译会报错
//另一种申明方式 DECLARE_GLOBAL_SHADER(FMyTestVS);


class FLensDistortionUVGenerationVS : public FLensDistortionUVGenerationShader
{
	DECLARE_SHADER_TYPE(FLensDistortionUVGenerationVS, Global);
public:

	/** Default constructor. */
	FLensDistortionUVGenerationVS() {}

	/** Initialization constructor. */
	FLensDistortionUVGenerationVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
		: FLensDistortionUVGenerationShader(Initializer)
	{
	}
};


class FLensDistortionUVGenerationPS : public FLensDistortionUVGenerationShader
{
	DECLARE_SHADER_TYPE(FLensDistortionUVGenerationPS, Global);
public:

	/** Default constructor. */
	FLensDistortionUVGenerationPS() {}

	/** Initialization constructor. */
	FLensDistortionUVGenerationPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
		: FLensDistortionUVGenerationShader(Initializer)
	{ }
};
//下面中一个有TEXT,一个没有,这个容易报错
//IMPLEMENT_GLOBAL_SHADER(FMyTestVS, "/Plugin/Foo/Private/MyShader.usf","MainVS", SF_Vertex);
//IMPLEMENT_GLOBAL_SHADER(FMyTestPS, "/Plugin/Foo/Private/MyShader.usf","MainPS", SF_Pixel);

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationVS, TEXT("/Plugin/Foo/Private/MyShader.usf"), TEXT("MainVS"), SF_Vertex)
IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationPS, TEXT("/Plugin/Foo/Private/MyShader.usf"), TEXT("MainPS"), SF_Pixel)

编写着色器文件.ush和对应的C++结构体

MyShader.ush
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

    /*=============================================================================
        LensDistortionUVGeneration.usf:将光学变形和不
        变形UV置换贴图生成到一个渲染目标中。

        像素着色器直接计算变形视口UV,
        不对使用Sv_Position和参考方程式的视口UV置换执行变形,
        并将它们保存到红色和绿色的通道中。

        为避免用费拉里法进行解析、
        或在 GPU 上执行牛顿法计算不变形视口 UV 这两种方式
        来对视口UV置换进行变形,这对着色器的工作方式如下:顶点着色器不对网格的顶点执行变形,
        并下传到像素着色器视口 UV 应在屏幕上
        所处的位置,而不进行变形。像素
        着色器可生成不变形视口UV,
        减去像素的视口UV后即可对视口UV置换进行变形。
    =============================================================================*/

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

    // 视口UV坐标中的像素大小。
    float2 PixelUVSize;

    // K1, K2, K3
    float3 RadialDistortionCoefs;

    // P1, P2
    float2 TangentialDistortionCoefs;

    // 未变形视口的相机矩阵。
    float4 UndistortedCameraMatrix;

    // 变形视口的相机矩阵。
    float4 DistortedCameraMatrix;

    // 对渲染目标输出乘法和加法。
    float2 OutputMultiplyAndAdd;

    // 不对V.z=1视图位置进行变形。
    float2 UndistortNormalizedViewPosition(float2 V)
    {
        float2 V2 = V * V;
        float R2 = V2.x + V2.y;

        // 径向变形(额外添加括号是为匹配 MF_Undistortion.uasset)。
        float2 UndistortedV = V * (1.0 + R2 * (RadialDistortionCoefs.x + R2 * (RadialDistortionCoefs.y + R2 * RadialDistortionCoefs.z)));

        // 切向变形。
        UndistortedV.x += TangentialDistortionCoefs.y * (R2 + 2 * V2.x) + 2 * TangentialDistortionCoefs.x * V.x * V.y;
        UndistortedV.y += TangentialDistortionCoefs.x * (R2 + 2 * V2.y) + 2 * TangentialDistortionCoefs.y * V.x * V.y;

        return UndistortedV;
    }

    // 返回变形视口UV的未变形视口UV。
    //
    // 注意:
    //        UV创建于左下角。
    float2 UndistortViewportUV(float2 ViewportUV)
    {
        // 已变形视口UV -> 已变形视图位置(z=1)
        float2 DistortedViewPosition = (ViewportUV - DistortedCameraMatrix.zw) / DistortedCameraMatrix.xy;

        // 计算未变形的视图位置(z=1)
        float2 UndistortedViewPosition = UndistortNormalizedViewPosition(DistortedViewPosition);

        // 未变形的视图位置(z=1) -> 未变形的视口UV。
        return UndistortedCameraMatrix.xy * UndistortedViewPosition + UndistortedCameraMatrix.zw;
    }

    // 翻转UV的y组件。
    float2 FlipUV(float2 UV)
    {
        return float2(UV.x, 1 - UV.y);
    }

    void MainVS(
        in uint GlobalVertexId :SV_VertexID,
        out float2 OutVertexDistortedViewportUV :TEXCOORD0,
        out float4 OutPosition :SV_POSITION
        )
    {
        // 计算单元索引。
        uint GridCellIndex = GlobalVertexId / 6;

        // 计算网格中单元行和列的ID。
        uint GridColumnId = GridCellIndex / GRID_SUBDIVISION_Y;
        uint GridRowId = GridCellIndex - GridColumnId * GRID_SUBDIVISION_Y;

        // 计算双三角形网格单元中的顶点ID。
        uint VertexId = GlobalVertexId - GridCellIndex * 6;

        // 计算单元中三角形顶点源自左下角的UV坐标。
        float2 CellVertexUV = float2(0x1 & ((VertexId + 1) / 3), VertexId & 0x1);

        // 计算网格中顶点源自左上角的UV。
        float2 GridInvSize = 1.f / float2(GRID_SUBDIVISION_X, GRID_SUBDIVISION_Y);
        float2 GridVertexUV = FlipUV(
            GridInvSize * (CellVertexUV + float2(GridColumnId, GridRowId)));

        // 标准不含半像素位移。
        GridVertexUV -= PixelUVSize * 0.5;

        // 输出顶点位置。
        OutPosition = float4(FlipUV(
            UndistortViewportUV(GridVertexUV) + PixelUVSize * 0.5) * 2 - 1, 0, 1);

        // 输出顶点源自左上角的UV。
        OutVertexDistortedViewportUV = GridVertexUV;
    }

    void MainPS(
        in noperspective float2 VertexDistortedViewportUV :TEXCOORD0,
        in float4 SvPosition :SV_POSITION,
        out float4 OutColor :SV_Target0
        )
    {
        // 计算像素源自左上角的UV。
        float2 ViewportUV = SvPosition.xy * PixelUVSize;

        // 标准不含半像素位移。
        ViewportUV -= PixelUVSize * 0.5;

        float2 DistortUVtoUndistortUV = (UndistortViewportUV((ViewportUV))) - ViewportUV;
        float2 UndistortUVtoDistortUV = VertexDistortedViewportUV - ViewportUV;

        // 输出置换通道。
        OutColor = OutputMultiplyAndAdd.y + OutputMultiplyAndAdd.x * float4(
            DistortUVtoUndistortUV, UndistortUVtoDistortUV);
    }
c++结构体申明
/** 光学变形/不变形的数学相机模型。
*
* 相机矩阵 =
*  | F.X  0  C.x |
*  |  0  F.Y C.Y |
*  |  0   0   1  |
*/
USTRUCT(BlueprintType)
struct FFooCameraModel
{
    GENERATED_USTRUCT_BODY()
        FFooCameraModel()
    {
        K1 = K2 = K3 = P1 = P2 = 0.f;
        F = FVector2D(1.f, 1.f);
        C = FVector2D(0.5f, 0.5f);
    }

    /** Radial parameter #1.*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        float K1;

    /** 径向参数 #2。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        float K2;

    /** 径向参数 #3。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        float K3;

    /** 切向参数 #1。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        float P1;

    /** 切向参数 #2。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        float P2;

    /** 相机矩阵的Fx和Fy。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        FVector2D F;

    /** 相机矩阵的Cx和Cy。*/
    UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Lens Distortion|Camera Model")
        FVector2D C;

    /** 不在视图空间中进行3D向量变形(x, y, z=1.f)并返回(x', y', z'=1.f)。*/
    FVector2D UndistortNormalizedViewPosition(FVector2D V) const;

    /** 返回不变形渲染所需的过扫描因子,避免出现未渲染的变形像素。*/
    float GetUndistortOverscanFactor(
        float DistortedHorizontalFOV,
        float DistortedAspectRatio) const;

    /** 在输出渲染目标中绘制UV置换贴图。
    * - 红色和绿色通道负责变形置换;
    * - 蓝色和透明通道负责不变形置换。
    * @param World 获取渲染设置的当前场景(如特征场景)。
    * @param DistortedHorizontalFOV 变形渲染中理想的水平视野。
    * @param DistortedAspectRatio 变形渲染中理想的高宽比。
    * @param UndistortOverscanFactor 未变形渲染的过扫描因子。
    * @param OutputRenderTarget 进行绘制的渲染目标。不必拥有和变形渲染相同的分辨率或高宽比。
    * @param OutputMultiply 应用在置换上的乘法因子。
    * @param OutputAdd 保存到输出渲染目标中之前被添加到相乘置换的值。
    */
    void DrawUVDisplacementToRenderTarget2(
        class UWorld* World,
        float DistortedHorizontalFOV,
        float DistortedAspectRatio,
        float UndistortOverscanFactor,
        class UTextureRenderTarget2D* OutputRenderTarget,
        float OutputMultiply,
        float OutputAdd) const;

    /** 对比两个光学变形模型并返回其是否相同。*/
    bool operator == (const FFooCameraModel& Other) const
    {
        return (
            K1 == Other.K1 &&
            K2 == Other.K2 &&
            K3 == Other.K3 &&
            P1 == Other.P1 &&
            P2 == Other.P2 &&
            F == Other.F &&
            C == Other.C);
    }

    /** 对比两个光学变形模型并返回其是否不同。*/
    bool operator != (const FFooCameraModel& Other) const
    {
        return !(*this == Other);
    }
};

申明全局着色器类型

#include "Engine/TextureRenderTarget2D.h"
#include "Engine/World.h"
#include "GlobalShader.h"
#include "PipelineStateCache.h"
#include "ProfilingDebugging/RealtimeGPUProfiler.h"
#include "RHIStaticStates.h"
#include "SceneInterface.h"
#include "ShaderParameterUtils.h"
#include "Logging/MessageLog.h"
#include "TextureResource.h"
#include "DataDrivenShaderPlatformInfo.h"
#include "RenderingThread.h"


在C++申明、绑定着色器参数,和赋值

class FLensDistortionUVGenerationShader : public FGlobalShader
{
	DECLARE_INLINE_TYPE_LAYOUT(FLensDistortionUVGenerationShader, NonVirtual);
public:

	static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
	{
		return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
	}

	static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
	{
		FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
		OutEnvironment.SetDefine(TEXT("GRID_SUBDIVISION_X"), kGridSubdivisionX);
		OutEnvironment.SetDefine(TEXT("GRID_SUBDIVISION_Y"), kGridSubdivisionY);
	}

	FLensDistortionUVGenerationShader() {}

	FLensDistortionUVGenerationShader(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
		: FGlobalShader(Initializer)
	{
		PixelUVSize.Bind(Initializer.ParameterMap, TEXT("PixelUVSize"));
		RadialDistortionCoefs.Bind(Initializer.ParameterMap, TEXT("RadialDistortionCoefs"));
		TangentialDistortionCoefs.Bind(Initializer.ParameterMap, TEXT("TangentialDistortionCoefs"));
		DistortedCameraMatrix.Bind(Initializer.ParameterMap, TEXT("DistortedCameraMatrix"));
		UndistortedCameraMatrix.Bind(Initializer.ParameterMap, TEXT("UndistortedCameraMatrix"));
		OutputMultiplyAndAdd.Bind(Initializer.ParameterMap, TEXT("OutputMultiplyAndAdd"));
	}
//这个很重要
	template<typename TShaderRHIParamRef>
	void SetParameters(
		FRHICommandListImmediate& RHICmdList,
		const TShaderRHIParamRef ShaderRHI,
		const FCompiledCameraModel& CompiledCameraModel,
		const FIntPoint& DisplacementMapResolution)
	{
		FVector2f PixelUVSizeValue(
			1.f / float(DisplacementMapResolution.X), 1.f / float(DisplacementMapResolution.Y));
		FVector3f RadialDistortionCoefsValue(
			CompiledCameraModel.OriginalCameraModel.K1,
			CompiledCameraModel.OriginalCameraModel.K2,
			CompiledCameraModel.OriginalCameraModel.K3);
		FVector2f TangentialDistortionCoefsValue(
			CompiledCameraModel.OriginalCameraModel.P1,
			CompiledCameraModel.OriginalCameraModel.P2);

		SetShaderValue(RHICmdList, ShaderRHI, PixelUVSize, PixelUVSizeValue);
		SetShaderValue(RHICmdList, ShaderRHI, DistortedCameraMatrix, FVector4f(CompiledCameraModel.DistortedCameraMatrix));
		SetShaderValue(RHICmdList, ShaderRHI, UndistortedCameraMatrix, FVector4f(CompiledCameraModel.UndistortedCameraMatrix));
		SetShaderValue(RHICmdList, ShaderRHI, RadialDistortionCoefs, RadialDistortionCoefsValue);
		SetShaderValue(RHICmdList, ShaderRHI, TangentialDistortionCoefs, TangentialDistortionCoefsValue);
		SetShaderValue(RHICmdList, ShaderRHI, OutputMultiplyAndAdd, FVector2f(CompiledCameraModel.OutputMultiplyAndAdd));
	}

private:
	
	LAYOUT_FIELD(FShaderParameter, PixelUVSize);
	LAYOUT_FIELD(FShaderParameter, RadialDistortionCoefs);
	LAYOUT_FIELD(FShaderParameter, TangentialDistortionCoefs);
	LAYOUT_FIELD(FShaderParameter, DistortedCameraMatrix);
	LAYOUT_FIELD(FShaderParameter, UndistortedCameraMatrix);
	LAYOUT_FIELD(FShaderParameter, OutputMultiplyAndAdd);
};

实现像素着色器和顶点着色器

class FLensDistortionUVGenerationVS : public FLensDistortionUVGenerationShader
{
	DECLARE_SHADER_TYPE(FLensDistortionUVGenerationVS, Global);
public:

	/** Default constructor. */
	FLensDistortionUVGenerationVS() {}

	/** Initialization constructor. */
	FLensDistortionUVGenerationVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
		: FLensDistortionUVGenerationShader(Initializer)
	{
	}
};

class FLensDistortionUVGenerationPS : public FLensDistortionUVGenerationShader
{
	DECLARE_SHADER_TYPE(FLensDistortionUVGenerationPS, Global);
public:

	/** Default constructor. */
	FLensDistortionUVGenerationPS() {}

	/** Initialization constructor. */
	FLensDistortionUVGenerationPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
		: FLensDistortionUVGenerationShader(Initializer)
	{ }
};

GPU中更新数据

数据传递CPU->GPU
DrawUVDisplacementToRenderTarget_RenderThread
void FFooCameraModel::DrawUVDisplacementToRenderTarget2(
	UWorld* World,
	float DistortedHorizontalFOV,
	float DistortedAspectRatio,
	float UndistortOverscanFactor,
	UTextureRenderTarget2D* OutputRenderTarget,
	float OutputMultiply,
	float OutputAdd) const
{
	check(IsInGameThread());

	if (!OutputRenderTarget)
	{
		FMessageLog("Blueprint").Warning(LOCTEXT("LensDistortionCameraModel_OutputTargetRequired", "DrawUVDisplacementToRenderTarget: Output render target is required."));
		return;
	}

	// Compiles the camera model to know the overscan scale factor.
	float TanHalfUndistortedHorizontalFOV = FMath::Tan(DistortedHorizontalFOV * 0.5f) * UndistortOverscanFactor;
	float TanHalfUndistortedVerticalFOV = TanHalfUndistortedHorizontalFOV / DistortedAspectRatio;

	// Output.
	FCompiledCameraModel CompiledCameraModel;
	CompiledCameraModel.OriginalCameraModel = *this;

	CompiledCameraModel.DistortedCameraMatrix.X = 1.0f / TanHalfUndistortedHorizontalFOV;
	CompiledCameraModel.DistortedCameraMatrix.Y = 1.0f / TanHalfUndistortedVerticalFOV;
	CompiledCameraModel.DistortedCameraMatrix.Z = 0.5f;
	CompiledCameraModel.DistortedCameraMatrix.W = 0.5f;

	CompiledCameraModel.UndistortedCameraMatrix.X = F.X;
	CompiledCameraModel.UndistortedCameraMatrix.Y = F.Y * DistortedAspectRatio;
	CompiledCameraModel.UndistortedCameraMatrix.Z = C.X;
	CompiledCameraModel.UndistortedCameraMatrix.W = C.Y;

	CompiledCameraModel.OutputMultiplyAndAdd.X = OutputMultiply;
	CompiledCameraModel.OutputMultiplyAndAdd.Y = OutputAdd;

	const FName TextureRenderTargetName = OutputRenderTarget->GetFName();
	FTextureRenderTargetResource* TextureRenderTargetResource = OutputRenderTarget->GameThread_GetRenderTargetResource();

	ERHIFeatureLevel::Type FeatureLevel = World->Scene->GetFeatureLevel();

	if (FeatureLevel < ERHIFeatureLevel::SM5)
	{
		FMessageLog("Blueprint").Warning(LOCTEXT("LensDistortionCameraModel_SM5Unavailable", "DrawUVDisplacementToRenderTarget: Requires RHIFeatureLevel::SM5 which is unavailable."));
		return;
	}

	ENQUEUE_RENDER_COMMAND(CaptureCommand)(
		[CompiledCameraModel, TextureRenderTargetResource, TextureRenderTargetName, FeatureLevel](FRHICommandListImmediate& RHICmdList)
		{
			DrawUVDisplacementToRenderTarget_RenderThread(
				RHICmdList,
				CompiledCameraModel,
				TextureRenderTargetName,
				TextureRenderTargetResource,
				FeatureLevel);
		}
	);
}

构建渲染管道流程

  • 渲染管道流程
  • 数据传递
  • FGraphicsPipelineStateInitializer GraphicsPSOInit;
  • VertexShader->SetParameters(RHICmdList, VertexShader.GetVertexShader(), CompiledCameraModel, DisplacementMapResolution);
  • PixelShader->SetParameters(RHICmdList, PixelShader.GetPixelShader(), CompiledCameraModel, DisplacementMapResolution);
static void DrawUVDisplacementToRenderTarget_RenderThread(
	FRHICommandListImmediate& RHICmdList,
	const FCompiledCameraModel& CompiledCameraModel,
	const FName& TextureRenderTargetName,
	FTextureRenderTargetResource* OutTextureRenderTargetResource,
	ERHIFeatureLevel::Type FeatureLevel)
{
	check(IsInRenderingThread());

#if WANTS_DRAW_MESH_EVENTS
	FString EventName;
	TextureRenderTargetName.ToString(EventName);
	SCOPED_DRAW_EVENTF(RHICmdList, SceneCapture, TEXT("LensDistortionDisplacementGeneration %s"), *EventName);
#else
	SCOPED_DRAW_EVENT(RHICmdList, DrawUVDisplacementToRenderTarget_RenderThread);
#endif

	FRHITexture2D* RenderTargetTexture = OutTextureRenderTargetResource->GetRenderTargetTexture();

	RHICmdList.Transition(FRHITransitionInfo(RenderTargetTexture, ERHIAccess::SRVMask, ERHIAccess::RTV));

	FRHIRenderPassInfo RPInfo(RenderTargetTexture, ERenderTargetActions::DontLoad_Store);
	RHICmdList.BeginRenderPass(RPInfo, TEXT("DrawUVDisplacement"));
	{
		FIntPoint DisplacementMapResolution(OutTextureRenderTargetResource->GetSizeX(), OutTextureRenderTargetResource->GetSizeY());

		// Update viewport.
		RHICmdList.SetViewport(
			0, 0, 0.f,
			DisplacementMapResolution.X, DisplacementMapResolution.Y, 1.f);

		// Get shaders.
		FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(FeatureLevel);
		TShaderMapRef< FLensDistortionUVGenerationVS > VertexShader(GlobalShaderMap);
		TShaderMapRef< FLensDistortionUVGenerationPS > PixelShader(GlobalShaderMap);

		// Set the graphic 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 = GetVertexDeclarationFVector4();
		GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader();
		GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader();
		SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit, 0);

		// Update viewport.
		RHICmdList.SetViewport(
			0, 0, 0.f,
			OutTextureRenderTargetResource->GetSizeX(), OutTextureRenderTargetResource->GetSizeY(), 1.f);

		// Update shader uniform parameters.
		VertexShader->SetParameters(RHICmdList, VertexShader.GetVertexShader(), CompiledCameraModel, DisplacementMapResolution);
		PixelShader->SetParameters(RHICmdList, PixelShader.GetPixelShader(), CompiledCameraModel, DisplacementMapResolution);

		// Draw grid.
		uint32 PrimitiveCount = kGridSubdivisionX * kGridSubdivisionY * 2;
		RHICmdList.DrawPrimitive(0, PrimitiveCount, 1);
	}
	RHICmdList.EndRenderPass();

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

相关推荐

  1. UE5 全局着色数据更新流程

    2023-12-10 11:10:03       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-10 11:10:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-10 11:10:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-10 11:10:03       82 阅读
  4. Python语言-面向对象

    2023-12-10 11:10:03       91 阅读

热门阅读

  1. Python——lambda匿名函数

    2023-12-10 11:10:03       59 阅读
  2. 第二十九章 控制到 XML 模式的映射 - 类名列表

    2023-12-10 11:10:03       45 阅读
  3. Linux centos7 扩展磁盘

    2023-12-10 11:10:03       50 阅读
  4. vue中的拖拽事件

    2023-12-10 11:10:03       58 阅读
  5. Let和Var的区别

    2023-12-10 11:10:03       56 阅读
  6. 项目记录:跨域问题解决方案

    2023-12-10 11:10:03       59 阅读