HLSL 跨平台转换方案:GLSL / SPIR-V
August 1, 2025About 2 min
HLSL 跨平台转换方案:GLSL / SPIR-V
把一批 DX11/DX12 的 HLSL shader(SM 5.0/5.1/6.0)移植到只吃 GLSL 4.30+ / SPIR-V 的目标平台时,核心问题是:怎么把 HLSL 翻译成目标平台能接受的着色器语言。这篇比较两条主流方案——直接用工具生成 GLSL 源码,还是先转成 SPIR-V 中间表示再落地。
方案一:用 HLSLcc 生成 GLSL 源码
HLSLcc(MIT license)以 DirectX 字节码为输入,可翻译成:
- GLSL(OpenGL 3.2+)
- GLSL ES(OpenGL ES 3.0+)
- 供 Vulkan 使用的 GLSL(作为 Glslang 的输入生成 SPIR-V)
- Metal Shading Language
Unity 就是用它来生成 OpenGL / OpenGL ES 3.0+ / Metal / Vulkan 的全部 shader。输入是编译后的 DX 字节码,这点对「从帧捕获文件里拿 shader」的场景比较友好——不强依赖 HLSL 源码。
方案二:先转 SPIR-V,再喂给目标平台编译器
先用 DirectXShaderCompiler(DXC)的 SPIR-V CodeGen 或 HLSLcc 生成 SPIR-V 二进制,再把它作为目标平台 GLSL 编译器的输入。
SPIR-V(Standard Portable Intermediate Representation)是 Khronos 的平台无关中间语言,最初为 OpenCL 设计,当前的 SPIR-V 版本在 2015 年 3 月公布。它是一个自包含、完整规格、二进制格式的中间表示,用来表达图形着色阶段和计算内核,跨多个 API。
优点:SPIR-V 平台无关,是主流引擎通用的翻译中转(比如 UE 把 HLSL 编译成 HLIR)。走 SPIR-V 这条中间层,同一套技术就有机会覆盖不同的重放/目标平台(各家主机的图形 API)。
缺点:
- 如果用 DXC 把 HLSL 转 SPIR-V,目前没看到能绕开 HLSL 源码的做法——而 HLSL 源码正是从帧捕获文件里难拿到的东西,这点待进一步调研。
- 目标平台的 GLSL 编译器对 SPIR-V 的支持通常有限制,需要对照该平台 SDK 文档里的 SPIR-V 支持章节逐条确认。
两条路线怎么选
- 只需要 GLSL 源码、且能拿到 DX 字节码 → 方案一(HLSLcc)最直接。
- 想要一套中间表示覆盖多个主机平台、且有 HLSL 源码 → 方案二(SPIR-V)更有扩展性,但要吃下各平台 SPIR-V 支持的限制。