2

I have a RGBA8UI internal format texture attached to a framebuffer, and somehow I need to reset it to a default value. Unfortunately, a simple gl.clear(gl.COLOR_BUFFER_BIT) does not seem to work, (I suspect the issue is the internal format of the texture), giving this error:

[.WebGL-000020EE00AD4700] GL_INVALID_OPERATION: No defined conversion between clear value and attachment format.

The framebuffer status is FRAMEBUFFER_COMPLETE. Here is a minimal example for jsfiddle:

HTML

<canvas id="canvas"></canvas>    

JS

const gl = document.getElementById('canvas').getContext('webgl2');

let targetTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, targetTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8UI, 1, 1, 0, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, null);

let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, targetTexture, 0);

let fstatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
console.log(fstatus, gl.FRAMEBUFFER_COMPLETE);

gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);

QUESTION

How can I clear/reset the texture?

user445082
  • 59
  • 1
  • 3

2 Answers2

0

Well according to the WebGL 2 spec (Section 3.7.9) you can not clear integer color buffers:

If an integer color buffer is among the buffers that would be cleared, an INVALID_OPERATION error is generated and nothing is cleared.

So you have to either call texImage2D again like you already did:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8UI, 1, 1, 0, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, null);

or (maybe more efficient) use a screenspace quad and a fragment-shader to write a constant value of your liking.

LJᛃ
  • 7,655
  • 2
  • 24
  • 35
0

I just ran into this myself. clear does not work for integer formats. Instead you can use:

gl.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);

There's also clearBufferiv for signed integer formats, clearBufferfv for float formats and depth, and clearBufferfi specifically for DEPTH_STENCIL formats.

Docs are here: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glClearBuffer.xhtml

James Darpinian
  • 103
  • 1
  • 5