WebGL: INVALID_VALUE: texImage2D: invalid internalformat - depthTexture in webgl2

846 views Asked by At
const depthTextures = gl => {
  const depthTexture = gl.createTexture();
  const depthTextureSize = 512;
  gl.bindTexture(gl.TEXTURE_2D, depthTexture);
  gl.texImage2D(gl.TEXTURE_2D, // target
  0, // mip level
  gl.DEPTH_COMPONENT, // internal format
  depthTextureSize, // width
  depthTextureSize, // height
  0, // border
  gl.DEPTH_COMPONENT, // format
  gl.UNSIGNED_INT, // type
  null); // data

  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  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);
  const depthFramebuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, depthFramebuffer);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, // target
  gl.DEPTH_ATTACHMENT, // attachment point
  gl.TEXTURE_2D, // texture target
  depthTexture, // texture
  0); // mip level
  // create a color texture of the same size as the depth texture
  // see article why this is needed_

  const unusedTexture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, unusedTexture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, depthTextureSize, depthTextureSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  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); // attach it to the framebuffer

  gl.framebufferTexture2D(gl.FRAMEBUFFER, // target
  gl.COLOR_ATTACHMENT0, // attachment point
  gl.TEXTURE_2D, // texture target
  unusedTexture, // texture
  0); // mip level

  return [depthFramebuffer, unusedTexture];
};

I found

Note: This extension is only available to WebGL1 contexts. In WebGL2, the functionality of this extension is available on the WebGL2 context by default. The constant in WebGL2 is gl.UNSIGNED_INT_24_8.

I change DEPTH_COMPONENT with RGBA but still no attaced framebuffer...

In other combination i get :

gl.texImage2D(
    gl.TEXTURE_2D,      // target
    0,                  // mip level
    gl.RGBA, // internal format
    depthTextureSize,   // width
    depthTextureSize,   // height
    0,                  // border
    gl.RGBA, // format
    gl.UNSIGNED_INT_24_8,    // type
    null);              // data
 GL_INVALID_OPERATION: Invalid combination of format, type and internalFormat.

 GL_INVALID_OPERATION: Only array uniforms may have count > 1.

Any suggestion ?

This is source which i wanna implement in my own already exist glmatrix project...

1

There are 1 answers

3
Rabbid76 On BEST ANSWER

The internal format of a depth texture cannot be RGBA, it must be one of the size internal formats e.g. (GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F) . If the source format is GL_DEPTH_COMPONENT, the source type must be either FLOAT or one of the unsigned integral types. The internal format must be one of the valid combinations together with the format and type, (see OpenGL ES 3.0 glTexImage2D). Valid textures for an gl.DEPTH_ATTACHMENT are therefore e.g.:

gl.texImage2D(
    gl.TEXTURE_2D, 0, 
    gl.GL_DEPTH_COMPONENT24, 
    depthTextureSize, depthTextureSize, 0,
    gl.GL_DEPTH_COMPONENT, gl.GL_UNSIGNED_INT,
    null);
gl.texImage2D(
    gl.TEXTURE_2D, 0, 
    gl.GL_DEPTH_COMPONENT32F, 
    depthTextureSize, depthTextureSize, 0,
    gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT,
    null);

Alternatively, you can use a combined depth and stencil texture (in this case it is a gl.DEPTH_STENCIL_ATTACHMENT instead of a gl.DEPTH_ATTACHMENT), e.g:

gl.texImage2D(
    gl.TEXTURE_2D, 0, 
    gl.GL_DEPTH24_STENCIL8, 
    depthTextureSize, depthTextureSize, 0,
    gl.GL_DEPTH_STENCIL, gl.GL_UNSIGNED_INT_24_8,
    null);