The graphics world has pretty much gone all in on shaders as the foundation of modern graphics hardware. DirectX, OpenGL/Vulkan and Metal all take a shader-centric approach to the graphics pipeline. Unfortunately each has a different shader language! DirectX uses HLSL, OpenGL uses GLSL while Metal uses MSL. Each is very similar yet quite different. So, what does this mean for game developers, especially those responsible for developing renderers? Well it means one of three things.
- you pick a single renderer and develop for it exclusively
- you create multiple “back ends” for each rendering architecture
- you create a tool to translate between them
The last option is exactly what Unity have done. Built on top of HLSLCrossCompiler developed by James Jones, they created HLSLcc which as of today is available for download on Github. Essentially its a C++ library that takes HLSL byte code and translates it to GLSL, GLSL ES, Vulkan and/or Metal format.
From the GitHub readme:
This library takes DirectX bytecode as input, and translates it into the following languages:
- GLSL (OpenGL 3.2 and later)
- GLSL ES (OpenGL ES 3.0 and later)
- GLSL for Vulkan consumption (as input for Glslang to generate SPIR-V)
- Metal Shading Language
This library is used to generate all shaders in Unity for OpenGL, OpenGL ES 3.0+, Metal and Vulkan.
Changes from original HLSLCrossCompiler:
- Codebase changed to C++11, with major code reorganizations.
- Support for multiple language output backends (currently ToGLSL and ToMetal)
- Metal language output support
- Temp register type analysis: In DX bytecode the registers are typeless 32-bit 4-vectors. We do code analysis to infer the actual data types (to prevent the need for tons of bitcasts).
- Loop transformation: Detect constructs that look like for-loops and transform them back to their original form
- Support for partial precision variables in HLSL (min16float etc). Do extra analysis pass to infer the intended precision of samplers.
- Reflection interface to retrieve the shader inputs and their types.
- Lots of workarounds for various driver/shader compiler bugs.
- Lots of minor fixes and improvements for correctness
- Lots of Unity-specific tweaks to allow extending HLSL without having to change the D3D compiler itself.
The code is released under the MIT license make it free and open to use by just about everybody.