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...