我的目标是使用gl.frameBufferTextureLayer
将切片渲染到3D纹理。但是,当我使用gl.readPixels
回读数据时,不会呈现任何内容。
当我将gl.TEXTURE_3D
更改为gl.TEXTURE_2D_ARRAY
时,它可以正常工作,但在测试here中,他们肯定会在FBO上附加一层3D纹理。 WebGL docs并没有说明纹理应该是什么,但是
GLES3 docs允许纹理确定为3D纹理。我已经检查了帧缓冲完整状态和所有这些东西......
是否有任何资源可以将3D纹理图层附加到WebGL2中的FBO,这是否可能?一些代码:
this.fbo= gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo);
this.colorTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, this.colorTexture);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, 64, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
this.renderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 64, 64);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
// Use level 1 in 3D texture
// Works when texture is GL_TEXTURE_2D_ARRAY
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, this.texture, 0, 1);
// ... Render scene
let data = new Uint8Array(64 * 64 * 4);
gl.readPixels(0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, data, 0); // data is empty
答案 0 :(得分:1)
首先让我们尝试一个简单的无渲染
const gl = document.createElement("canvas").getContext("webgl2");
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, 2, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, 1);
gl.clearColor(.25, .5, .75, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
const data = new Uint8Array(2 * 2 * 4);
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data);
console.log(data);

有效
现在让我们尝试渲染
const gl = document.createElement("canvas").getContext("webgl2");
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, 2, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, 1);
const vs = `
#version 300 es
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 4.0;
}
`;
const fs = `
#version 300 es
precision mediump float;
out vec4 color;
void main() {
color = vec4(.75, .5, .25, 1);
}
`
const prg = twgl.createProgram(gl, [vs, fs]);
gl.useProgram(prg);
gl.viewport(0, 0, 2, 2);
gl.drawArrays(gl.POINTS, 0, 1);
const data = new Uint8Array(2 * 2 * 4);
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data);
console.log(data);

<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
&#13;
也有效。
让我们试试深度缓冲区
const gl = document.createElement("canvas").getContext("webgl2");
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, 2, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, 1);
const rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 2, 2);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
const vs = `
#version 300 es
uniform float depth;
void main() {
gl_Position = vec4(0, 0, depth, 1);
gl_PointSize = 4.0;
}
`;
const fs = `
#version 300 es
precision mediump float;
uniform vec4 color;
out vec4 outColor;
void main() {
outColor = color;
}
`
const prgInfo = twgl.createProgramInfo(gl, [vs, fs]);
gl.useProgram(prgInfo.program);
gl.viewport(0, 0, 2, 2);
gl.enable(gl.DEPTH_TEST);
// draw in middle
twgl.setUniforms(prgInfo, {
depth: 0,
color: [1, 0, 0, 1],
});
gl.drawArrays(gl.POINTS, 0, 1);
// draw in front
twgl.setUniforms(prgInfo, {
depth: -.5,
color: [0, 1, 0, 1],
});
gl.drawArrays(gl.POINTS, 0, 1);
// draw in back
twgl.setUniforms(prgInfo, {
depth: .5,
color: [0, 0, 1, 1],
});
gl.drawArrays(gl.POINTS, 0, 1);
// should be front color (0, 255, 0, 255)
const data = new Uint8Array(2 * 2 * 4);
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data);
console.log(data);
&#13;
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
&#13;
似乎工作
也许您忘了设置视口?我经常犯这个错误