# P5js - inconsistent shader behaviour leading to program crashes

**URL:** <https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386>\
**Category:** Coding Questions\
**Created:** [September 17, 2026, 4:15pm UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386 "2026-09-17T16:15:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 17, 2026, 4:15pm UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/1 "2026-09-17T16:15:42Z")

</div>

Version 3 of canvasGUI (released April 2026) uses a shader to display the GUI over a webgl2 context within a p5.js sketch. This was successful and an example was created to demonstrate it. This example can be found [here](https://editor.p5js.org/canvasgui/sketches/0zdAEOC5c) and can be seen below.

Recently I have tried creating 3D sketches using p5.js and canvasGUI but the sketches failed. At first I suspected canvasGUI but I believe the issue is with p5.js because

1. Some sketches like the example below work and some don’t
2. This [sketch](https://editor.p5js.org/quark-js/sketches/uaZmnGgDU) in the p5.js web editor will display either the gui or the animation but attempting to display both crashes the sketch (you can try this yourself 😄)
3. canvasGUI works as expected in a pure JavaScript program using a webgl2 canvas. For instance this [link](http://www.lagers.org.uk/zzz/webgl/) takes you to a sketch (same as in [2] but without p5.js) and it works as expected.

Unfortunately the web editor console did not display any editor messages so I ran skecth [3] using VSC amd a local host server and got the results using 3 different browsers.

**Firefox browser (v156.0)**

```plaintext
WebGL warning: uniform setter: UniformLocation is not from the current active Program. 32
After reporting 32, no further warnings will be reported for this WebGL context. 

```

**Duckduckgo browser (v1.206.0)**

```plaintext
[Error] WebGL: INVALID_OPERATION: uniform1i: location not for current program
	uniform1i
	_updateTexture (p5.js:125775)
	bindTextures (p5.js:61984)
	_drawFills (p5.js:54777)
	_drawGeometry (p5.js:54756)
	model (p5.js:54724)
	(anonymous function) (p5.js:114039)
	(anonymous function) (p5.js:92654)
	draw (test 01.js:30)
	(anonymous function) (p5.js:3571)
[Warning] WebGL: too many errors, no more errors will be reported to the console for this context.

```

**Safari browser (v20.6.1)**

```plaintext
[Error] WebGL: INVALID_OPERATION: uniformMatrix4fv: location not for current program
	uniformMatrix4fv
	setWebGLUniformValue (p5.js:68758)
	setUniform (p5.js:62280)
	_setGlobalUniforms (p5.js:55610)
	_drawFills (p5.js:54775)
	_drawGeometry (p5.js:54756)
	drawShape (p5.js:54688)
	endShape (p5.js:27289)
	endShape (p5.js:54698)
	(anonymous function) (p5.js:33073)
	(anonymous function) (p5.js:92654)
	showAnimation (_2_sketch.js:79)
	draw (_2_sketch.js:64)
	(anonymous function) (p5.js:3571)

```

Before I raise this as an issue on github I would be interested in hearing from anyone who has experienced similar problems or are aware of any issues that might shed light on this issue.

Now I know very little about creating shaders, the one used in canvasGUI was kindly created by @scudly butd my experiments indicate there is no problem with the actual shader rather it is an issue of p5.js executing the shader program.

The example created using canvasGUI v3.2.0 and p5.js v3.2.2

https://editor.p5js.org/canvasgui/full/0zdAEOC5c

---

<div class="post-metadata">

**Author:** ![davepagurek](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/davepagurek/32/17535_2.png) [@davepagurek](https://discourse.processing.org/u/davepagurek)\
**Post date:** [September 17, 2026, 4:36pm UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/2 "2026-09-17T16:36:13Z")

</div>

p5, for optimization purposes, does not always re-apply the same gl program if it thinks it shouldn’t have changed, so if canvasGUI is changing the active shader program and does not change it back to what p5 left it at, it could break p5’s assumptions.

p5 caches this info here, in a shader’s `_bound`: [p5.js/src/webgl/p5.Shader.js at 8ce25945fac3c3d49a8ec1cc255b2cb0cb94ca89 · processing/p5.js · GitHub](https://github.com/processing/p5.js/blob/8ce25945fac3c3d49a8ec1cc255b2cb0cb94ca89/src/webgl/p5.Shader.js#L849-L852)

So one thing you could do, before switching shaders, is make sure the current active shader is unbound first so that it knows to re-bind if it needs to use it, doing something like `p5Instance._renderer._curShader.unbindShader()`.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 18, 2026, 10:42am UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/3 "2026-09-18T10:42:59Z")

</div>

Thanks for the quick reply I have been doing some experimentation based on your comments.

I added the following code to the draw method removing all references to canvasGUI

```js
    const shader = p5.instance._renderer._curShader;
    const had = Boolean(shader)
    shader?.unbindShader(); // Does not appear to unbind the shader
    const has = Boolean(p5.instance._renderer._curShader);
    const same = (shader === p5.instance._renderer._curShader);
    console.log(`Current shader existed? ${had} and still there? ${has} same one? ${same} `);

```

the result was

> `Current shader existed? true and still there? true same one? true`

in other words the shader was not unbound from the renderer.

Even if it was just down to setting the current shader it doesn’t explain why some of my sketches worked and others didn’t. `🤔

Looking at the error messages it would seem to be a texture problem so I tried to add a texture for the spheres in the above example and I got the same problem. It appears to problem with linking to textures.

I need a break, my brains melting LOL

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 18, 2026, 11:05am UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/4 "2026-09-18T11:05:45Z")

</div>

The code below (TypeScript) is part of the `GUI` [class](https://github.com/quarks/canvasGUI/blob/main/src_ts/canvas_gui.ts) and shows the creation and use of the shader program to overlay the webgl canvas.

**This method (lines 263 - 312) creates the shader program and is called when a GUI object is instantiated for a webgl2 canvas**

```js
  /**
   * Create the shader program to overlay a 2D HUD over a 3D canvas
   * Based on code provided by @scudly
   * @hidden
   */
  _createGuiShaderProgram() {
    const gl = this._canvasContext;

    // Vertex shader program
    const vsSource = `
    precision mediump float;

    uniform vec2 uScale;
    attribute vec3 aVertexPosition;
    varying vec2 vTextureCoord;

    void main(void) {
        gl_Position = vec4(aVertexPosition, 1.0);
        vTextureCoord.x = (1.0 + aVertexPosition.x) * 0.5;
        vTextureCoord.y = (1.0 - aVertexPosition.y) * 0.5;
    }
    `;

    // Fragment shader program
    const fsSource = `
    precision mediump float;

    varying vec2 vTextureCoord;
    uniform sampler2D uSampler;

    void main(void) {
        gl_FragColor = texture2D(uSampler, vTextureCoord);
    }
    `;

    // Compile shaders and link the program
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vsSource);
    gl.compileShader(vertexShader);

    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fsSource);
    gl.compileShader(fragmentShader);

    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    return shaderProgram;
  }

```

**This method (lines 226- 261) is called to overlay the gui buffer image each frame**

```js
  /**
   * Show GUI over a 'webgl2' canvas
   * Based on code provided by @scudly
   * @hidden
   */
  _showOverWebGL() {
    const gl = this._canvasContext;
    // Create texture from 2D canvas
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
      this._uiBuffer);
    gl.generateMipmap(gl.TEXTURE_2D);

    // Create and bind a buffer for the vertices
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, GUI.VERTS, gl.STATIC_DRAW);

    gl.useProgram(this._guiShader);

    // Bind vertex position attribute
    const position = gl.getAttribLocation(this._guiShader, 'aVertexPosition');
    gl.enableVertexAttribArray(position);
    gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);

    // Set the texture sampler uniform
    const uSampler = gl.getUniformLocation(this._guiShader, 'uSampler');
    gl.uniform1i(uSampler, 0);

    gl.clear(gl.DEPTH_BUFFER_BIT);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    gl.disable(gl.BLEND);
  }

```

---

<div class="post-metadata">

**Author:** ![davepagurek](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/davepagurek/32/17535_2.png) [@davepagurek](https://discourse.processing.org/u/davepagurek)\
**Post date:** [September 18, 2026, 11:12am UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/5 "2026-09-18T11:12:03Z")

</div>

> [@quark](#):
>
> in other words the shader was not unbound from the renderer.

I’m not sure that this is true. I mentioned before that the shader’s internal `_bound` property is what tracks whether it thinks the shader is the active WebGL shader, and is what controls whether or not p5 tries to reactivate the shader in the WebGL state before using it. So I’d still recommend trying that first, as the error messages all indicate that p5 is trying to set uniforms on shaders that aren’t active, which is directly related to this.

For why some sketches don’t have the error, did you have links to a sketch with an error and one without?

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 19, 2026, 9:32am UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/6 "2026-09-19T09:32:43Z")

</div>

> [@davepagurek](#):
>
> I mentioned before that the shader’s internal `_bound` property

The shader [unbind](https://github.com/processing/p5.js/blob/8ce25945fac3c3d49a8ec1cc255b2cb0cb94ca89/src/webgl/p5.Shader.js#L859-L865) method sets the shaders `_bound` property to false

> [@davepagurek](#):
>
> For why some sketches don’t have the error, did you have links to a sketch with an error and one without?

There are links in my first post although the p5.js sketch editor does not display error messages in the console I saw them while running on a local server.

I have updated this [sketch](https://editor.p5js.org/quark-js/sketches/uaZmnGgDU) to incorporate your suggestion to unbind the current shader. Lines 8 and 9 control what you want to display

```auto
let showGUI = true;
let showAnim = false;

```

With these settings the gui is displayed and I sketch displays the message  
`Shader exists? false is bound? undefined and stays bound? undefined`

If I just display the animation I get  
`Shader exists? true is bound? false and stays bound? false`

If I attempt to display both I get  
`Shader exists? true is bound? false and stays bound? false `

Just to clarify the situation

1. canvasGUI works as expected in a 100% native JavaScript sketch (no p5.js)
2. canvasGUI has no dependency on or access to p5.js
3. canvasGUI accesses the HTML canvas element and its drawing context directly
4. the`gui.draw()` method does not and cannot access p5.js internal state

If you have the time and inclination this guide describes the inner workings of canvasGUI v3 in some detail. 😁

Now I am a novice when it comes to shaders so I maybe be missing something obvious to more experienced programmers.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 20, 2026, 10:33am UTC](https://discourse.processing.org/t/p5js-inconsistent-shader-behaviour-leading-to-program-crashes/49386/7 "2026-09-20T10:33:04Z")

</div>

@davepagurek thanks for your help I have made some progress but not quite there yet.

canvasGUI V3 was created to remove dependencies on p5.js so it could be used in native JavaScript sketches with or without p5.js

This video shows canvasGUI 3.2.0 working in a native JavaScript sketch without p5.js so that aim was achieved.

[![](https://i.ytimg.com/vi/sqGIFZKSHuM/hqdefault.jpg "canvasGUI using native JavaScript") ](https://www.youtube.com/watch?v=sqGIFZKSHuM)

So now all I need to do is get it to work with p5.js to help with that I have created 2 sketches that should do the same thing with p5.js they can be found here

1. [Rotating square with solid fill](https://www.youtube.com/watch?v=sqGIFZKSHuM)
2. [Rotating square with texture fill](https://editor.p5js.org/quark-js/sketches/JqAMAtnMA)

In both cases pressing the ‘s’ key should make the GUI visible. If you do that in (1) the GUI will display but the background and animation will disappear. In (2) the GUI fails to appear and the background and animation both disappear. In both cases we get the same error messages as shown in my previous posts.

So based on @davepagurek’s advice my first attempt was simply to restore the previous shader program after running the GUI shader -

```js
_showOverWebGL() {
    const gl = this._canvasContext;

    // Remember the current shader program
    const curShaderProgram = gl.getParameter(gl.CURRENT_PROGRAM);

    // Create texture from 2D canvas
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
      this._uiBuffer);
    gl.generateMipmap(gl.TEXTURE_2D);

    // Create and bind a buffer for the vertices
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, GUI.VERTS, gl.STATIC_DRAW);

    gl.useProgram(this._guiShader);

    // Bind vertex position attribute
    const position = gl.getAttribLocation(this._guiShader, 'aVertexPosition');
    gl.enableVertexAttribArray(position);
    gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);

    // Set the texture sampler uniform
    const uSampler = gl.getUniformLocation(this._guiShader, 'uSampler');
    gl.uniform1i(uSampler, 0);

    gl.clear(gl.DEPTH_BUFFER_BIT);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    gl.disable(gl.BLEND);

    // Current attempt to fix my issue
    // Restore the previous shader program 
    if (curShaderProgram)
      gl.useProgram(curShaderProgram);
  }

```

This had limited success in that the sketch without the texture (1) runs as expected.  
🥳

In the case of (2) the GUI failed to appear but the animation continued and no error messages were reported so I suspect there is a logical error in my approach.

I did try unbinding the p5js’s current shader in the `draw` method (see below) but it didn’t make a difference.

```js
function draw() {
    push();
    angle += speed * deltaTime;
    angle %= TWO_PI;

    background(204, 230, 255);

    if (showAnim)
        showAnimation();

    const shdr = p5.instance._renderer._curShader;
    shdr?.unbindShader();

    if (showGUI) 
        gui.draw();
    
}

```

As a novice with shaders this is a baptism of fire for me but I am enjoying the heat and learning a lot so thanks for your help and I hope you can point me in the right direction to the final solution.  
👍😄
