# WGSL PostProcess Vertex shader building wrong

**URL:** <https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494>\
**Category:** Questions\
**Tags:** shader, wgsl, postprocessing\
**Created:** [February 18, 2026, 9:46pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494 "2026-02-18T21:46:59Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 18, 2026, 9:46pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/1 "2026-02-18T21:46:59Z")

</div>

I am trying to use a post process effect with a custom fragment shader. When I run my app and look at the console, I am hit with a ton of invalid shader warnings for both the fragment and vertex. It should be using the built-in `ShadersWGSL/postprocess.vertex.fx` shader.

The first warning I always get is: `Invalid fragment shader: The varying named “vUV” is not declared in the vertex shader! This declaration will be ignored.`

Which is implying that the vertex shader is not exporting the `vUV` varying. I did a debug shader code on the engine to see and the vertex shader was in fact missing the varying in the fragmentInputs struct. The result of that dump is here:

```auto
//#define SHADER_NAME vertex:postprocess
diagnostic(off, chromium.unreachable_code);
struct VertexInputs {
@builtin(vertex_index) vertexIndex : u32,
@builtin(instance_index) instanceIndex : u32,
@location(0) position : vec3f,
};
var vertexInputs : VertexInputs;
struct FragmentInputs {
@builtin(position) position : vec4,

};
var vertexOutputs : FragmentInputs;

struct LeftOver {
world : mat4x4,
viewProjection : mat4x4f,
color : vec4f,
aspectRatio : f32,
h_color: vec3,
};
@group(1) @binding(1) var uniforms : LeftOver;
const IS_NDC_HALF_ZRANGE = true;
struct Internals {
yFactor_: f32,
textureOutputHeight_: f32,
};
@group(1) @binding(0) var internals : Internals;

const madd=vec2(0.5,0.5);
//#define CUSTOM_VERTEX_DEFINITIONS
@vertex
fn main(input : VertexInputs)->FragmentInputs {
vertexInputs = input;

//#define CUSTOM_VERTEX_MAIN_BEGIN
vertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;
vertexOutputs.position=vec4(vertexInputs.position,0.0,1.0);
//#define CUSTOM_VERTEX_MAIN_END
vertexOutputs.position.y = vertexOutputs.position.y * internals.yFactor_;
return vertexOutputs;
}

```

I create my post process like this

```auto
this._highlightEffect = new PostProcess('Highlight Effect', shadersPath + '/highlightEffect', {
    shaderLanguage: ShaderLanguage.WGSL,
    samplers: ['renderTargetTexture'],
    uniforms: ['aspectRatio', 'h_color'],
    camera: camera
});

```

And my shader has the correct variables at the top for a post process shader

```auto
uniform aspectRatio : f32;
uniform h_color: vec3<f32>;

// Varying
varying vUV : vec2<f32>;

var textureSamplerSampler : sampler;
var textureSampler: texture_2d<f32>;

var renderTargetTextureSampler : sampler;
var renderTargetTexture: texture_2d<f32>;

```

I tested this in the playground with a custom fragment shader and it worked.

I am using Babylon 8.36.1 on Windows, building into an angular app with webpack.

Any help is appreciated.

Thanks

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [February 19, 2026, 8:16am UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/2 "2026-02-19T08:16:51Z")

</div>

Your WGSL code dump is very strange, because it doesn’t match the dump I get from [this simple PG](https://playground.babylonjs.com/?version=8.36.1&webgpu#4DQXIK):

```wgsl
//#define SHADER_NAME vertex:postprocess
diagnostic(off, chromium.unreachable_code);
struct VertexInputs {
  @builtin(vertex_index) vertexIndex : u32,
  @builtin(instance_index) instanceIndex : u32,
@location(0) position : vec2<f32>,
};
var<private> vertexInputs : VertexInputs;
struct FragmentInputs {
  @builtin(position) position : vec4<f32>,
  @location(0) @interpolate(perspective, center) vUV : vec2<f32>,
};
var<private> vertexOutputs : FragmentInputs;

struct LeftOver {
  scale : vec2<f32>,
  degree : f32,
};
@group(1) @binding(3) var<uniform> uniforms : LeftOver;
const IS_NDC_HALF_ZRANGE = true;
struct Internals {
yFactor_: f32,
textureOutputHeight_: f32,
};
@group(1) @binding(2) var<uniform> internals : Internals;

const madd=vec2(0.5,0.5);
//#define CUSTOM_VERTEX_DEFINITIONS
@vertex
fn main(input : VertexInputs)->FragmentInputs {
  vertexInputs = input;

//#define CUSTOM_VERTEX_MAIN_BEGIN
vertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;
vertexOutputs.position=vec4(vertexInputs.position,0.0,1.0);
//#define CUSTOM_VERTEX_MAIN_END
  vertexOutputs.position.y = vertexOutputs.position.y * internals.yFactor_;
  return vertexOutputs;
}

```

The whitespace is not the same. In addition, the declaration of certain variables should include the namespace “private” or “uniform,” which is not the case in your dump.

How did you generate this result? Was it by using `engine.dbgShowShaderCode = true`? The fact that it works in Playground indicates a problem in your application’s packaging, not in your code.

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 2:53pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/3 "2026-02-19T14:53:24Z")

</div>

> [@Evgeni\_Popov](#):
>
> engine.dbgShowShaderCode = true

That is how I generated it in my application as well.

Im not packaging any differently from when I was using WebGL and the GLSL built in PP shader but Ill start focusing on the build output.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [February 19, 2026, 5:09pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/4 "2026-02-19T17:09:06Z")

</div>

After closer inspection of your dump, all the `<XXX>` constructs are missing!

So, did you really copy this code from the console, or is it a copy from a html page (where `<XXX>` would be considered as tags and not copied)?

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 5:55pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/5 "2026-02-19T17:55:33Z")

</div>

Copied from the DevTools console in Microsoft Edge

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 6:00pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/6 "2026-02-19T18:00:24Z")

</div>

Apologies, the missing tags looks like a result of a bad paste into the forum text. They disappear if I paste the console log without enabling a code block first. This is the actual output.

```auto
diagnostic(off, chromium.unreachable_code);
struct VertexInputs {
  @builtin(vertex_index) vertexIndex : u32,
  @builtin(instance_index) instanceIndex : u32,
@location(0) position : vec3f,
};
var<private> vertexInputs : VertexInputs;
struct FragmentInputs {
  @builtin(position) position : vec4<f32>,

};
var<private> vertexOutputs : FragmentInputs;

struct LeftOver {
  world : mat4x4<f32>,
  viewProjection : mat4x4f,
  color : vec4f,
  aspectRatio : f32,
  highlightColor : vec3<f32>,
};
@group(1) @binding(1) var<uniform> uniforms : LeftOver;
const IS_NDC_HALF_ZRANGE = true;
struct Internals {
yFactor_: f32,
textureOutputHeight_: f32,
};
@group(1) @binding(0) var<uniform> internals : Internals;

const madd=vec2(0.5,0.5);
//#define CUSTOM_VERTEX_DEFINITIONS
@vertex
fn main(input : VertexInputs)->FragmentInputs {
  vertexInputs = input;

//#define CUSTOM_VERTEX_MAIN_BEGIN
vertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;
vertexOutputs.position=vec4(vertexInputs.position,0.0,1.0);
//#define CUSTOM_VERTEX_MAIN_END
  vertexOutputs.position.y = vertexOutputs.position.y * internals.yFactor_;
  return vertexOutputs;
}

```

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [February 19, 2026, 6:14pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/7 "2026-02-19T18:14:23Z")

</div>

I tested locally by removing the vUV declaration from the `postprocess.vertex.fx`, and I get an error:

```auto
WebGPU uncaptured error (1): [object GPUValidationError] - Error while parsing WGSL: :35:1 error: struct member vUV not found
vertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;

```

It’s expected, as the **vUV** variable is not declared anymore.

In your dump, you do have the `vertexOutputs.vUV=...` line, without the declaration: I assume you also get this error in the console at some point?

With this setup, I do have the same output than you for `FragmentInputs `:

```wgsl
struct FragmentInputs {
  @builtin(position) position : vec4<f32>,

};

```

So, it seems the declaration is not in the `postprocess.vertex.fx` file that you use. Can you check it?

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 6:23pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/8 "2026-02-19T18:23:35Z")

</div>

I do also get that error.

The shader in my `node_modules/@babylonjs/core/ShadersWGSL/postprocess.vertex.js` is

```auto
// Do not edit.

import { ShaderStore } from "../Engines/shaderStore.js";
const name = "postprocessVertexShader";
const shader = `attribute position: vec2<f32>;uniform scale: vec2<f32>;varying vUV: vec2<f32>;const madd=vec2(0.5,0.5);
#define CUSTOM_VERTEX_DEFINITIONS
@vertex
fn main(input : VertexInputs)->FragmentInputs {
#define CUSTOM_VERTEX_MAIN_BEGIN
vertexOutputs.vUV=(vertexInputs.position*madd+madd)*uniforms.scale;vertexOutputs.position=vec4(vertexInputs.position,0.0,1.0);
#define CUSTOM_VERTEX_MAIN_END
}
`;
// Sideeffect
if (!ShaderStore.ShadersStoreWGSL[name]) {
    ShaderStore.ShadersStoreWGSL[name] = shader;
}
/** @internal */
export const postprocessVertexShaderWGSL = { name, shader };
//# sourceMappingURL=postprocess.vertex.js.map

```

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [February 19, 2026, 6:30pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/9 "2026-02-19T18:30:33Z")

</div>

So, `varying vUV: vec2<f32>` is there…

The next step would be to put a debug breakpoint in `Engines/WebGPU/webgpuShaderProcessorWGSL.ts`, line 118 (inside the `varyingProcessor` method), and see if you hit this method when **varying** equals `varying vUV: vec2<f32>`. If yes, you should step in and see if you reach the line `this._varyingsWGSL.push(" @location(${location}) ${interpolation} ${name} : ${varyingType},");`.

Alternatively, if you can setup a live link that repro the problem, I could have a look.

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 7:03pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/10 "2026-02-19T19:03:18Z")

</div>

I did the breakpoint and I do hit that function once with `varying == varying vUV: vec2<f32>` and it does reach `this._varyingsWGSL.push`

I will try to set up a lightweight repo I can share that recreates the issue

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 19, 2026, 8:41pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/11 "2026-02-19T20:41:38Z")

</div>

I was able to recreate the problem in this repo that replicates my project setup

> **[GitHub - tholub99/babylon-wgsl-webpack-postprocess](https://github.com/tholub99/babylon-wgsl-webpack-postprocess)**
>
> Contribute to tholub99/babylon-wgsl-webpack-postprocess development by creating an account on GitHub.

In this case my external post process fragment is just a copy of the black white wgsl fragment.

There are some differences in the shader dump (a lot more leftOver elements) but the core problem is still there.

Its in the readme but running it just requires doing `npm i && npm run build:dev` in the `babylon-package` directory, followed by `npm i && npm run start` in the `test-app` directory

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [February 20, 2026, 9:46am UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/12 "2026-02-20T09:46:14Z")

</div>

Thanks for the repro!

I was able to find and fix the bug:

> <https://github.com/BabylonJS/Babylon.js/pull/17930>
>
> See https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/…62494/11
> 
> We had a bug when compiling vertex/fragment shaders for an E0 effect, where the shader processor state was incorrect if the shaders were loaded asynchronously (i.e., not from the \*\*ShaderStore\*\*). It was possible that another E1 effect would be processed between the compilation of E0's vertex and fragment shaders, which led to bugs because the shader processor is a singleton.
> 
> This PR ensures that vertex and fragment shaders are always compiled one after the other, and in the same JS tick.

---

<div class="post-metadata">

**Author:** ![Teych](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/teych/32/52003_2.png) [@Teych](https://forum.babylonjs.com/u/Teych)\
**Post date:** [February 20, 2026, 2:10pm UTC](https://forum.babylonjs.com/t/wgsl-postprocess-vertex-shader-building-wrong/62494/13 "2026-02-20T14:10:50Z")

</div>

Great to hear. Thank you for looking into this!
