如何在webgl中渲染到整数渲染缓冲区



我在使用webgl2渲染到整数渲染缓冲区时遇到问题。使用底部的示例代码,我得到像素阵列中的所有零,并在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.

当我替换时:

gl.readPixels(
0, 0, 256, 256, 
gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT), 
gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE), 
pixels
);

对于

gl.readPixels(0, 0, 256, 256, gl.RGBA_INTEGER, gl.BYTE, pixels);

错误变为:

WebGL warning: readPixels: `pixels` type does not match `type`.

(在Firefox上,gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE)返回gl.INT而不是gl.BYTE。(

我尝试过在Uint8Array和Int8Array之间更改像素的TypedArray,但没有任何选项可用。我应该注意的是,提供的示例确实适用于Chrome。有没有一种方法可以在Firefox上渲染到int缓冲区,或者它完全被窃听了?

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);

想明白了。无论出于何种原因,Firefox都希望将gl.INT和Int32Array传递给readPixels。请注意,这不符合规范,并且在Chrome上失败。

最新更新