Render to Multiple Multi-sampled attachments
by Cody Bennett
HTML
<script src="https://twgljs.org/dist/4.x/twgl.min.js"</script>
JavaScript
const vs = `#version 300 es
void main() {
gl_PointSize = 10.0;
gl_Position = vec4(0, 0, 0, 1);
}
`;
const fs = `#version 300 es
precision mediump float;
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 picking;
void main() {
color = vec4(1, 0, 0, 1);
picking = vec4(0, 1, 0, 1);
}
`;
function main() {
// make the canvas non-multi sampled by setting it to
// antialias: false, otherwise we can't blit to it.
// (of course we could blit to our own non-multi-sampled
// texture)
const gl = document.createElement('canvas').getContext('webgl2', {antialias: false});
if (!gl) {
return log("need webgl2");
}
gl.viewport(0, 0, 1, 1);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const width = 1;
const height = 1;
const samples = 2;
const renderbuffers = [
{ format: gl.RGBA8, attach: gl.COLOR_ATTACHMENT0, },
{ format: gl.RGBA8, attach: gl.COLOR_ATTACHMENT1, },
{ format: gl.DEPTH_COMPONENT32F, attach: gl.DEPTH_ATTACHMENT, },
].map((info) => {
const rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorageMultisample(
gl.RENDERBUFFER,
samples,
info.format,
width, height);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferRenderbuffer(
gl.FRAMEBUFFER,
info.attach,
gl.RENDERBUFFER,
rb);
return rb;
});
if (!isFBGood(gl)) {
return;
}
const program = twgl.createProgram(gl, [vs, fs]);
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
gl.COLOR_ATTACHMENT1,
]);
gl.useProgram(program);
gl.drawArrays(gl.POINTS, 0, 1);
// now read them out.
function readColorBuffer(renderbuffer) {
const readFB = gl.createFramebuffer();
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFB);
gl.framebufferRenderbuffer(
gl.READ_FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.RENDERBUFFER,
renderbuffer);
// bit to...