Uniform Buffer、FVertexFactory、FVertexFactoryType

按照惯例,先自淫一下,宣传下自己的书。

Uniform Buffer对应C++代码里面用BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT_WITH_CONSTRUCTOR或BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT两个宏生成的Shader Parameter,对应为Struct结构。

实现:

IMPLEMENT_GLOBAL_SHADER_PARAMETER_STRUCT(FSkyLightData, "SkyLight");

声明:

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FSkyLightData, )
SHADER_PARAMETER(uint32, SamplesPerPixel)
SHADER_PARAMETER_TEXTURE(Texture2D, SceneColorTexture)
SHADER_PARAMETER(float, MaxRayDistance)
SHADER_PARAMETER(FVector, Color)

END_GLOBAL_SHADER_PARAMETER_STRUCT()

支持的数据类型

它里面可以存放任何类型的数据,资源类型则为指针类型。

加入普通数据类型:

SHADER_PARAMETER(FMatrix,LocalToWorld)
SHADER_PARAMETER_EX(float,DecalReceiverMask,EShaderPrecisionModifier::Half)

加入资源数据类型:

 SHADER_PARAMETER_TEXTURE(Texture2D, SceneColorTexture)
 SHADER_PARAMETER_SAMPLER(SamplerState, SceneColorTextureSampler)
 SHADER_PARAMETER_TEXTURE(Texture2D<float>, SceneDepthTextureNonMS)
 SHADER_PARAMETER_TEXTURE(Texture2D<float4>, GBufferATextureNonMS)
 SHADER_PARAMETER_SRV(Buffer<float4>, VertexFetch_PointColorBuffer)
 SHADER_PARAMETER_SRV(Texture2D<uint2>, CustomStencilTexture)

加入数组类型:

 SHADER_PARAMETER_TEXTURE_ARRAY(Texture2D, Textures, [GMaxLUTBlendCount])
 SHADER_PARAMETER_SAMPLER_ARRAY(SamplerState, Samplers, [GMaxLUTBlendCount])
 SHADER_PARAMETER_ARRAY(float, LUTWeights, [GMaxLUTBlendCount]) 

加入Struct类型

SHADER_PARAMETER_STRUCT_INCLUDE(FLightShaderParameters, LightParameters)

加入UniformBuffer索引

SHADER_PARAMETER_STRUCT_REF(FSkyLightData, SkyLight)

加入Unordered Access View

SHADER_PARAMETER_SRV(RaytracingAccelerationStructure, TLAS)

在Shader中,Uniform Buffer参数可按照Struct方式访问的。在任何一个Shader里面你就可以使用 “SKyLight.Color”。

实现原理

Uniform Buffer是Unreal自己引进的资源类型,没有对应的渲染API的资源。它里面保存的数据会在RHI层解析出来,然后设置到对应的渲染API Slot中。所以RHI层保存了每个Uniform Buffer数据分布情况。

C++层

每次都会创建对应的Struct,填写Struct数据,然后用Struct创建Uniform Buffer,无论成员数据在Shader中是否用到,都会赋值,资源类型为指针类型。

在宏声明中

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FSkyLightData, )

会声明FSkyLightData类,下面接着是它的参数。

在宏实现中

#define IMPLEMENT_GLOBAL_SHADER_PARAMETER_STRUCT(StructTypeName,ShaderVariableName) \
  FShaderParametersMetadata StructTypeName::StaticStructMetadata( \
  FShaderParametersMetadata::EUseCase::GlobalShaderParameterStruct, \
  FName(TEXT(#StructTypeName)), \
  TEXT(#StructTypeName), \
  TEXT(ShaderVariableName), \
  sizeof(StructTypeName), \
 StructTypeName::zzGetMembers())

会定义FSkyLightData类中FShaderParametersMetadata类型的静态全局变量。全局静态变量初始化会先于Main函数,被加入到全局GlobalListLink链表中。

FShaderParametersMetadata类保存着所有成员变量的细节和分布情况。

StructTypeName::zzGetMembers()会递归调用收集所有成员。

Shader层

在编译Shader前,GlobalListLink中保存所有类,生成Shader代码可用的结构体,因为不是所有数据都被用到,编译后,得到的占用Slot情况都是精简后的,数据分布情况保留在RHI层的Shader中。

RHI层

Uniform Buffer进入RHI层,会把Uniform Buffer数据分解出来,根据当前RHI层Shader数据分布情况,设置到对应Slot中。

FVertexFactory

可以得到Vertex Declaration 和Stream

每个Sub Mesh都会new Vertex Factory

FVertexFactoryType

全局唯一静态变量

包含所有和Vertex Shader有关的内容。


FMaterial遍历所有FVertexFactoryType生成所有的Vertex Shader。

通过FMaterial得到对应Vertex Shader。

发布于 2020-07-22 16:55