vault backup: 2024-02-06 20:08:30
This commit is contained in:
parent
67a7f200b8
commit
cb4b81260a
@ -662,3 +662,235 @@ private:
|
|||||||
|
|
||||||
为了更好地说明它们之间的关系,以静态模型的FStaticMeshDataType为例:
|
为了更好地说明它们之间的关系,以静态模型的FStaticMeshDataType为例:
|
||||||
![[UE_VertexFactory_FStaticMeshDataType.jpg]]
|
![[UE_VertexFactory_FStaticMeshDataType.jpg]]
|
||||||
|
FStaticMeshDataType会包含若干个FVertexStreamComponent实例,每个FVertexStreamComponent包含了一个在**FVertexDeclarationElementList**的**FVertexElement实例索引**和一个在**FVertexInputStreamArray**列表的**FVertexStream实例索引**。
|
||||||
|
此外,FVertexFactory是个基类,内置的子类主要有:
|
||||||
|
- FGeometryCacheVertexVertexFactory:几何缓存顶点的顶点工厂,常用于预生成的布料、动作等网格类型。
|
||||||
|
- FGPUBaseSkinVertexFactory:GPU蒙皮骨骼网格的父类,它的子类有:
|
||||||
|
- TGPUSkinVertexFactory:可指定骨骼权重方式的GPU蒙皮的顶点工厂。
|
||||||
|
- FLocalVertexFactory:局部顶点工厂,常用于**静态网格**,它拥有**数量较多的子类**:
|
||||||
|
- FInstancedStaticMeshVertexFactory:实例化的静态网格顶点工厂。
|
||||||
|
- FSplineMeshVertexFactory:样条曲线网格顶点工厂。
|
||||||
|
- FGeometryCollectionVertexFactory:几何收集顶点工厂。
|
||||||
|
- FGPUSkinPassthroughVertexFactory:启用了Skin Cache模式的蒙皮骨骼顶点工厂。
|
||||||
|
- FSingleTriangleMeshVertexFactory:单个三角形网格的顶点工厂,用于体积云渲染。
|
||||||
|
- ......
|
||||||
|
- FParticleVertexFactoryBase:用于粒子渲染的顶点工厂基类。
|
||||||
|
- FLandscapeVertexFactory:用于渲染地形的顶点工厂。
|
||||||
|
|
||||||
|
除了以上继承自FVertexFactory,还有一些不是继承自FVertexFactory的类型,如:
|
||||||
|
- FGPUBaseSkinAPEXClothVertexFactory:布料顶点工厂。
|
||||||
|
- TGPUSkinAPEXClothVertexFactory:可带骨骼权重模式的布料顶点工厂。
|
||||||
|
|
||||||
|
除了FVertexFactory,相应的其它核心类也有继承体系。比如FVertexFactoryShaderParameters的子类有:
|
||||||
|
- FGeometryCacheVertexFactoryShaderParameters
|
||||||
|
- FGPUSkinVertexFactoryShaderParameters
|
||||||
|
- FMeshParticleVertexFactoryShaderParameters
|
||||||
|
- FParticleSpriteVertexFactoryShaderParameters
|
||||||
|
- FGPUSpriteVertexFactoryShaderParametersVS
|
||||||
|
- FGPUSpriteVertexFactoryShaderParametersPS
|
||||||
|
- FSplineMeshVertexFactoryShaderParameters
|
||||||
|
- FLocalVertexFactoryShaderParametersBase
|
||||||
|
- FLandscapeVertexFactoryVertexShaderParameters
|
||||||
|
- FLandscapeVertexFactoryPixelShaderParameters
|
||||||
|
- ......
|
||||||
|
|
||||||
|
另外,有部分顶点工厂还会在内部派生FStaticMeshDataType的类型,以复用静态网格相关的数据成员。为了更好地说明顶点工厂的使用方式,下面就以最常见的FLocalVertexFactory和使用了FLocalVertexFactory的CableComponent为例:
|
||||||
|
```c++
|
||||||
|
|
||||||
|
class ENGINE_API FLocalVertexFactory : public FVertexFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FLocalVertexFactory(ERHIFeatureLevel::Type InFeatureLevel, const char* InDebugName);
|
||||||
|
|
||||||
|
// 派生自FStaticMeshDataType的数据类型.
|
||||||
|
struct FDataType : public FStaticMeshDataType
|
||||||
|
{
|
||||||
|
FRHIShaderResourceView* PreSkinPositionComponentSRV = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 环境变量更改和校验.
|
||||||
|
static bool ShouldCompilePermutation(const FVertexFactoryShaderPermutationParameters& Parameters);
|
||||||
|
static void ModifyCompilationEnvironment(const FVertexFactoryShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment);
|
||||||
|
static void ValidateCompiledResult(const FVertexFactoryType* Type, EShaderPlatform Platform, const FShaderParameterMap& ParameterMap, TArray<FString>& OutErrors);
|
||||||
|
|
||||||
|
// 由TSynchronizedResource从游戏线程更新而来的数据.
|
||||||
|
void SetData(const FDataType& InData);
|
||||||
|
// 从其它顶点工厂复制数据.
|
||||||
|
void Copy(const FLocalVertexFactory& Other);
|
||||||
|
|
||||||
|
// FRenderResource接口.
|
||||||
|
virtual void InitRHI() override;
|
||||||
|
virtual void ReleaseRHI() override
|
||||||
|
{
|
||||||
|
UniformBuffer.SafeRelease();
|
||||||
|
FVertexFactory::ReleaseRHI();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 顶点颜色接口.
|
||||||
|
void SetColorOverrideStream(FRHICommandList& RHICmdList, const FVertexBuffer* ColorVertexBuffer) const;
|
||||||
|
void GetColorOverrideStream(const FVertexBuffer* ColorVertexBuffer, FVertexInputStreamArray& VertexStreams) const;
|
||||||
|
|
||||||
|
// 着色器参数和其它数据接口.
|
||||||
|
inline FRHIShaderResourceView* GetPositionsSRV() const;
|
||||||
|
inline FRHIShaderResourceView* GetPreSkinPositionSRV() const;
|
||||||
|
inline FRHIShaderResourceView* GetTangentsSRV() const;
|
||||||
|
inline FRHIShaderResourceView* GetTextureCoordinatesSRV() const;
|
||||||
|
inline FRHIShaderResourceView* GetColorComponentsSRV() const;
|
||||||
|
inline const uint32 GetColorIndexMask() const;
|
||||||
|
inline const int GetLightMapCoordinateIndex() const;
|
||||||
|
inline const int GetNumTexcoords() const;
|
||||||
|
FRHIUniformBuffer* GetUniformBuffer() const;
|
||||||
|
|
||||||
|
(......)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// 从游戏线程传入的数据. FDataType是FStaticMeshDataType的子类.
|
||||||
|
FDataType Data;
|
||||||
|
// 局部顶点工厂的着色器参数.
|
||||||
|
TUniformBufferRef<FLocalVertexFactoryUniformShaderParameters> UniformBuffer;
|
||||||
|
// 顶点颜色流索引.
|
||||||
|
int32 ColorStreamIndex;
|
||||||
|
|
||||||
|
(......)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Engine\Source\Runtime\Engine\Public\LocalVertexFactory.cpp
|
||||||
|
void FLocalVertexFactory::InitRHI()
|
||||||
|
{
|
||||||
|
// 是否使用gpu场景.
|
||||||
|
const bool bCanUseGPUScene = UseGPUScene(GMaxRHIShaderPlatform, GMaxRHIFeatureLevel);
|
||||||
|
|
||||||
|
// 初始化位置流和位置声明.
|
||||||
|
if (Data.PositionComponent.VertexBuffer != Data.TangentBasisComponents[0].VertexBuffer)
|
||||||
|
{
|
||||||
|
// 增加顶点声明.
|
||||||
|
auto AddDeclaration = [this, bCanUseGPUScene](EVertexInputStreamType InputStreamType, bool bAddNormal)
|
||||||
|
{
|
||||||
|
// 顶点流元素.
|
||||||
|
FVertexDeclarationElementList StreamElements;
|
||||||
|
StreamElements.Add(AccessStreamComponent(Data.PositionComponent, 0, InputStreamType));
|
||||||
|
|
||||||
|
bAddNormal = bAddNormal && Data.TangentBasisComponents[1].VertexBuffer != NULL;
|
||||||
|
if (bAddNormal)
|
||||||
|
{
|
||||||
|
StreamElements.Add(AccessStreamComponent(Data.TangentBasisComponents[1], 2, InputStreamType));
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8 TypeIndex = static_cast<uint8>(InputStreamType);
|
||||||
|
PrimitiveIdStreamIndex[TypeIndex] = -1;
|
||||||
|
if (GetType()->SupportsPrimitiveIdStream() && bCanUseGPUScene)
|
||||||
|
{
|
||||||
|
// When the VF is used for rendering in normal mesh passes, this vertex buffer and offset will be overridden
|
||||||
|
StreamElements.Add(AccessStreamComponent(FVertexStreamComponent(&GPrimitiveIdDummy, 0, 0, sizeof(uint32), VET_UInt, EVertexStreamUsage::Instancing), 1, InputStreamType));
|
||||||
|
PrimitiveIdStreamIndex[TypeIndex] = StreamElements.Last().StreamIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化声明.
|
||||||
|
InitDeclaration(StreamElements, InputStreamType);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 增加PositionOnly和PositionAndNormalOnly两种顶点声明, 其中前者不需要法线.
|
||||||
|
AddDeclaration(EVertexInputStreamType::PositionOnly, false);
|
||||||
|
AddDeclaration(EVertexInputStreamType::PositionAndNormalOnly, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 顶点声明元素列表.
|
||||||
|
FVertexDeclarationElementList Elements;
|
||||||
|
|
||||||
|
// 顶点位置
|
||||||
|
if(Data.PositionComponent.VertexBuffer != NULL)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(Data.PositionComponent,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图元id
|
||||||
|
{
|
||||||
|
const uint8 Index = static_cast<uint8>(EVertexInputStreamType::Default);
|
||||||
|
PrimitiveIdStreamIndex[Index] = -1;
|
||||||
|
if (GetType()->SupportsPrimitiveIdStream() && bCanUseGPUScene)
|
||||||
|
{
|
||||||
|
// When the VF is used for rendering in normal mesh passes, this vertex buffer and offset will be overridden
|
||||||
|
Elements.Add(AccessStreamComponent(FVertexStreamComponent(&GPrimitiveIdDummy, 0, 0, sizeof(uint32), VET_UInt, EVertexStreamUsage::Instancing), 13));
|
||||||
|
PrimitiveIdStreamIndex[Index] = Elements.Last().StreamIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切线和法线, 切线法线才需要被顶点流使用, 副法线由shader生成.
|
||||||
|
uint8 TangentBasisAttributes[2] = { 1, 2 };
|
||||||
|
for(int32 AxisIndex = 0;AxisIndex < 2;AxisIndex++)
|
||||||
|
{
|
||||||
|
if(Data.TangentBasisComponents[AxisIndex].VertexBuffer != NULL)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(Data.TangentBasisComponents[AxisIndex],TangentBasisAttributes[AxisIndex]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Data.ColorComponentsSRV == nullptr)
|
||||||
|
{
|
||||||
|
Data.ColorComponentsSRV = GNullColorVertexBuffer.VertexBufferSRV;
|
||||||
|
Data.ColorIndexMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 顶点颜色
|
||||||
|
ColorStreamIndex = -1;
|
||||||
|
if(Data.ColorComponent.VertexBuffer)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(Data.ColorComponent,3));
|
||||||
|
ColorStreamIndex = Elements.Last().StreamIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FVertexStreamComponent NullColorComponent(&GNullColorVertexBuffer, 0, 0, VET_Color, EVertexStreamUsage::ManualFetch);
|
||||||
|
Elements.Add(AccessStreamComponent(NullColorComponent, 3));
|
||||||
|
ColorStreamIndex = Elements.Last().StreamIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 纹理坐标
|
||||||
|
if(Data.TextureCoordinates.Num())
|
||||||
|
{
|
||||||
|
const int32 BaseTexCoordAttribute = 4;
|
||||||
|
for(int32 CoordinateIndex = 0;CoordinateIndex < Data.TextureCoordinates.Num();CoordinateIndex++)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(
|
||||||
|
Data.TextureCoordinates[CoordinateIndex],
|
||||||
|
BaseTexCoordAttribute + CoordinateIndex
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 CoordinateIndex = Data.TextureCoordinates.Num(); CoordinateIndex < MAX_STATIC_TEXCOORDS / 2; CoordinateIndex++)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(
|
||||||
|
Data.TextureCoordinates[Data.TextureCoordinates.Num() - 1],
|
||||||
|
BaseTexCoordAttribute + CoordinateIndex
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 光照图
|
||||||
|
if(Data.LightMapCoordinateComponent.VertexBuffer)
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(Data.LightMapCoordinateComponent,15));
|
||||||
|
}
|
||||||
|
else if(Data.TextureCoordinates.Num())
|
||||||
|
{
|
||||||
|
Elements.Add(AccessStreamComponent(Data.TextureCoordinates[0],15));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化顶点声明
|
||||||
|
InitDeclaration(Elements);
|
||||||
|
|
||||||
|
const int32 DefaultBaseVertexIndex = 0;
|
||||||
|
const int32 DefaultPreSkinBaseVertexIndex = 0;
|
||||||
|
if (RHISupportsManualVertexFetch(GMaxRHIShaderPlatform) || bCanUseGPUScene)
|
||||||
|
{
|
||||||
|
SCOPED_LOADTIMER(FLocalVertexFactory_InitRHI_CreateLocalVFUniformBuffer);
|
||||||
|
UniformBuffer = CreateLocalVFUniformBuffer(this, Data.LODLightmapDataIndex, nullptr, DefaultBaseVertexIndex, DefaultPreSkinBaseVertexIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现FLocalVertexFactory的参数类型.
|
||||||
|
IMPLEMENT_VERTEX_FACTORY_PARAMETER_TYPE(FLocalVertexFactory, SF_Vertex, FLocalVertexFactoryShaderParameters);
|
||||||
|
|
||||||
|
// 实现FLocalVertexFactory.
|
||||||
|
IMPLEMENT_VERTEX_FACTORY_TYPE_EX(FLocalVertexFactory,"/Engine/Private/LocalVertexFactory.ush",true,true,true,true,true,true,true);
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user