Can I use the TintWASM library in the Babylon.js repository?

I noticed that a library called TintWASM has been placed in the Babylon.js repository.

This seems to convert SPIR-V to WGSL.

I have some example code of WebGPU using GLSL, and I would like to convert it to WGSL using this library.

Can I use this library in my own projects?

It will cost you a lot :wink:

Just kidding obviously. Feel free to reuse and abuse it in your own projects !!! You will also need the glslang lib to convert first from glsl to SPIRV.

We are at the moment also evaluating a move to Naga in order to improve our bundle size.

cc @syntheticmagus


Thank you! I’ve incorporated it into the triangle example to try it out, and it’s working in Google Chrome 94 beta, so perhaps the conversion is working.

I don’t know if I’m using it correctly, but I tried using it like glslang and it worked.


Maybe you will find this helpful


I made a simple tool to convert from GLSL to WGSL using TintWASM.


Woot! is this the same that you used @Evgeni_Popov?

1 Like

Yes, @cx20 is using our TWGSL module created by @syntheticmagus.




@cx20 the problem you’re probably having (and I am also having currently) is that you have to convert glsl100 and glsl300 to glsl400 or spirv before running it through naga’s glsl to wgsl. The easiest way to do that is to transform the glsl to spirv using naga or glslang, like sebavan mentioned, then do a second pass using naga again to go from spirv to wgsl. BUT see my ping to syntheticmagus below, there is maybe even a better tool.

I was working on a cli yesterday and found something very nice, especially for the babylon shaders.
.GitHub - scoopr/naga-include-poc

you can use includes and mix glsl and wgsl

float sqr(float a) {
    return mul(a,a);



struct WidgetThing {
    widget: Widget;
    color: vec4<f32>;

struct Input1 {
    quux: Quux;
    xyzzy: Xyzzy;

[[group(0), binding(0)]]
var<uniform> input1: Input1;

struct VertexOutput {
    [[builtin(position)]] position: vec4<f32>;

fn example_vertex_entrypoint() -> VertexOutput  {

    let sz = sqr(2.0);
    let widget_thing = WidgetThing(make_widget(sz), vec4<f32>(0.0, 0.0, 0.0, 1.0));

    return widget_thing.widget.pos;    

Curious if you guys think the cross-syntax includes would be useful or not

We have evaluated Naga as a replacement for GLSLang+TintWASM but unfortunately decided not to use it for two/three reasons:

  • it’s the work of a single person and we don’t know how the codebase will be maintained in the future (what if that person goes away?)
  • we fear the code could be a bit fragile because the path GLSL=>WGSL is not used by the browser. On the contrary, Tint is also used by the browser for the SpirV to WGSL path (which assures us that this path will be up to date and maintained ~forever).
  • (less important than the two reasons above because it will eventually be fixed, though we don’t know when) Half of the validation tests (~15/30) we tested with Naga failed because of some yet unsupported features

All good reasons, plus little benefit of switching to naga for the same capabilities and only size. Didn’t know that u guys had made a final decision on tint vs naga. I have no reason to prefer naga vs anything else, its just i can actually make rust/cargo build things, whereas cpp, im probably batting .003 and zig breaks shit every release (still hopeful on that front though)