UE4-Loading时材质Shader序列化流程

Posted RapdoZoro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4-Loading时材质Shader序列化流程相关的知识,希望对你有一定的参考价值。

文章为本人学习虚幻4引擎源码所整理笔记,如有纰漏欢迎指正交流。 Ar.IsLoading( )时: 完成将材质所有MaterialResource的MaterialShaderMap实例化; 完成MaterialShaderMap实例中的 MeshShaderMaps、 OrderedMeshShaderMaps初始化; 完成所有Shader 序列化(遍历所有 MeshShaderMaps,序列化好的Shader存到SerializedShaders、SerializedShaderPipelines中供后续注册使用 )。

1.异步加载材质序列化导出,最终调用void UMaterial::Serialize(FArchive& Ar) ,对每个材质进行序列化:   (Material.cpp)

调用顺序:

-> FAsyncLoadingThread::ProcessAsyncLoading( )                       ---AsyncLoading.cpp

-> FAsyncLoadEventQueue::PopAndExecute( )                             ---AsyncLoadingThread.h

-> void FAsyncPackage::Event_ProcessImportsAndExports( )       ---AsyncLoading.cpp

-> FAsyncPackage::ProcessImportsAndExports_Event( )               ---AsyncLoading.cpp

-> void FAsyncPackage::EventDrivenSerializeExport( )                  ---AsyncLoading.cpp

-> void UMaterial::Serialize(FArchive& Ar)                                     ---Material.cpp

 LoadedMaterialResources为UMaterial成员变量,一个材质会对应多个MaterialResource,注意这里是UMaterial:

2.在对每个材质的序列化其ShaderMaps中时,其实是对该材质的所有MaterialResource序列化到ShaderMap中:  (Material.cpp)

3.FMaterial::SerializeInlineShaderMap(FArchive& Ar),完成了对该材质序列化到ShaderMap中,并最终赋值改游戏线程的GameThreadShaderMap及渲染线程的RenderingThreadShaderMap,

  注意这里是FMaterial,FMaterialResource继承自FMaterial:                      (MaterialShared.cpp)

GameThreadShaderMap及RenderingThreadShaderMap是FMaterial成员变量: (MaterialShared.h)

4.进一步在中看看具体是怎样序列化的,在FMaterialShaderMap::Serialize()方法的Ar.IsLoading()部分:  MaterialShader.cpp 1).一个MaterialShaderMap实例含有多个MeshShaderMap,根据VFType存放在MeshShaderMaps和OrderedMeshShaderMaps中; 2).清空MeshShaderMaps,然后遍历所有VertexFactoryType对MeshShaderMaps赋值(此时尚未初始化Shader); 3).利用MeshShaderMaps初始化OrderedMeshShaderMaps(具体看FMaterialShaderMap::InitOrderedMeshShaderMaps()方法实现),   OrderedMeshShaderMaps和MeshShaderMaps存的其实是同一份MeshShaderMap,OrderedMeshShaderMaps便于通过VertexFactoryType快速查找对应的MeshShaderMap; 4).遍历所有OrderedMeshShaderMaps中的MeshShaderMap,执行真正的序列化实现SerializeInline(); *在该方法的Ar.IsSaving()部分,会先执行SerializeInline(),再执行RegisterSerializedShaders(),注册序列化好的所有MeshShaderMap。 5.在每个MeshShaderMap初始化时,具体执行如下:  (Shader.h 1).根据所有FShaderType序列化所有Shader并储存在SerializedShaders中; 2).根据所有FShaderPipelineType序列化所有Shader并储存在SerializedShaderPipelines中; 3).SerializedShaders、SerializedShaderPipelines为TShaderMap的成员变量; 4).FMeshMaterialShaderMap继承自TShaderMap; 6.上面对每个MeshShaderMap的每个Shader进行序列化时,调用FShader* SerializeShaderForLoad( )方法,进而调用FShader::SerializeBase( )方法:  (Shader.h

7.在FShader::SerializeBase( )方法中,真正执行了对每个Shader的序列化,

包括序列化出Shader的OutputHash、MaterialShaderMapHash、ShaderPipeline、VFType、VFSourceHash、Type、SourceHash、Target等;

另外还对ShaderResource进行了序列化并存到了SerializedResource中供后续ShaderResource注册使用。   (Shader.cpp)

FShader成员:

!!!序列化好的SerializedShaders、SerializedShaderPipelines的使用时机在后续,遍历SerializedShaders、SerializedShaderPipelines,注册到Shaders、ShaderPipelines中。

以上类的对应关系为:

一个UMaterial对应多个FMaterialResource(根据MaterialQualityLevel和RHIFeatureLevel两个key),

一个FMaterialResource对应一个FMaterialShaderMap,

一个FMaterialShaderMap对应多个FMeshMaterialShaderMap(根据VertexFactoryType),

一个FMeshMaterialShaderMap对应多个Shader(根据ShaderType)

以上是关于UE4-Loading时材质Shader序列化流程的主要内容,如果未能解决你的问题,请参考以下文章

UE4-Loading时材质Shader序列化流程

Unity Shader入门精要学习笔记 - 第3章 Unity Shader 基础

unityshader怎样赋予材质球

UE4-注册已序列化Shader流程

UE4-注册已序列化Shader流程

unity之PBR材质流程与材质制作实践