vault backup: 2024-02-06 20:08:30
This commit is contained in:
parent
67a7f200b8
commit
cb4b81260a
@ -661,4 +661,236 @@ private:
|
||||
上面展示了Vertex Factory的很多类型,有好几个是核心类,比如FVertexFactory、FVertexElement、FRHIVertexDeclaration、FRHIVertexBuffer、FVertexFactoryType、FVertexStreamComponent、FVertexInputStream、FVertexFactoryShaderParameters等。那么它们之间的关系是什么呢?
|
||||
|
||||
为了更好地说明它们之间的关系,以静态模型的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