Convert GLSL to WGSL

I know that babylon.js can convert glsl shader code on the fly to wgsl, I was wondering is it possible to setup a playground that simply outputs the converted code? This would be a useful tool and I’m not having much look with other online tools that claim to do so.

1 Like

Have you tried Spector Chrome extension. It is able to show the final shader code for runtime.

1 Like

You can set BABYLON.WebGPUTintWASM.ShowWGSLShaderCode = true:

Have you tried Spector Chrome extension. It is able to show the final shader code for runtime.

Spector does not work with WebGPU, unfortunately. Other debugging tools for WebGPU are under development.

2 Likes

Oh wow, no kidding. I see it in the console; this Javascript:

var createScene = function () {
    BABYLON.WebGPUTintWASM.ShowWGSLShaderCode = true;

    // This creates a basic Babylon Scene object (non-mesh)
    var scene = new BABYLON.Scene(engine);

    // This creates and positions a free camera (non-mesh)
    var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);

    // This targets the camera to scene origin
    camera.setTarget(BABYLON.Vector3.Zero());

    // This attaches the camera to the canvas
    camera.attachControl(canvas, true);

    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);

    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    // Our built-in 'sphere' shape.
    var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);

    // Move the sphere upward 1/2 its height
    sphere.position.y = 1;

    // Our built-in 'ground' shape.
    var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);

    return scene;
};

Generates:

struct Mesh {
  /* @offset(0) */
  world : mat4x4<f32>,
  /* @offset(64) */
  visibility : f32,
}

struct Scene {
  /* @offset(0) */
  viewProjection : mat4x4<f32>,
  /* @offset(64) */
  view : mat4x4<f32>,
  /* @offset(128) */
  projection : mat4x4<f32>,
  /* @offset(192) */
  vEyePosition : vec4<f32>,
}

struct Internals {
  /* @offset(0) */
  yFactor_ : f32,
  /* @offset(4) */
  textureOutputHeight_ : f32,
}

struct Material {
  /* @offset(0) */
  diffuseLeftColor : vec4<f32>,
  /* @offset(16) */
  diffuseRightColor : vec4<f32>,
  /* @offset(32) */
  opacityParts : vec4<f32>,
  /* @offset(48) */
  reflectionLeftColor : vec4<f32>,
  /* @offset(64) */
  reflectionRightColor : vec4<f32>,
  /* @offset(80) */
  refractionLeftColor : vec4<f32>,
  /* @offset(96) */
  refractionRightColor : vec4<f32>,
  /* @offset(112) */
  emissiveLeftColor : vec4<f32>,
  /* @offset(128) */
  emissiveRightColor : vec4<f32>,
  /* @offset(144) */
  vDiffuseInfos : vec2<f32>,
  /* @offset(152) */
  vAmbientInfos : vec2<f32>,
  /* @offset(160) */
  vOpacityInfos : vec2<f32>,
  /* @offset(168) */
  vReflectionInfos : vec2<f32>,
  /* @offset(176) */
  vReflectionPosition : vec3<f32>,
  /* @offset(192) */
  vReflectionSize : vec3<f32>,
  /* @offset(208) */
  vEmissiveInfos : vec2<f32>,
  /* @offset(216) */
  vLightmapInfos : vec2<f32>,
  /* @offset(224) */
  vSpecularInfos : vec2<f32>,
  /* @offset(240) */
  vBumpInfos : vec3<f32>,
  /* @offset(256) */
  diffuseMatrix : mat4x4<f32>,
  /* @offset(320) */
  ambientMatrix : mat4x4<f32>,
  /* @offset(384) */
  opacityMatrix : mat4x4<f32>,
  /* @offset(448) */
  reflectionMatrix : mat4x4<f32>,
  /* @offset(512) */
  emissiveMatrix : mat4x4<f32>,
  /* @offset(576) */
  lightmapMatrix : mat4x4<f32>,
  /* @offset(640) */
  specularMatrix : mat4x4<f32>,
  /* @offset(704) */
  bumpMatrix : mat4x4<f32>,
  /* @offset(768) */
  vTangentSpaceParams : vec2<f32>,
  /* @offset(776) */
  pointSize : f32,
  /* @offset(780) */
  alphaCutOff : f32,
  /* @offset(784) */
  refractionMatrix : mat4x4<f32>,
  /* @offset(848) */
  vRefractionInfos : vec4<f32>,
  /* @offset(864) */
  vRefractionPosition : vec3<f32>,
  /* @offset(880) */
  vRefractionSize : vec3<f32>,
  /* @offset(896) */
  vSpecularColor : vec4<f32>,
  /* @offset(912) */
  vEmissiveColor : vec3<f32>,
  /* @offset(928) */
  vDiffuseColor : vec4<f32>,
  /* @offset(944) */
  vAmbientColor : vec3<f32>,
  /* @offset(960) */
  vDetailInfos : vec4<f32>,
  /* @offset(976) */
  detailMatrix : mat4x4<f32>,
}

struct Light0 {
  /* @offset(0) */
  vLightData : vec4<f32>,
  /* @offset(16) */
  vLightDiffuse : vec4<f32>,
  /* @offset(32) */
  vLightSpecular : vec4<f32>,
  /* @offset(48) */
  vLightGround : vec3<f32>,
  /* @offset(64) */
  shadowsInfo : vec4<f32>,
  /* @offset(80) */
  depthValues : vec2<f32>,
}

var<private> position_1 : vec3<f32>;

var<private> normal : vec3<f32>;

@group(1) @binding(2) var<uniform> x_22 : Mesh;

var<private> vNormalW : vec3<f32>;

@group(0) @binding(0) var<uniform> x_63 : Scene;

var<private> vPositionW : vec3<f32>;

@group(1) @binding(0) var<uniform> x_83 : Internals;

@group(1) @binding(1) var<uniform> x_94 : Material;

@group(1) @binding(3) var<uniform> light0 : Light0;

var<private> gl_Position : vec4<f32>;

fn main_1() {
  var positionUpdated : vec3<f32>;
  var normalUpdated : vec3<f32>;
  var finalWorld : mat4x4<f32>;
  var worldPos : vec4<f32>;
  var normalWorld : mat3x3<f32>;
  var uvUpdated : vec2<f32>;
  let x_12 : vec3<f32> = position_1;
  positionUpdated = x_12;
  let x_15 : vec3<f32> = normal;
  normalUpdated = x_15;
  let x_27 : mat4x4<f32> = x_22.world;
  finalWorld = x_27;
  let x_30 : mat4x4<f32> = finalWorld;
  let x_31 : vec3<f32> = positionUpdated;
  worldPos = (x_30 * vec4<f32>(x_31.x, x_31.y, x_31.z, 1.0f));
  let x_41 : mat4x4<f32> = finalWorld;
  let x_42 : vec4<f32> = x_41[0u];
  let x_44 : vec4<f32> = x_41[1u];
  let x_46 : vec4<f32> = x_41[2u];
  normalWorld = mat3x3<f32>(vec3<f32>(x_42.x, x_42.y, x_42.z), vec3<f32>(x_44.x, x_44.y, x_44.z), vec3<f32>(x_46.x, x_46.y, x_46.z));
  let x_51 : mat3x3<f32> = normalWorld;
  let x_52 : vec3<f32> = normalUpdated;
  vNormalW = normalize((x_51 * x_52));
  let x_65 : mat4x4<f32> = x_63.viewProjection;
  let x_66 : vec4<f32> = worldPos;
  gl_Position = (x_65 * x_66);
  let x_71 : vec4<f32> = worldPos;
  vPositionW = vec3<f32>(x_71.x, x_71.y, x_71.z);
  uvUpdated = vec2<f32>(0.0f, 0.0f);
  let x_86 : f32 = x_83.yFactor_;
  let x_89 : f32 = gl_Position.y;
  gl_Position.y = (x_89 * x_86);
  return;
}

struct main_out {
  @location(1)
  vNormalW_1 : vec3<f32>,
  @builtin(position)
  gl_Position : vec4<f32>,
  @location(0)
  vPositionW_1 : vec3<f32>,
}

@vertex
fn main(@location(0) position_1_param : vec3<f32>, @location(1) normal_param : vec3<f32>) -> main_out {
  position_1 = position_1_param;
  normal = normal_param;
  main_1();
  return main_out(vNormalW, gl_Position, vPositionW);
}

webgpuTintWASM.ts:74 ***********************************************
webgpuTintWASM.ts:73 struct lightingInfo {
  diffuse : vec3<f32>,
  specular : vec3<f32>,
}

struct Scene {
  /* @offset(0) */
  viewProjection : mat4x4<f32>,
  /* @offset(64) */
  view : mat4x4<f32>,
  /* @offset(128) */
  projection : mat4x4<f32>,
  /* @offset(192) */
  vEyePosition : vec4<f32>,
}

struct Material {
  /* @offset(0) */
  diffuseLeftColor : vec4<f32>,
  /* @offset(16) */
  diffuseRightColor : vec4<f32>,
  /* @offset(32) */
  opacityParts : vec4<f32>,
  /* @offset(48) */
  reflectionLeftColor : vec4<f32>,
  /* @offset(64) */
  reflectionRightColor : vec4<f32>,
  /* @offset(80) */
  refractionLeftColor : vec4<f32>,
  /* @offset(96) */
  refractionRightColor : vec4<f32>,
  /* @offset(112) */
  emissiveLeftColor : vec4<f32>,
  /* @offset(128) */
  emissiveRightColor : vec4<f32>,
  /* @offset(144) */
  vDiffuseInfos : vec2<f32>,
  /* @offset(152) */
  vAmbientInfos : vec2<f32>,
  /* @offset(160) */
  vOpacityInfos : vec2<f32>,
  /* @offset(168) */
  vReflectionInfos : vec2<f32>,
  /* @offset(176) */
  vReflectionPosition : vec3<f32>,
  /* @offset(192) */
  vReflectionSize : vec3<f32>,
  /* @offset(208) */
  vEmissiveInfos : vec2<f32>,
  /* @offset(216) */
  vLightmapInfos : vec2<f32>,
  /* @offset(224) */
  vSpecularInfos : vec2<f32>,
  /* @offset(240) */
  vBumpInfos : vec3<f32>,
  /* @offset(256) */
  diffuseMatrix : mat4x4<f32>,
  /* @offset(320) */
  ambientMatrix : mat4x4<f32>,
  /* @offset(384) */
  opacityMatrix : mat4x4<f32>,
  /* @offset(448) */
  reflectionMatrix : mat4x4<f32>,
  /* @offset(512) */
  emissiveMatrix : mat4x4<f32>,
  /* @offset(576) */
  lightmapMatrix : mat4x4<f32>,
  /* @offset(640) */
  specularMatrix : mat4x4<f32>,
  /* @offset(704) */
  bumpMatrix : mat4x4<f32>,
  /* @offset(768) */
  vTangentSpaceParams : vec2<f32>,
  /* @offset(776) */
  pointSize : f32,
  /* @offset(780) */
  alphaCutOff : f32,
  /* @offset(784) */
  refractionMatrix : mat4x4<f32>,
  /* @offset(848) */
  vRefractionInfos : vec4<f32>,
  /* @offset(864) */
  vRefractionPosition : vec3<f32>,
  /* @offset(880) */
  vRefractionSize : vec3<f32>,
  /* @offset(896) */
  vSpecularColor : vec4<f32>,
  /* @offset(912) */
  vEmissiveColor : vec3<f32>,
  /* @offset(928) */
  vDiffuseColor : vec4<f32>,
  /* @offset(944) */
  vAmbientColor : vec3<f32>,
  /* @offset(960) */
  vDetailInfos : vec4<f32>,
  /* @offset(976) */
  detailMatrix : mat4x4<f32>,
}

struct Light0 {
  /* @offset(0) */
  vLightData : vec4<f32>,
  /* @offset(16) */
  vLightDiffuse : vec4<f32>,
  /* @offset(32) */
  vLightSpecular : vec4<f32>,
  /* @offset(48) */
  vLightGround : vec3<f32>,
  /* @offset(64) */
  shadowsInfo : vec4<f32>,
  /* @offset(80) */
  depthValues : vec2<f32>,
}

struct Mesh {
  /* @offset(0) */
  world : mat4x4<f32>,
  /* @offset(64) */
  visibility : f32,
}

struct Internals {
  /* @offset(0) */
  yFactor_ : f32,
  /* @offset(4) */
  textureOutputHeight_ : f32,
}

@group(0) @binding(0) var<uniform> x_70 : Scene;

var<private> vPositionW : vec3<f32>;

@group(1) @binding(1) var<uniform> x_87 : Material;

var<private> vNormalW : vec3<f32>;

@group(1) @binding(3) var<uniform> light0 : Light0;

@group(1) @binding(2) var<uniform> x_210 : Mesh;

var<private> glFragColor : vec4<f32>;

@group(1) @binding(0) var<uniform> x_222 : Internals;

fn computeHemisphericLighting_vf3_vf3_vf4_vf3_vf3_vf3_f1_(viewDirectionW : ptr<function, vec3<f32>>, vNormal : ptr<function, vec3<f32>>, lightData : ptr<function, vec4<f32>>, diffuseColor : ptr<function, vec3<f32>>, specularColor : ptr<function, vec3<f32>>, groundColor : ptr<function, vec3<f32>>, glossiness : ptr<function, f32>) -> lightingInfo {
  var ndl : f32;
  var result : lightingInfo;
  var angleW : vec3<f32>;
  var specComp : f32;
  let x_24 : vec3<f32> = *(vNormal);
  let x_25 : vec4<f32> = *(lightData);
  ndl = ((dot(x_24, vec3<f32>(x_25.x, x_25.y, x_25.z)) * 0.5f) + 0.5f);
  let x_35 : vec3<f32> = *(groundColor);
  let x_36 : vec3<f32> = *(diffuseColor);
  let x_37 : f32 = ndl;
  result.diffuse = mix(x_35, x_36, vec3<f32>(x_37, x_37, x_37));
  let x_42 : vec3<f32> = *(viewDirectionW);
  let x_43 : vec4<f32> = *(lightData);
  angleW = normalize((x_42 + vec3<f32>(x_43.x, x_43.y, x_43.z)));
  let x_49 : vec3<f32> = *(vNormal);
  let x_50 : vec3<f32> = angleW;
  specComp = max(0.0f, dot(x_49, x_50));
  let x_53 : f32 = specComp;
  let x_55 : f32 = *(glossiness);
  specComp = pow(x_53, max(1.0f, x_55));
  let x_59 : f32 = specComp;
  let x_60 : vec3<f32> = *(specularColor);
  result.specular = (x_60 * x_59);
  let x_63 : lightingInfo = result;
  return x_63;
}

const x_116 = vec3<f32>(0.0f, 0.0f, 0.0f);

const x_159 = vec4<f32>(0.0f, 0.0f, 0.0f, 1.0f);

fn main_1() {
  var viewDirectionW_1 : vec3<f32>;
  var baseColor : vec4<f32>;
  var diffuseColor_1 : vec3<f32>;
  var alpha : f32;
  var normalW : vec3<f32>;
  var uvOffset : vec2<f32>;
  var baseAmbientColor : vec3<f32>;
  var glossiness_1 : f32;
  var specularColor_1 : vec3<f32>;
  var diffuseBase : vec3<f32>;
  var specularBase : vec3<f32>;
  var shadow : f32;
  var info : lightingInfo;
  var param : vec3<f32>;
  var param_1 : vec3<f32>;
  var param_2 : vec4<f32>;
  var param_3 : vec3<f32>;
  var param_4 : vec3<f32>;
  var param_5 : vec3<f32>;
  var param_6 : f32;
  var refractionColor : vec4<f32>;
  var reflectionColor : vec4<f32>;
  var emissiveColor : vec3<f32>;
  var finalDiffuse : vec3<f32>;
  var finalSpecular : vec3<f32>;
  var color : vec4<f32>;
  let x_74 : vec4<f32> = x_70.vEyePosition;
  let x_78 : vec3<f32> = vPositionW;
  viewDirectionW_1 = normalize((vec3<f32>(x_74.x, x_74.y, x_74.z) - x_78));
  baseColor = vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f);
  let x_90 : vec4<f32> = x_87.vDiffuseColor;
  diffuseColor_1 = vec3<f32>(x_90.x, x_90.y, x_90.z);
  let x_97 : f32 = x_87.vDiffuseColor.w;
  alpha = x_97;
  let x_100 : vec3<f32> = vNormalW;
  normalW = normalize(x_100);
  uvOffset = vec2<f32>(0.0f, 0.0f);
  baseAmbientColor = vec3<f32>(1.0f, 1.0f, 1.0f);
  let x_110 : f32 = x_87.vSpecularColor.w;
  glossiness_1 = x_110;
  let x_113 : vec4<f32> = x_87.vSpecularColor;
  specularColor_1 = vec3<f32>(x_113.x, x_113.y, x_113.z);
  diffuseBase = x_116;
  specularBase = x_116;
  shadow = 1.0f;
  let x_125 : vec3<f32> = viewDirectionW_1;
  param = x_125;
  let x_127 : vec3<f32> = normalW;
  param_1 = x_127;
  let x_130 : vec4<f32> = light0.vLightData;
  param_2 = x_130;
  let x_133 : vec4<f32> = light0.vLightDiffuse;
  param_3 = vec3<f32>(x_133.x, x_133.y, x_133.z);
  let x_137 : vec4<f32> = light0.vLightSpecular;
  param_4 = vec3<f32>(x_137.x, x_137.y, x_137.z);
  let x_142 : vec3<f32> = light0.vLightGround;
  param_5 = x_142;
  let x_144 : f32 = glossiness_1;
  param_6 = x_144;
  let x_145 : lightingInfo = computeHemisphericLighting_vf3_vf3_vf4_vf3_vf3_vf3_f1_(&(param), &(param_1), &(param_2), &(param_3), &(param_4), &(param_5), &(param_6));
  info = x_145;
  shadow = 1.0f;
  let x_147 : vec3<f32> = info.diffuse;
  let x_148 : f32 = shadow;
  let x_150 : vec3<f32> = diffuseBase;
  diffuseBase = (x_150 + (x_147 * x_148));
  let x_153 : vec3<f32> = info.specular;
  let x_154 : f32 = shadow;
  let x_156 : vec3<f32> = specularBase;
  specularBase = (x_156 + (x_153 * x_154));
  refractionColor = x_159;
  reflectionColor = x_159;
  let x_164 : vec3<f32> = x_87.vEmissiveColor;
  emissiveColor = x_164;
  let x_166 : vec3<f32> = diffuseBase;
  let x_167 : vec3<f32> = diffuseColor_1;
  let x_169 : vec3<f32> = emissiveColor;
  let x_173 : vec3<f32> = x_87.vAmbientColor;
  let x_178 : vec4<f32> = baseColor;
  finalDiffuse = (clamp((((x_166 * x_167) + x_169) + x_173), vec3<f32>(0.0f, 0.0f, 0.0f), vec3<f32>(1.0f, 1.0f, 1.0f)) * vec3<f32>(x_178.x, x_178.y, x_178.z));
  let x_182 : vec3<f32> = specularBase;
  let x_183 : vec3<f32> = specularColor_1;
  finalSpecular = (x_182 * x_183);
  let x_186 : vec3<f32> = finalDiffuse;
  let x_187 : vec3<f32> = baseAmbientColor;
  let x_189 : vec3<f32> = finalSpecular;
  let x_191 : vec4<f32> = reflectionColor;
  let x_194 : vec4<f32> = refractionColor;
  let x_196 : vec3<f32> = ((((x_186 * x_187) + x_189) + vec3<f32>(x_191.x, x_191.y, x_191.z)) + vec3<f32>(x_194.x, x_194.y, x_194.z));
  let x_197 : f32 = alpha;
  color = vec4<f32>(x_196.x, x_196.y, x_196.z, x_197);
  let x_202 : vec4<f32> = color;
  let x_205 : vec3<f32> = max(vec3<f32>(x_202.x, x_202.y, x_202.z), vec3<f32>(0.0f, 0.0f, 0.0f));
  let x_206 : vec4<f32> = color;
  color = vec4<f32>(x_205.x, x_205.y, x_205.z, x_206.w);
  let x_212 : f32 = x_210.visibility;
  let x_214 : f32 = color.w;
  color.w = (x_214 * x_212);
  let x_219 : vec4<f32> = color;
  glFragColor = x_219;
  return;
}

struct main_out {
  @location(0)
  glFragColor_1 : vec4<f32>,
}

@fragment
fn main(@location(0) vPositionW_param : vec3<f32>, @location(1) vNormalW_param : vec3<f32>) -> main_out {
  vPositionW = vPositionW_param;
  vNormalW = vNormalW_param;
  main_1();
  return main_out(glFragColor);
}

Gosh, I wish I had come here earlier to see more examples when I was first learning webGPU. This is really nice to have, thank you!