1、ShaderLab构成
(1)ShaderLab Text:Shader编码
(2)Shader Compiler
包含Preprocess和Binary Compile过程
(3)ShaderLab Asset
编译后生成的文件
(4)ShaderLab Runtime
负责运行时Shader解析工作
2、ShaderLab工作流
(1)如图2-1,Editor下Shader Compiler会对ShaderLab代码进行预处理生成Shader Compilation Info(中间信息集,包含变体等信息),然后Shader Compilation Info经过序列化写入Libarary/ShaderCache文件下。
PreProcess过程包含语法解析、词法解析、提取不同语言的片段并使用对应语言的编译器解析。
(2)Editor下运行或打包时,Shader Compiler通过Binary Compile根据第一步生成的信息生成Shader Asset。
其中Binary Compile为了平台兼容性和实现简便性会进行两步编译,首先使用d3dcompiler将源Shader语言编译成DXBC,然后使用改进的HLSLCC将DXBC编译成目标平台对应的Shader。Unity2020版本后为了提高扩展性,将DXBC替换成DXIL
图2-3是知乎上一大神总结的Unity中Shader编译流程。
(3)真机Runtime加载Shader
如图2-4,当需要某个shader时,Unity的Persitent Manager会先创建一个Shader Class Instance的壳,然后调用Transfer Function将Shader Asset中存储的shader数据反序列化填充Shader Class Instance,全部数据加载好后再从主线程唤醒进行数据处理。
(4)WarmUp
如图2-5,当我们WarmUp一个Shader变体时,会对所有的Shader Variant进行打分,最后返回一个分数最高的变体。
如图2-6,Unity中Warmup一个变体时,CPU内存中存储的Code Data会被加载到GPU中处理,CPU中占用的内存会被Unity清除。