glslcc: Cross-compiler for GLSL shader language (GLSL->HLSL,METAL,GLES,GLSLv3)


glslcc: Cross-compiler for GLSL shader language (GLSL->HLSL,METAL,GLES,GLSLv3)


glslcc is a command line tool that converts GLSL code to HLSL, GLES (version 2.0 and 3.0), Metal (MSL) and also other GLSL versions (GLSL 330, GLSL 400, etc..).
It uses glslang for parsing GLSL and compiling SPIR-V. And SPIRV-cross for converting the code from SPIR-V to the target language.


  • Currently, vertex, fragment and compute shaders are supported
  • Flatten UBOs, useful for ES2 shaders
  • Show preprocessor result, show include files (for resolving shader dependencies in external tools)
  • Add defines
  • Add include directories
  • shader reflection data in Json format
  • Can output to a native binary file format (.sgs), that holds all the shaders and reflection data for pipeline
  • Can output to individual files
  • Can output all pipeline shaders (vertex+fragment) and their reflection data to .c file variables
  • Supports both GLES2 and GLES3 shaders
  • Can output to other GLSL versions like 330
  • Optional D3D11 byte code output for HLSL shaders
  • Support for special tags (begin_vert/begin_frag) in a single .glsl file (embed multiple sources)


glslcc uses CMake. built and tested on:

  • Windows 10 - Microsoft visual studio 2015 Update 3
  • Ubuntu 16.04 - GCC 5.4.0
  • MacOS - 10.14 sdk with clang-1000.11.45.2

How to build on Windows

Note: These instructions assume you already have Git and CMake installed.

I assume that terminal users are using a Linux-style terminal for Windows; therefore '/' is used in file paths. If you're running Windows cmd all '/' need to replaced with '\'

  1. Get the code
git clone
  1. Run CMake
./cmake -S path/to/glslcc/ -B path/to/glslcc/build

If you don't include the -B flag, the build files will instead be written to wherever cmake.exe is, which you probably don't want

  1. Build and Run the executable from the terminal and enjoy! See below for further examples of command line args
./glslcc.exe --vert=path/to/shader.vert --frag=path/to/shader.frag --output=path/to/shader.hlsl --lang=hlsl --reflect


I'll have to write a more detailed documentation but for these are the arguments: (glslcc --help)

-h --help                           - Print this help text
-V --version                        - Print version
-v --vert=
                    - Vertex shader source file
-f --frag=
                     - Fragment shader source file
-c --compute=
                   - Compute shader source file
-o --output=
                     - Output file
-l --lang=
         - Convert to shader language -D --defines(=Defines) - Preprocessor definitions, seperated by comma or ';' -Y --invert-y - Invert position.y in vertex shader -p --profile=
          - Shader profile version (HLSL: 40, 50, 60), (ES: 200, 300), (GLSL: 330, 400, 420) -C --dumpc - Dump shader limits configuration -I --include-dirs=
           - Set include directory for 
            files, seperated by ';' -P --preprocess - Dump preprocessed result to terminal -N --cvar=
             - Outputs Hex data to a C include file with a variable name -F --flatten-ubos - Flatten UBOs, useful for ES2 shaders -r --reflect(=Filepath) - Output shader reflection information to a json file -G --sgs - Output file should be packed SGS format -b --bin - Compile to bytecode instead of source. requires ENABLE_D3D11_COMPILER build flag -g --debug - Generate debug info for binary compilation, should come with --bin -O --optimize - Optimize shader for release compilation -S --silent - Does not output filename(s) after compile success -i --input=<(null)> - Input shader source file. determined by extension (.vert/.frag/.comp) -0 --validate - Only performs shader validatation and error checking -E --err-format=
              - Output error format -L --list-includes - List include files in shaders, does not generate any output files Current supported shader stages are: - Vertex shader (--vert) - Fragment shader (--frag) - Compute shader (--compute) 

Here's some examples:

Example shader (write shaders GLSL 4.5) : You can also use #include. The compiler automatically inserts #extension GL_GOOGLE_include_directive : require at the begining of any shader.

Vertex Shader (shader.vert):

#version 450

layout (location = POSITION) in vec3 aPos;
layout (location = COLOR0) in vec4 aColor;
layout (location = TEXCOORD0) in vec2 aCoord;

layout (std140, binding=0) uniform matrices
    mat4 projection;
    mat4 view;
    mat4 model;

layout (location = COLOR0) out flat vec4 outColor;
layout (location = TEXCOORD0) out vec2 outCoord;

void main()
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    outColor = aColor;
    outCoord = aCoord;

Fragment shader (shader.frag):

#version 450

precision mediump float;

layout (location = COLOR0) in flat vec4 inColor;
layout (location = TEXCOORD0) in vec2 inCoord;

layout (location = SV_Target0) out vec4 fragColor;

layout (binding = 0) uniform sampler2D colorMap;

void main() 
    lowp vec4 c = texture(colorMap, inCoord);
    fragColor = inColor * c;

Cross-compiles the vertex-shader and fragment-shader to HLSL files with reflection Json data Output files will be shader_vs.hlsl, shader_fs.hlsl for HLSL code, and shader_vs.hlsl.json, shader_fs.hlsl.json for their reflection data.

glslcc --vert=shader.vert --frag=shader.frag --output=shader.hlsl --lang=hlsl --reflect

This command does the same thing, but outputs all the data to a C header file shader.h, with specified variable names g_shader_vs, g_shader_fs, g_shader_vs_refl and g_shader_fs_refl which are the same data in files in hex representation. Also sets preprocessor values HLSL=1 and USE_TEXTURE3D=1 for both shaders.

glslcc --vert=shader.vert --frag=shader.frag --output=shader.h --lang=hlsl --reflect --cvar=g_shader --defines=HLSL=1;USE_TEXTURE3D=1

You can also pass files without explicitly defining input shaders in arguments. their shader type will be resolved by checking their file extensions. So .vert=vertex-shader, .frag=fragment-shader, .comp=compute-shader

glslcc shader.vert shader.frag --output=shader --lang=hlsl

To only validate a specific shader (useful for tools and IDEs), use --validate flag, with your specified output error format. By default, on windows, it outputs msvc's error format and on other platforms outputs gcc's error format, and only glslang's format if explicitly defined:

glslcc shader.vert --validate --err-format=glslang

Embed multiple sources into a single file

To to this, you can use the special tags and write your vertex/fragment sources inside of them. Tags are //@begin_vert for vertex shader and //@begin_frag for fragment shader. Also remember to end the block with //@end. The compiler will extract the blocks and compile each source separately just like individual files.

Note that this only works with .glsl files and no other extension:

    #version 450

    layout (location = POSITION)  in  vec3 a_pos;
    layout (location = TEXCOORD0) in  vec2 a_coord;
    layout (location = TEXCOORD0) out vec2 f_coord;

    layout (binding=0, std140) uniform matrices {
        mat4 mvp;
    void main() {
        gl_Position = mvp * vec4(a_pos, 1.0);
        f_coord = a_coord;

    #version 450

    precision mediump float;

    layout (location = TEXCOORD0)  in  vec2 f_coord;
    layout (location = SV_Target0) out vec4 frag_color;

    layout (binding = 0) uniform sampler2D tex_image;

    void main() {
        frag_color = texture(tex_image, f_coord);

Reflection data

Reflection data comes in form of json files and activated with --reflect option. It includes all the information that you need to link your 3d Api to the shader

HLSL semantics

As you can see in the above example, I have used HLSL shader semantics for input and output layout. This must done for compatibility with HLSL shaders and also proper vertex assembly creation in D3D application. The reflection data also emits proper semantics for each vertex input for the application.
Here are supported HLSL semantics that you should use with layout (location = SEMANTIC):


SV_Target0, SV_Target1, SV_Target2, SV_Target3

SGS file format

There is also an option for exporting to .sgs files (--sgs) which is a simple IFF like binary format to hold all shaders (vs + fs + cs) with their reflection inside a binary blob. Check out sgs-file.h for the file format spec and headers. The blocks are layed out like this:

The blocks are composed of a uint32_t fourcc code + uint32_t variable defining the size of the block. So each block header is 8 bytes. For each header structure, check out the header file.

  • SGS block
    • struct sgs_chunk
    • STAG blocks: defines each shader stage (vs + fs + ..)
      • CODE: actual code for the shader stage
      • DATA: binary (byte-code) data for the shader stage
      • REFL: Reflection data for the shader stage
        • struct sgs_chunk_refl: reflection data header
        • struct sgs_refl_input[]: array of vertex-shader input attributes (see sgs_chunk_refl for number of inputs)
        • struct sgs_refl_uniform_buffer[]: array of uniform buffer objects (see sgs_chunk_refl for number of uniform buffers)
        • struct sgs_refl_texture[]: array of texture objects (see sgs_chunk_refl for number of textures)
        • struct sgs_refl_texture[]: array of storage image objects (see sgs_chunk_refl for number of storage images)
        • struct sgs_refl_buffer[]: array of storage buffer objects (see sgs_chunk_refl for number of storage buffers)

MSVC Linter

If you happen to work with msvc 2017 and higher, there is this extension called GLSL language integration (github) that this compiler is compatible with, so it can perform automating error checking in your editor. use these parameters in extensions's config:

glslcc -0 -E glslang

VSCode Linter

For visual studio code linting, I have modified existing GLSL Lint extension to work with this tool instead. you can find it here.

Just install the tool manually in vscode, and add these options to vscode:

    "glsllint.glslangValidatorPath": "/path/to/glslcc.exe",
    "glsllint.glslangValidatorArgs": "--validate --err-format=glslang"

D3D11 Compiler

There is a support for compiling d3d11 shaders (ps_5_0, vs_5_0, cs_5_0) into D3D11 byte-code instead of HLSL source code. On windows with Windows SDK, set ENABLE_D3D11_COMPILER=ON flag for cmake, build the project and use --bin in the command line arguments to generate binary byte-code file.

CMake module

I've added glslcc.cmake module, to facilitate shader compilation in cmake projects. here's an example on how you can use it in your CMakeLists.txt to make shaders as C header files:

set(shaders test.vert test.frag)
set_source_files_properties(${shaders} PROPERTIES GLSLCC_OUTPUT_DIRECTORY "shaders_inc")
glslcc_target_compile_shaders_h(project_name "${shaders}")

These properties can be assigned to shaders source files:

  • GLSLCC_OUTPUT_DIRECTORY: output directory path
  • GLSLCC_SHADER_LANG: shader language, gles/msl/hlsl/glsl. if not defined, it will be automatically selected by running platform
  • GLSLCC_SHADER_VERSION: shader profile version. default: hlsl:50, gles:200, glsl:330
  • GLSLCC_OUTPUT_FILENAME: compiled filename. default: SOURCE_FILE.EXT.h
  • GLSLCC_COMPILE_FLAGS: extra compilation flags to pass to glslcc
  • COMPILE_DEFINITIONS: compile definitions
  • INCLUDE_DIRECTORIES: shader include directories


  • Support for more shader stages. I didn't have any use for geometry and tesselation shaders, but the glslang supports all of them, so adding new shader stages shouldn't be a problem

License (BSD 2-clause)

Copyright 2018 Sepehr Taghdisian. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.

  • parse_output_log() early-outs after finding the first non-error and fails to output further errors

    parse_output_log() early-outs after finding the first non-error and fails to output further errors

    I've just started using the codebase so apologies if I'm missing something, but consider the following code in glslcc.cpp:

    static bool parse_output_log(const char* str, std::vector<output_parse_result>* r) { const char* header = "ERROR: "; while (sx_strstr(str, header) == str) { str += sx_strlen(header); const char* divider = sx_strchar(str, ':'); <snip> r->push_back(lr); } return true; }

    In my shader, the first output message in str is a "WARNING: ", not an "ERROR: ". The result appears to be that we write nothing to the output_parse_result vector as we only parse the array as far as the first non-error message and all further messages are ignored.

    opened by Weaseltron 4
  • Use const reference in for-loop for fix

    Use const reference in for-loop for fix

    AppleClang 12 complains about unnecessary copies in for loops when using -Werror. Now this warning/error is actually in spirv-cross, but since you bundle that in this repository, I thought I'd open a PR here.

    It probably makes more sense to see if a newer version of spirv-cross than the one bundled here fixes this (I didn't test this), so feel free to close this.

    opened by paulgessinger 3
  • How to handle in cross manier stage binding

    How to handle in cross manier stage binding


    Excellent job on library, I'm working on personal game engine and come to your shader compiler, I added the HLSL stage semantics support (POSITION, COLOR0 etc) and it fits well.

    Question is, How you handle shader bindings? While vulkan has set and binding for uniform buffers, samplers etc, HLSL and DirectX has stage binding, do you plan to add some schema/trick for this part as well?


    opened by amerkoleci 3
  • samples failed to cross-compile

    samples failed to cross-compile

    Hey again, Just used your own samples and they refused to work:

    > glslcc --vert=shader.vert --frag=shader.frag --output=shader.hlsl --lang=hlsl --reflect
    ERROR: sample.vert:5: '' : vertex input cannot be further qualified
    ERROR: sample.vert:5: '' : compilation terminated
    ERROR: 2 compilation errors.  No code generated.
    opened by r-lyeh 3
  • missing lib linkage

    missing lib linkage

    Hey @septag

    Just trying to compile your tool :D

    It gave following error when linking: sxd.lib(os.obj) : error LNK2019: unresolved external symbol [email protected] referenced in function _sx_os_processmem [glslcc\.build\src\glslcc.vcxproj]

    So I added #pragma comment(lib, "psapi.lib") somewhere to fix it :)

    PS: Suggestion: what about providing binary releases?

    opened by r-lyeh 2
  • Sampler Array Indexing Issues

    Sampler Array Indexing Issues

    I have come to the following problem while trying to cross-compile from glsl to hlsl bytecode (D3D11).

    One of my shaders contains the following code

    int index = int(fsIn.tTexture); //casting from float to int
            case 0:
                return u_Textures[0].Sample(...);
            case 1:
                return u_Textures[1].Sample(...);

    This is all fine if it is ported the same way in hlsl, however, it gets shortened to

    int _21 = int(Texture);
    FragColor = u_Textures[_21]

    Which is not valid D3D11 hlsl code.

    Any possible workarounds without having to rewrite the shaders completely?

    May thanks.

    opened by Abdul-AZ 1
  • Fix compilation error on non-Windows platforms

    Fix compilation error on non-Windows platforms

    Define PATH_MAX depending on platform instead of using Windows-only MAX_PATH.

    This fixes the project not compiling on POSIX systems. More #ifs might be needed for other platforms.

    opened by thokr 1
  • Mat4 attribute when targeting MSL results in attributes being used more than once

    Mat4 attribute when targeting MSL results in attributes being used more than once

    I have the following vertex shader inputs -

    layout (location = 0) in vec3 a_position; layout (location = 1) in vec3 a_normal; layout (location = 2) in vec4 a_color; layout (location = 3) in mat4 joint; Using glslang to produce SPIR-V and then invoking SPIRV-cross targeting metal, the following MSL is produced -

    struct main0_in { float4 joint_0 [[attribute(0)]]; float4 joint_1 [[attribute(1)]]; float3 a_position [[attribute(1)]]; float4 joint_2 [[attribute(2)]]; float3 a_normal [[attribute(2)]]; float4 joint_3 [[attribute(3)]]; float4 a_color [[attribute(3)]]; };

    Which produces the following error when the msl is compiled -

    error: 'attribute' index '1' is used more than once I tried setting joint to location 0 and position, normal and color to 4 5 and 6 respectively, but the same code was generated.

    Am I doing something wrong here, or is this a legitimate issue?

    opened by zacharycarter 1
  • MSL vertex layout reordered

    MSL vertex layout reordered

    It seems that glslcc is reordering the vertex layout according to usage when transpiling to MSL:

    #version 450
    layout (location = 0) in vec2 Position;
    layout (location = 1) in vec2 UV;
    layout (location = 2) in vec4 Color;
    /* uniforms and outputs here... */
    void main()
        Frag_UV = UV;
        Frag_Color = Color;
        gl_Position = Projection * vec4(Position.xy,0,1);

    Gives me this input in MSL:

    struct main0_in
        float2 UV [[attribute(0)]];
        float4 Color [[attribute(1)]];
        float2 Position [[attribute(2)]];

    The attribute order is the usage order in the code, not the original location. If I change the source's main() to:

    void main()
        gl_Position = Projection * vec4(Position.xy,0,1);
        Frag_UV = UV;
        Frag_Color = Color;

    I get the 'correct' order.

    opened by ltjax 1
  • API support?

    API support?

    Hello, Thanks for your great works.

    I just wanna know if i can use this library as cpp api by loading it. I couldn't find api functions, It looks just supporting command line interface.

    Or do you have ways to get translated code string from glslcc?

    opened by SungJJinKang 0
  • AutoMap option

    AutoMap option


    There is two glslang automap options that should be interesting in this tool:


    This remove binding and location requirement in shader.

    opened by eduardodoria 1
  • Add member reflection info to push constants

    Add member reflection info to push constants

    Push constant blocks currently do not get member information in the reflection output:

    layout(push_constant) uniform matrices {
        mat4 u_model;
        mat4 u_modelViewProj;
    } mat;

    results in

    "push_cbs": [
        "id": 19,
        "name": "mat"

    With this PR, it gets the same member information as uniform buffers:

    "push_cbs": [
        "id": 19,
        "name": "mat",
        "members": [
            "name": "u_model",
            "type": "mat4",
            "offset": 0,
            "size": 64
            "name": "u_modelViewProj",
            "type": "mat4",
            "offset": 64,
            "size": 64

    Currently this only applies to json, I wasn't sure push constant info is even written to the binary output, and didn't want to modify it.

    Anyway, I'm pretty new to this stuff, so let me know if my assumptions here are wrong, and this is not actually information that should be in the reflection info.

    opened by paulgessinger 0
  • Missing type qualifiers for multi-dimensional arrays

    Missing type qualifiers for multi-dimensional arrays

    When converting compute shaders to gles profile 310, glslcc converts multi-dimensional arrays to one-dimensionsal and adjusts index expressions accordingly. Unfortunately, the adjusting index multiplier constants lack type qualifiers, leading to load errors such as:

    error: could not implicitly convert operands to arithmetic operator
    error: operands to arithmetic operators must be numeric


    $ cat binning.comp 
    #version 450
    layout(local_size_x = 256, local_size_y = 1) in;
    shared uint bitmaps[8][256];
    void main() {
        for (uint i = 0; i < 8; i++) {
            bitmaps[i][gl_LocalInvocationID.x] = 0;
    $ glslcc --compute binning.comp --lang gles --profile 310 -o blah && cat blah_cs
    #version 310 es
    layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
    shared uint bitmaps[8 * 256];
    void main()
        for (uint i = 0u; i < 8u; i++)
            bitmaps[i * 256 + gl_LocalInvocationID.x] = 0u;

    Note how the constant 256 in i * 256 + gl_LocalInvocationID.x lacks a type qualifier; replacing it with 256u avoids the load error.

    opened by eliasnaur 0
Sepehr Taghdisian
Sepehr Taghdisian
Shader cross compiler to translate HLSL (Shader Model 4 and 5) to GLSL

XShaderCompiler ("Cross Shader Compiler") Features Cross compiles HLSL shader code (Shader Model 4 and 5) into GLSL Simple to integrate into other pro

Lukas Hermanns 345 Nov 23, 2022
GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.

GLSL optimizer ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a different shader compilati

Aras Pranckevičius 1.6k Nov 27, 2022
HLSL Parser and Translator for HLSL, GLSL, and MSL.

HLSLParser This is a fork of Unknownworld's hlslparser adapted to our needs in The Witness. We currently use it to translate pseudo-HLSL shaders (usin

null 3 Jul 2, 2022
HLSL Parser and Translator for HLSL, GLSL, and MSL.

HLSLParser This is a fork of Unknownworld's hlslparser adapted to our needs in The Witness. We currently use it to translate pseudo-HLSL shaders (usin

null 316 Nov 15, 2022
A cross platform shader language with multi-threaded offline compilation or platform shader source code generation

A cross platform shader language with multi-threaded offline compilation or platform shader source code generation. Output json reflection info and c++ header with your shaders structs, fx-like techniques and compile time branch evaluation via (uber-shader) "permutations".

Alex Dixon 285 Nov 16, 2022
HLSL to GLSL language translator based on ATI's HLSL2GLSL. Used in Unity.

HLSL to GLSL shader language translator ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a d

Aras Pranckevičius 522 Nov 24, 2022
Minify and obfuscate GLSL or HLSL code

Shader Minifier Shader Minifier is a tool that minifies and obfuscates shader code (GLSL and HLSL). Its original use-case is for the demoscene, for op

Laurent Le Brun 245 Nov 27, 2022
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.

News Visual Studio 2013 is no longer supported As scheduled, Microsoft Visual Studio 2013 is no longer officially supported. Please upgrade to at leas

The Khronos Group 2.3k Nov 24, 2022
Shader Playground is a website for exploring shader compilers.

Shader Playground is a website for exploring shader compilers. Visit website Supported backends Compilers ANGLE Clspv DXC FXC Glslan

Tim Jones 442 Dec 2, 2022
LLVM IR and optimizer for shaders, including front-end adapters for GLSL and SPIR-V and back-end adapter for GLSL

Licensing LunarGLASS is available via a three clause BSD-style open source license. Goals The primary goals of the LunarGLASS project are: Reduce the

LunarG, Inc. 154 Sep 12, 2022
ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages

ShaderConductor ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages. Features Converts HLSL to readable, usable and

Microsoft 1.5k Nov 25, 2022
Skyline's fork of yuzu's shader compiler

Skyline Shader Compiler (SSC) A fork of yuzu's shader compiler modified for Skyline's needs with all other changes being upstreamed and changes from y

Skyline 16 Nov 3, 2022
A small DLL that fixes tool's usage of the Halo 3 shader compiler.

h3-shader-compiler-fix A small DLL that fixes tool's usage of the Halo 3 shader compiler. Tool forgot to initialise the compiler before using it, so t

null 7 Jun 20, 2022
A Visual Studio extension that provides enhanced support for editing High Level Shading Language (HLSL) files

HLSL Tools for Visual Studio This extension is for Visual Studio 2017 / 2019. Go here for the Visual Studio Code extension. HLSL Tools is a Visual Stu

Tim Jones 429 Nov 26, 2022
Signed - a 3D modeling and construction language based on Lua and SDFs. Signed will be available for macOS and iOS and is heavily optimized for Metal.

Signed - A 3D modeling language Abstract Signed is a Lua based 3D modeling language, it provides a unique way to create high quality 3D content for yo

Markus Moenig 90 Nov 21, 2022
SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages.

SPIRV-Cross SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages. Features Convert SPIR-V to readable, usable an

The Khronos Group 1.6k Dec 3, 2022
Lightweight, cross-platform & full-featured shader IDE

SHADERed is a lightweight tool for writing and debugging shaders. It is easy to use, open source, cross-platform (runs on Windows, Linux & Web).

dfranx 3.7k Nov 26, 2022
C/C++ language server supporting multi-million line code base, powered by libclang. Emacs, Vim, VSCode, and others with language server protocol support. Cross references, completion, diagnostics, semantic highlighting and more

Archived cquery is no longer under development. clangd and ccls are both good replacements. cquery cquery is a highly-scalable, low-latency language s

Jacob Dufault 2.3k Nov 20, 2022