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序列化流程的主要内容,如果未能解决你的问题,请参考以下文章