Why
在原生的 DirectX 开发中,想要给 Shader 传递数据,通常需要使用常量数据 (Constant Buffer / cbuffer)、资源绑定 (SRV / UAV / Sampler),它们的无论在定义阶段还是使用阶段都十分繁琐,为此,虚幻引擎封装了Shader Parameter Struct。
What
Shader Parameter Struct 是虚幻引擎中用于在 CPU(C++ 端) 和 GPU(Shader 端 / USF) 之间传递数据的标准化数据结构。 它通过一组特定的 C++ 宏来定义。这套宏在底层通过编译期元编程,为原本不支持反射的 C++ 结构体生成了静态反射信息(包括变量名、数据类型、内存偏移量等)。
// 声明一个简单的 Shader 参数结构体
BEGIN_SHADER_PARAMETER_STRUCT(结构体名, )
// 普通数据
SHADER_PARAMETER(数据类型, 参数名称)
// RDG 资源 (比如一张输入的贴图和它的采样器)
SHADER_PARAMETER_RDG_TEXTURE(纹理类型, 参数名称)
SHADER_PARAMETER_SAMPLER(采样器类型, 参数名称)
// 输出目标 (Render Target)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()只需要写简单的几行代码,宏在背后就帮你把严格的内存对齐、编译期防呆检查、以及运行时需要的内存布局信息全部打理好了。
How
Unreal Shader File (.usf)
// 这些变量名必须和 C++ 中宏定义的名字一模一样
float4 TintColor;
float Intensity;
Texture2D MyInputTexture;
SamplerState MyTextureSampler;
void MainPS(
in float2 UV : TEXCOORD0,
out float4 OutColor : SV_Target0)
{
float4 TexColor = MyInputTexture.Sample(MyTextureSampler, UV);
OutColor = TexColor * TintColor * Intensity;
}相应的C++定义
BEGIN_SHADER_PARAMETER_STRUCT(FMyTestShaderParameters, )
SHADER_PARAMETER(FVector4f, TintColor)
SHADER_PARAMETER(float, Intensity)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, MyInputTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, MyTextureSampler)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()创建并填充数据
// 1. 获取图构建器
FRDGBuilder& GraphBuilder = ...;
// 2. 分配参数结构体的内存 (必须通过 RDG 分配,不能在栈上自己 new)
FMyTestShaderParameters* PassParameters = GraphBuilder.AllocParameters<FMyTestShaderParameters>();
// 3. 填充数据
PassParameters->TintColor = FVector4f(1.0f, 0.5f, 0.2f, 1.0f);
PassParameters->Intensity = 2.0f;
PassParameters->MyInputTexture = SomeRDGTexture; // 传入你的 RDG 贴图
PassParameters->MyTextureSampler = TStaticSamplerState<SF_Bilinear>::GetRHI();
PassParameters->RenderTargets[0] = FRenderTargetBinding(OutputTexture, ERenderTargetLoadAction::EClear);More
常量数据
这类宏用于传递基础的数值型数据(如标量、向量、矩阵)。在 DirectX 中,UE 会自动将结构体中所有的这些普通参数打包成一个 Constant Buffer(常量缓冲区,CBV)。
| UE 宏定义 | 对应的 DirectX / HLSL 概念 |
|---|---|
SHADER_PARAMETER(Type, Name) |
Constant Buffer (cbuffer) 中的变量。 |
SHADER_PARAMETER_ARRAY(Type, Name, Size) |
Constant Buffer 中的定长数组。 |
注意
在底层,DirectX 不会为每一个 float 或 FMatrix 单独绑定,而是将整个 BEGIN_SHADER_PARAMETER_STRUCT 里的普通参数合并打包,绑定到一个 cbuffer (Constant Buffer View, CBV) 槽位中。
着色器资源视图 (SRV - Shader Resource View)
这类宏用于绑定着色器中只读的资源(贴图、结构化缓冲区等)。
| UE 宏定义 | 对应的 DirectX / HLSL 概念 | 补充说明 |
|---|---|---|
SHADER_PARAMETER_TEXTURE(Type, Name) |
SRV (Texture2D, Texture3D 等) | 非 RDG 管理的常规贴图(通常是常驻内存的全局贴图)。 |
SHADER_PARAMETER_SRV(Type, Name) |
SRV (StructuredBuffer, ByteAddressBuffer) | 非 RDG 管理的只读 Buffer。 |
SHADER_PARAMETER_RDG_TEXTURE(Type, Name) |
SRV (Texture2D 等) | RDG 托管 的贴图。DirectX 层面与普通 SRV 无异,但 C++ 侧 RDG 会自动处理同步、内存复用和资源屏障(Resource Barrier)。 |
SHADER_PARAMETER_RDG_BUFFER_SRV(Type, Name) |
SRV (StructuredBuffer 等) | RDG 托管 的只读 Buffer。 |
SHADER_PARAMETER_RDG_TEXTURE_SRV(Type, Name) |
SRV (Texture2D 等) | 显式绑定一个 RDG 贴图的特定 SRV(比如只读取贴图的某一个 Mip 层)。 |
无序访问视图 (UAV - Unordered Access View)
这类宏用于绑定着色器中可读可写的资源。通常用于 Compute Shader 或 Pixel Shader 中的写入操作。
| UE 宏定义 | 对应的 DirectX / HLSL 概念 | 补充说明 |
|---|---|---|
SHADER_PARAMETER_UAV(Type, Name) |
UAV (RWTexture2D, RWStructuredBuffer) | 非 RDG 管理的读写资源。 |
SHADER_PARAMETER_RDG_BUFFER_UAV(Type, Name) |
UAV (RWStructuredBuffer 等) | RDG 托管 的可读写 Buffer。在 Compute Shader 计算完后,RDG 会自动插入屏障以供后续阶段使用。 |
SHADER_PARAMETER_RDG_TEXTURE_UAV(Type, Name) |
UAV (RWTexture2D 等) | RDG 托管 的可读写贴图。 |
采样器 (Samplers)
用于贴图采样的状态配置(过滤模式、寻址模式等)。
| UE 宏定义 | 对应的 DirectX / HLSL 概念 |
|---|---|
SHADER_PARAMETER_SAMPLER(Type, Name) |
SamplerState。映射到 DirectX 的采样器状态对象(Sampler State Object)。 |
嵌套结构体与 Uniform Buffers
用于将其他数据块复用到当前的参数结构体中。
| UE 宏定义 | 对应的 DirectX / HLSL 概念 |
|---|---|
SHADER_PARAMETER_STRUCT(Type, Name) |
将另一个结构体的参数**内联(Inline)**到当前的 Constant Buffer 中。 |
SHADER_PARAMETER_STRUCT_REF(Type, Name) |
绑定到一个外部独立的 Constant Buffer View (CBV),而不是将数据拷贝进来。 |
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(Type, Name) |
CBV。绑定一个 RDG 生命周期管理的 Uniform Buffer (Constant Buffer)。 |
渲染目标 (Render Targets)
这是 RDG 特有的宏,不对应 HLSL 代码中的变量,而是对应图形渲染管线的输出合并阶段(Output Merger Stage)。
| UE 宏定义 | 对应的 DirectX 概念 |
|---|---|
RENDER_TARGET_BINDING_SLOTS() |
映射到 DirectX 的 RTV (Render Target View) 和 DSV (Depth Stencil View)。在 C++ 层配置渲染通道时,告诉管线像素着色器的输出应该写到哪些缓冲(Color Buffer / Depth Buffer)中。 |