How to write to a framebuffer in regl?

1k Views Asked by At

I am trying to update the texture inside a framebuffer in REGL. But for some reason, it does not update the framebuffer.

here is the full code:

const regl = createREGL({
  extensions: 'OES_texture_float'
})

const initialTexture = regl.texture([
  [
    [0, 255, 0, 255]
  ]
])

const fbo = regl.framebuffer({
  color: initialTexture,
  depth: false,
  stencil: false,
})

const updateColor = regl({
  framebuffer: () => fbo,
  vert: `
    precision mediump float;
  
    attribute vec2 position;

    void main() {
      gl_Position = vec4(position, 0.0, 1.0);
    }
 `,
  frag: `
    precision mediump float;

    void main() {
      gl_FragColor = vec4(255.0, 0.0, 0.0, 255.0);
    }
 `,
  attributes: {
    // a triangle big enough to fill the screen
    position: [
     -4, 0,
      4, 4,
      4, -4
    ],
  },

  count: 3,
})

regl.clear({
  // background color (black)
  color: [0, 0, 0, 1],
  depth: 1,
});

updateColor(() => {
  console.log(regl.read())
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.11/regl.min.js"></script>

  • I set the initialTexture to green.
  • In the updateColor command I specify the framebuffer making regl render to the framebuffer
  • The fragment shader in updateColor renders a red color
  • After the updateColor command has run, I expected the initialTexture to be red, but it stays green.

What am I doing wrong?

1

There are 1 best solutions below

1
On BEST ANSWER

Apparently if you provide a function to a regl command then you have to manually draw

updateColor(() => {
  regl.draw();   // manually draw
  console.log(regl.read())
});

I guess the point is if you provided a function then you're asking to customize stuff?

const regl = createREGL({
  extensions: 'OES_texture_float'
})

const initialTexture = regl.texture([
  [
    [0, 255, 0, 255]
  ]
])

const fbo = regl.framebuffer({
  color: initialTexture,
  depth: false,
  stencil: false,
})

const updateColor = regl({
  framebuffer: () => fbo,
  vert: `
    precision mediump float;
  
    attribute vec2 position;

    void main() {
      gl_Position = vec4(position, 0.0, 1.0);
    }
 `,
  frag: `
    precision mediump float;

    void main() {
      gl_FragColor = vec4(255.0, 0.0, 0.0, 255.0);
    }
 `,
  // Here we define the vertex attributes for the above shader
  attributes: {
    // regl.buffer creates a new array buffer object
    position: regl.buffer([
      [-2, -2],   // no need to flatten nested arrays, regl automatically
      [4, -2],    // unrolls them into a typedarray (default Float32)
      [4,  4]
    ])
    // regl automatically infers sane defaults for the vertex attribute pointers
  },
  count: 3,
})

regl.clear({
  // background color (black)
  color: [0, 0, 0, 1],
  depth: 1,
});

updateColor(() => {
  regl.draw();
  console.log(regl.read())
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.11/regl.js"></script>

As for how I found the answer I first checked that drawArrays and/or drawElements was being called by adding

WebGLRenderingContext.prototype.drawArrays = function() {
  console.log('drawArrays');
}

and similar for drawElements and I saw that it was never being called.

I tried the sample in the regl readme and it did.

Then I stepped though the code in the debugger, it wasn't that deep to see it never called drawXXX but if removed the function from updateColor it did call drawXXX. As for how to know that regl.draw() would fix it that was a guess. It is mentioned in the docs but it's not clear that's what's right to do