This is a fork of Unknownworld’s hlslparser adapted to our needs in The Witness. We currently use it to translate pseudo-HLSL shaders (using the legacy D3D9 syntax) to HLSL10 and Metal Shading Language (MSL). There’s also a GLSL translator available that we do not use yet, but that is being maintained by community contributions.
The HLSL parser has been extended with many HLSL10 features, but retaining the original HLSL C-based syntax.
For example, the following functions in our HLSL dialect:
float tex2Dcmp(sampler2DShadow s, float3 texcoord_comparevalue); float4 tex2DMSfetch(sampler2DMS s, int2 texcoord, int sample); int2 tex2Dsize(sampler2D s);
Are equivalent to these methods in HLSL10:
float Texture2D::SampleCmp(SamplerComparisonState s, float2 texcoord, float comparevalue); float4 Texture2DMS<float4>::Load(int2 texcoord, int sample); void Texture2D<float4>::GetDimensions(out uint w, out uint h);
Here are the original release notes:
HLSL Parser and GLSL code generator
This is the code we used in Natural Selection 2 to convert HLSL shader code to GLSL for use with OpenGL. The code is pulled from a larger codebase and has some dependencies which have been replaced with stubs. These dependencies are all very basic (array classes, memory allocators, etc.) so replacing them with our own equivalent should be simple if you want to use this code.
The parser is designed to work with HLSL code written in the legacy Direct3D 9 style (e.g. D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY should be used with D3D11). The parser works with cbuffers for uniforms, so in addition to generating GLSL, there is a class provided for generating D3D9-compatible HLSL which doesn’t support cbuffers. The GLSL code requires version 3.1 for support of uniform blocks. The parser is designed to catch all errors and generate “clean” GLSL which can then be compiled without any errors.
The HLSL parsing is done though a basic recursive descent parser coded by hand rather than using a parser generator. We believe makes the code easier to understand and work with.
To get consistent results from Direct3D and OpenGL, our engine renders in OpenGL “upside down”. This is automatically added into the generated GLSL vertex shaders.
Although this code was written specifically for our use, we hope that it may be useful as an educational tool or a base for someone who wants to do something similar.