Shader 交叉编译
Last updated
Last updated
dxc 需要在GitHub上下载,但是我在Windows sdk中也找到了:C:\Program Files (x86)\Windows Kits\10\bin\10.0.20348.0\x64,这里我们是从GitHub上下载下来的。
dxc 把 hlsl 编译成 spir-v 的例子(可以用 dxc.exe -help 查看所有参数):
-Fh 参数可以编译成一个头文件,然后就能直接包含使用了。
直接编译给 D3D12 使用:
我们可以改变头文件的变量名字,并且生成反射文件:
fxc 包含于Windows sdk中,我们直接在 C:\Program Files (x86)\Windows Kits\10\bin\10.0.20348.0\x64 可以拿到。
fxc 是可以支持 SM5.1 的,但是 dx11 似乎只能用到 5.0 ?参见:
https://github.com/KhronosGroup/Vulkan-Guide/blob/main/chapters/hlsl.adoc
https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst
shader编译有离线和在线两种选择,对于dx,可以有三种方法:(参考https://zhuanlan.zhihu.com/p/594417850
离线编译成 cso 字节码, 在程序启动读取 cso 字节码, 创建 pipeline state object
离线编译 .h 文件, 其中有个 unsigned char
的全局变量, 直接 include 对应的文件使用
在程序运行期间编译着色器代码,并读取生成的字节码
一般会有一个uber shader,然后会生成很多变体(例如某项目最终所有的变体加起来有7w个着色器,每个着色器变体都会对应一个pso)。
进一步可以参考:
shader可以指定入口,比如 Test.shader,vertex shader的入口是VS_MAIN,那么可以通过:
这样子,如果是 vs 就在原来的名字后面加尾缀 VS,生成的头文件的变量名也保持一致。
但是这样子产生头文件的方式,代码包含后还得hard code数组的名字才行,就无法自定义一个shader直接拖给材质使用了,因此还是直接生成dxil,然后直接解析文件来的好:
-p:编译指定路径下的所有 hshader 文件(递归搜寻)
-s:编译该shader文件,需要是 .hshader 文件:
需要在文件最顶部指定 shader 类型与入口,例如:
此时dxc会按照vs_6_6编译,fxc按照vs_5_0编译
本人也物色到一个不错的库:https://github.com/GPUOpen-LibrariesAndSDKs/RenderPipelineShaders
是AMD家的,但是我看了一下,协议非常严格,完全不能商用。只能够作为学习参考。