Tengo problemas para usar webgl2 para renderizar en un búfer de renderizado entero. Usando el código de ejemplo en la parte inferior, obtengo ceros en la matriz de píxeles y el siguiente error en Firefox:
WebGL warning: readPixels: Format and type RGBA_INTEGER/<enum 0x1400> incompatible with this RGBA8I attachment. This framebuffer requires either RGBA_INTEGER/INT or getParameter(IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE) RGBA_INTEGER/INT.Cuando sustituyo:
gl.readPixels( 0, 0, 256, 256, gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT), gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE), pixels );por
gl.readPixels(0, 0, 256, 256, gl.RGBA_INTEGER, gl.BYTE, pixels);El error se convierte en:
WebGL warning: readPixels: `pixels` type does not match `type`. (En Firefox, gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) devuelve gl.INT en lugar de gl.BYTE).
Intenté cambiar TypedArray para píxeles entre Uint8Array e Int8Array, pero ninguna opción funciona. Debo señalar que el ejemplo proporcionado funciona en Chrome. ¿Hay alguna manera de renderizar en el búfer int en Firefox o está completamente defectuoso?
const gl = document.getElementById('target').getContext('webgl2', { preserveDrawingBuffer: true }); const prog = gl.createProgram() const vert = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vert, `#version 300 es in vec2 a_position; void main() { gl_Position = vec4(a_position, 0., 1.); }`); gl.compileShader(vert); gl.attachShader(prog, vert); const frag = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(frag, `#version 300 es precision highp isampler2D; out ivec4 color; void main() { color = ivec4(255, 0, 0, 255); }`); gl.compileShader(frag); gl.attachShader(prog, frag); gl.linkProgram(prog); const vao = gl.createVertexArray(); gl.bindVertexArray(vao) const buff = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buff); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([-1,-1, -1,1, 1,-1, 1,1, -1,1, 1,-1]), gl.STATIC_DRAW ); const pos = gl.getAttribLocation(prog, 'a_position'); gl.enableVertexAttribArray(pos); gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0) const rbo = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8I, 256, 256); const fbo = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo ); gl.viewport(0, 0, 256, 256); gl.clearColor(0,0,0,0); gl.clear(gl.COLOR_BUFFER_BIT); gl.disable(gl.DEPTH_TEST); gl.useProgram(prog); gl.drawBuffers([gl.COLOR_ATTACHMENT0]); gl.drawArrays(gl.TRIANGLES, 0, 6); gl.readBuffer(gl.COLOR_ATTACHMENT0); const pixels = new Int8Array(256 ** 2 * 4); gl.readPixels(0, 0, 256, 256, gl.RGBA_INTEGER, gl.BYTE, pixels); console.log(pixels);Lo averigué. Por alguna razón, Firefox quiere que gl.INT e Int32Array pasen a readPixels. Tenga en cuenta que esto no cumple con las especificaciones y falla en Chrome.