在UE5管线中添加global view数据贴图

FViewUniformShaderParameters

= C++ 侧定义的 View 参数结构

View

= shader 里绑定出来的 uniform buffer 变量名

View.xxx

= 访问 FViewUniformShaderParameters 里的某个字段

你这次做的链路是:

Engine.h

保存 UTexture2D 资源和 ini 配置路径

UnrealEngine.cpp

引擎启动时根据 MyGlobalTextureName 加载贴图

SceneView.h

在 FViewUniformShaderParameters 里声明 MyGlobalTexture / Sampler

SceneRendering.cpp

把 GEngine->MyGlobalTexture 的 TextureRHI 塞进 ViewUniformShaderParameters

材质 Custom 节点 / shader

用 View.MyGlobalTexture 采样


第 1 步:在 View 里声明贴图

打开:

SceneView.h (line 1119)

找到:

复制代码
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT_WITH_CONSTRUCTOR(FViewUniformShaderParameters, ENGINE_API)

在里面加:

复制代码
SHADER_PARAMETER_TEXTURE(Texture2D, XSJ3DSDFTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, XSJ3DSDFTextureSampler)
SHADER_PARAMETER(FVector4f, XSJ3DSDFTextureSizeAndInvSize)

首先FViewUniformShaderParameters 是View变量的类型是 View 这个变量背后的数据结构

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT_WITH_CONSTRUCTOR(...)

意思是:

开始定义一个全局 shader parameter struct,并且这个 struct 带构造函数。

这个 struct 里的成员会被 Unreal 传到 GPU shader 里。

而且本质上就是同一类东西:shader 参数绑定

Compute Shader 里你可能见过这种:

BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER(float, MyValue) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, MyTexture) SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutputTexture) END_SHADER_PARAMETER_STRUCT()
也是参数绑定


第 2 步:给 Engine 加一个贴图资源变量

打开:

Engine.h (line 1406)

UEngine 正好就是 Unreal 已经用来保存这类"全局引擎资源"的地方。

UPROPERTY() TObjectPtr<class UTexture2D> MyGlobalTexture;

UPROPERTY(globalconfig) FSoftObjectPath MyGlobalTextureName;

然后在函数声明区域,加:

ENGINE_API void ConditionallyLoadMyGlobalTexture();

UPROPERTY(globalconfig)作用是:

让你能在 ini 里配置贴图路径:

MyGlobalTextureName=/Game/YourFolder/T_3DSDF.T_3DSDF

作用是:保存已经加载出来的贴图对象。

也就是之后 C++ 可以访问:

GEngine->MyGlobalTexture


第 3 步:实现加载函数

打开:

UnrealEngine.cpp (line 3591)

void UEngine::ConditionallyLoadMyGlobalTexture()
{``
if (MyGlobalTexture == nullptr && MyGlobalTextureName.IsValid())
{``
LoadEngineTexture(MyGlobalTexture, *MyGlobalTextureName.ToString());
}
}

然后在初始化加载贴图的地方,找到:

void UEngine::InitializeObjectReferences()

后面加:

ConditionallyLoadMyGlobalTexture();

UEngine::InitializeObjectReferences() 的作用是:

在引擎启动时,把一些"引擎默认资源"加载出来,保存到 GEngine 里,后面全局使用。


第 4 步:在 ini 里配置你的贴图路径

打开:

引擎中:BaseEngine.ini 或者 项目中:DefaultEngine.ini

/Script/Engine.Engine 下面加:

MyGlobalTextureName=/Game/YourFolder/T_3DSDF.T_3DSDF

路径换成你的贴图真实路径。

如果你的贴图在项目里,建议放项目的:

YourProject/Config/DefaultEngine.ini

同样写:ini

MyGlobalTextureName=/Game/YourFolder/T_3DSDF.T_3DSDF


第 5 步:把贴图塞进 ViewUniformShaderParameters

打开:

SceneRendering.cpp (line 1295)

找到函数:cpp

void FViewInfo::SetupUniformBufferParameters(...)

加:

复制代码
ViewUniformShaderParameters.MyGlobalTexture = nullptr;
ViewUniformShaderParameters.MyGlobalTextureSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
ViewUniformShaderParameters.GlobalTextureSizeAndInvSize = FVector4f(1.0, 1.0, 1.0, 1.0);

if (GEngine->MyGlobalTexture)
{
	const FTextureResource* TextureResource = GEngine->MyGlobalTexture->GetResource();

	if (TextureResource && TextureResource->TextureRHI)
	{
		ViewUniformShaderParameters.MyGlobalTexture = TextureResource->TextureRHI;

		const FIntVector TextureSize = TextureResource->TextureRHI->GetSizeXYZ();
		ViewUniformShaderParameters.GlobalTextureSizeAndInvSize = FVector4f(
			TextureSize.X,
			TextureSize.Y,
			1.0f / FMath::Max(TextureSize.X, 1),
			1.0f / FMath::Max(TextureSize.Y, 1)
		);
	}
}

ViewUniformShaderParameters.MyGlobalTexture = OrBlack2DIfNull(ViewUniformShaderParameters.MyGlobalTexture);
ViewUniformShaderParameters.MyGlobalTextureSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();

这一步很重要:没有真实贴图时,用黑图兜底,避免 shader 绑定空资源崩掉。

FTextureResource 是 UTexture 和 GPU 纹理之间的桥梁;你要把贴图传给 shader,就需要从 UTexture2D 拿到 FTextureResource,再拿里面的 TextureRHI。

TextureResource->TextureRHI
才是更底层的 RHI 贴图,也就是可以传给 shader 的 GPU 资源。


第 6 步:

在SceneManagement.cpp中的FViewUniformShaderParameters::FViewUniformShaderParameters()新增

MyGlobalTexture = GBlackTexture->TextureRHI;

MyGlobalTextureSampler =

TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();

GlobalTextureSizeAndInvSize = FVector4f(1.0f, 1.0f, 1.0f, 1.0f);

在材质编辑器 Custom 节点里读

材质里加一个 Custom 节点。

类型接 TextureCoordinate。

return Texture2DSample(View.XSJ3DSDFTexture, View.XSJ3DSDFTextureSampler, UV);


结果:


总结:

1、在FViewUniformShaderParameters(View的类型)中加上对应需要的变量

2、在引擎初始化资源的时候CPU段加上对应变量,并在UnrealEngine.cpp中初始化他们

3、初始化成功在SceneRendering内将CPU初始化好的数据给到FViewUniformShaderParameters对应变量

UEngine 在 CPU 侧持有和初始化资源;FViewUniformShaderParameters 声明 View 要暴露给 shader/GPU 的参数;SceneRendering.cpp 在构建 View uniform buffer 时,把 CPU 侧资源对应的 RHI 句柄填进去,让 shader 能通过 View.xxx 访问。

SceneRendering.cpp 可以理解成:每一帧渲染时,CPU 侧负责组织这一帧怎么画的地方

它不是 GPU shader,也不是贴图资产加载代码。它主要做的是:

已有场景数据 + 当前相机/View ↓ 准备本帧 View 参数 ↓ 准备可见性、光照、阴影、材质、后处理等渲染任务 ↓ 把这些任务提交给 RHI / GPU