Skip to content

Fix: Support WebGL2 MRTs#336

Open
Determinated738 wants to merge 1 commit into
stackgl:masterfrom
Determinated738:fix-color-attachments
Open

Fix: Support WebGL2 MRTs#336
Determinated738 wants to merge 1 commit into
stackgl:masterfrom
Determinated738:fix-color-attachments

Conversation

@Determinated738

Copy link
Copy Markdown

This PR fixes a bug where the OverrideDrawBufferEnum helper in src/native/webgl.cc lacked a default return case.

Previously, passing any color attachment index greater than 0 resulted in undefined behavior/garbage values being passed to the driver. This prevented Multiple Render Targets from functioning correctly in WebGL2 contexts.

Minimal code to recreate the bug:

import createGL from "gl";

const gl = createGL(2, 2, { createWebGL2Context: true });
gl.getExtension("EXT_color_buffer_float");

const tex0 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex0);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 2, 2, 0, gl.RGBA, gl.FLOAT, null);

const tex1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 2, 2, 0, gl.RGBA, gl.FLOAT, null);

const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);

gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex1, 0);

gl.drawBuffers([
    gl.COLOR_ATTACHMENT0,
    gl.COLOR_ATTACHMENT1
]);

const vs = `#version 300 es
    in vec2 pos;
    void main() {
        gl_Position = vec4(pos, 0.0, 1.0);
    }`;

const fs = `#version 300 es
    precision highp float;

    layout(location=0) out vec4 out0;
    layout(location=1) out vec4 out1;

    void main() {
        out0 = vec4(1.0, 0.0, 0.0, 1.0);
        out1 = vec4(0.0, 1.0, 0.0, 1.0);
    }`;

function compile(type, src) {
    const s = gl.createShader(type);
    gl.shaderSource(s, src);
    gl.compileShader(s);
    return s;
}

const prog = gl.createProgram();
gl.attachShader(prog, compile(gl.VERTEX_SHADER, vs));
gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, fs));
gl.linkProgram(prog);
gl.useProgram(prog);

const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    -1, -1,
    1, -1,
    -1, 1,
    1, 1,
]), gl.STATIC_DRAW);

const loc = gl.getAttribLocation(prog, "pos");
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);

gl.viewport(0, 0, 2, 2);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

function read(att) {
    gl.readBuffer(att);
    const out = new Float32Array(4);
    gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, out);
    return Array.from(out);
}

const a0 = read(gl.COLOR_ATTACHMENT0);
const a1 = read(gl.COLOR_ATTACHMENT1);

console.log("ATTACHMENT 0:", a0); // Expect [ 1, 0, 0, 1 ]
console.log("ATTACHMENT 1:", a1); // Bug: Expect [ 0, 1, 0, 1] but returns [ 1, 0, 0, 1]

Changes:

Added a default case in OverrideDrawBufferEnum, to make sure standard WebGL 2 attachment enums are passed through to the driver unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant