I recently finished writing the DirectX renderer for my game engine. Now I have an OpenGL, DirectX as well as a not yet finished Vulkan renderer.

Well, the majority of the renderers work perfectly now but I have a problem: I need a shader programming language.

The problem is that OpenGL and Vulkan use GLSL but DirectX uses HLSL (and Apple's Metal API uses MSL). So I searched for a High Level Shader Language and found only C for graphics from NVIDIA. But since this project was deprecated I looked for something else: Without success.

It's a bit annoying to write for 3 shader programming languages at the same time, so I'm looking for a language that can be translated into the native language immediately when the game starts (or is simply compatible with a lot of rendering APIs)

After several weeks of finding nothing, I decided to write my own language for it. But before I invest too much time I want to know if there is another solution to this problem.

  • 1
    \$\begingroup\$ Welcome GDSE. If you have additional information that clarifies your question, often times should should also edit your question to include that information directly. The self contained posts are easier to answer and comments are more transitory than edits. \$\endgroup\$
    – Pikalek
    Feb 28 at 16:32
  • \$\begingroup\$ You might be interested in Google/Angle. \$\endgroup\$
    – Theraot
    Feb 28 at 20:42
  • \$\begingroup\$ Vulkan doesn't use GLSL but SPIR-V. There is a tool suite which among other useful things contains an offline SPIR-V reference compiler called glslangValidator. No idea about DirectX though. \$\endgroup\$
    – user144188
    Mar 2 at 10:33

This problem is often solved through the use of a transpiler, a program that can translate a shader written in one language into another.

HLSL2GLSL is one such example that was used in Unity up until 2016. Shaders could be authored in a standard HLSL syntax, then transpiled at build time into corresponding GLSL code.

SPIRV-Cross is another transpiler maintained by the Unity team that can serve as a bridge between HLSL, GLSL, MSL, and Vulkan.

Using an existing shader language as your source helps you avoid the overhead of designing a brand new one from scratch, and you can leverage a lot of work shared by other teams via projects like the ones linked above.

There are some extra considerations though, as outlined in the SPIRV-Cross Readme:

Implementation notes

When using SPIR-V and SPIRV-Cross as an intermediate step for cross-compiling between high level languages there are some considerations to take into account, as not all features used by one high-level language are necessarily supported natively by the target shader language. SPIRV-Cross aims to provide the tools needed to handle these scenarios in a clean and robust way, but some manual action is required to maintain compatibility.

The areas they call out include:

  • HLSL source to GLSL
    • HLSL entry points
    • Vertex/Fragment interface linking
  • HLSL source to legacy GLSL/ESSL
    • Separate image samplers (HLSL/Vulkan) for backends which do not support it (GLSL)
    • Descriptor sets (Vulkan GLSL) for backends which do not support them (HLSL/GLSL/Metal)
    • Linking by name for targets which do not support explicit locations (legacy GLSL/ESSL)
    • Clip-space conventions
    • Reserved identifiers

See the linked document for all the gory details of how to handle these situations.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.