Problem with delete shader for optimization

hey :slight_smile:
I have a big sketch with a lot of shaders that I use at different times.
so for optimizations, I want to delete the PGraphics and the shaders that I don’t want to use anymore.
(As recommended here: WebGL best practices - Web APIs | MDN)
I want to use the function WebGLRenderingContext.deleteShader() as described here:
WebGLRenderingContext.deleteShader() - Web APIs | MDN

but I get this error:
TypeError: pg.deleteShader is not a function
what can I do?
and on that note: do you have any tips for optimizing a lot of shaders in p5? :upside_down_face:

here is the code for the sketch:

let theShader;

function preload() {
  theShader = loadShader("shader.vert", "shader.frag");
}

function setup() {
  pixelDensity(1);
  createCanvas(windowWidth, windowHeight, WEBGL);
  pg = createGraphics(width, height, WEBGL);

  noStroke();
  console.log("DONE SET UP");
}

function draw() {
  push();
  translate(-width / 2, -height / 2);
  pg.shader(theShader);
  theShader.setUniform("u_resolution", [width, height]);

  pg.rect(0, 0, width, height);
  image(pg, 0, 0);
  pop();
}

function keyPressed() {
  pg.deleteShader(theShader);
  pg.remove();
  pg = null;
}

(the shader is the most basic one so I won’t put it here, but here is the editor so its in there and also you can run it there:

thank you

Hi @Omri,

You can access the rendering context from the canvas:

const canvas = createCanvas(400, 400, WEBGL);
canvas.drawingContext.deleteShader(shader);

Source code:

1 Like

thank you for all your help!
I changed it as you suggested, but I needed to declare the canvas as a global parameter, I I couldn’t use const. I wrote like that:

let canvas;
function setup() {
  canvas = createCanvas(windowWidth, windowHeight, WEBGL);
...
}

is that what you meant?
now when I’n trying to delete the shader like that: canvas.drawingContext.deleteShader(theShader);
I get this error:
TypeError: Failed to execute 'deleteShader' on 'WebGLRenderingContext': parameter 1 is not of type 'WebGLShader'.

and in another sketch I’m running not in the web editor I get this error:
Uncaught TypeError: canvas.drawingContext.deleteShader is not a function

I suppose you are using createShader() which is a wrapper around WebGLShader so you can’t pass it directly to deleteShader

Maybe you want to delete both vertex and fragment shader, they are hidden attributes:

const shader = createShader(...);

canvas.drawingContext.deleteShader(shader._vertShader);
canvas.drawingContext.deleteShader(shader._fragShader);

I didn’t tested it but maybe it causes bugs and it’s hacky

2 Likes

@josephh thank you for your help!

I’m using the

canvas.drawingContext.deleteShader(shader._vertShader);
canvas.drawingContext.deleteShader(shader._fragShader);

it fixed the last thing, but now I have this warning:
sketch.js:534 WebGL: INVALID_OPERATION: delete: object does not belong to this context
and it doesn’t delete the shader.

Do you know what is it?

First of all, how many shaders do you have? Do you think it really makes a difference in terms of memory and computation?

Maybe the shader was already deleted by the garbage collector that’s why you can’t delete it again.

1 Like