WebGL drawBuffer输出黑色纹理

问题描述 投票:0回答:1

我试图借助drawBuffers编写简单的webgl多遍程序。我创建2个drawBuffer纹理,并在fragmentShaderPass1中为其分配颜色。 Texture1应该为绿色,Texture2应该为棕色。然后,将这些纹理作为制服传递给fragmentShaderPass2,fragmentShaderPass2使用Texture1的颜色来渲染矩形。问题是矩形总是黑色而不是绿色!我在这里错了吗?

    // STAGE 1
    let fragmentShaderPass1 = `
        #extension GL_EXT_draw_buffers : require
        precision highp float;
        precision highp int;
        precision highp sampler2D;

        void main( void )
        {
            gl_FragData[0] = vec4(.2, .8, .0, 1);  // green
            gl_FragData[1] = vec4(.6, .5, .4, .3);  // brown
        }
    `;
    let pass1_prog = createProgram(gl, globals.vertexShader, fragmentShaderPass1);

    let firstStageFrameBuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, firstStageFrameBuffer);

    gl.useProgram(pass1_prog);

    for (let i = 0; i < 2; i++) 
    {
        let tex = gl.createTexture();
        textures.push(tex);

        gl.bindTexture(gl.TEXTURE_2D, tex);

        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

        // attach texture to framebuffer
        gl.framebufferTexture2D(gl.FRAMEBUFFER, ext.COLOR_ATTACHMENT0_WEBGL + i, gl.TEXTURE_2D, tex, 0);
    }

    gl.disable(gl.DEPTH_TEST); // framebuffer doesn't even have a depth buffer!
    gl.viewport(0, 0, _this.canvas.width, _this.canvas.height); 

    ext.drawBuffersWEBGL([
        ext.COLOR_ATTACHMENT0_WEBGL,
        ext.COLOR_ATTACHMENT1_WEBGL
    ]);

    gl.drawArrays(gl.POINTS, 0, 1); 



    // STAGE 2
    let fragmentShaderPass2 = `
        precision highp float;
        precision highp int;
        precision highp sampler2D;

        uniform sampler2D inColor0;
        uniform sampler2D inColor1;

        void main( void )
        {
            gl_FragColor = texture2D(inColor0, vec2(0.5));
        }
    `;
    let pass2_prog = createProgram(gl, globals.vertexShader, fragmentShaderPass2);

    gl.bindFramebuffer(gl.FRAMEBUFFER, null);

    gl.useProgram(pass2_prog);
    gl.viewport(0, 0, canvas.width, canvas.height); 
    gl.clearColor(1.0, 1.0, 1.0, 1.0);

    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, textures[0]);
    gl.uniform1i(gl.getUniformLocation(pass2_prog, "inColor0"), 0);

    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, textures[1]); 
    gl.uniform1i(gl.getUniformLocation(pass2_prog, "inColor1"), 1);

    gl.drawArrays(gl.POINTS, 0, 1);
javascript webgl framebuffer multipass
1个回答
0
投票

您在上面发布的代码无法使纹理可渲染,并且在the JavaScript console中出现此错误

渲染警告:绑定到纹理单元0的纹理不可渲染。它可能不是2的幂或可能有不兼容的纹理过滤(也许)?

它们是不可渲染的,因为get没有mips,但设置为使用mips。它们也可能不是2维的幂(尽管您没有显示尺寸)。

使其可渲染

  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

使其渲染

const canvas = document.querySelector('canvas');
const _this = {canvas};
const textures = [];
const gl = _this.canvas.getContext('webgl');
const ext = gl.getExtension('WEBGL_draw_buffers');
if (!ext) { alert('need WEBGL_draw_buffers'); }
const globals = {
  vertexShader: `
    void main() {
      gl_Position = vec4(0, 0, 0, 1);
      gl_PointSize = 100.0;
    }
  `,
}
// STAGE 1
let fragmentShaderPass1 = `
  #extension GL_EXT_draw_buffers : require
  precision highp float;
  precision highp int;
  precision highp sampler2D;

  void main( void )
  {
      gl_FragData[0] = vec4(.2, .8, .0, 1);  // green
      gl_FragData[1] = vec4(.6, .5, .4, 1);  // brown
  }
`;
let pass1_prog = createProgram(gl, globals.vertexShader, fragmentShaderPass1);

let firstStageFrameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, firstStageFrameBuffer);

gl.useProgram(pass1_prog);

for (let i = 0; i < 2; i++) {
  let tex = gl.createTexture();
  textures.push(tex);

  gl.bindTexture(gl.TEXTURE_2D, tex);

  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

  // attach texture to framebuffer
  gl.framebufferTexture2D(gl.FRAMEBUFFER, ext.COLOR_ATTACHMENT0_WEBGL + i, gl.TEXTURE_2D, tex, 0);
}

gl.disable(gl.DEPTH_TEST); // framebuffer doesn't even have a depth buffer!
gl.viewport(0, 0, _this.canvas.width, _this.canvas.height);

ext.drawBuffersWEBGL([
  ext.COLOR_ATTACHMENT0_WEBGL,
  ext.COLOR_ATTACHMENT1_WEBGL
]);

gl.drawArrays(gl.POINTS, 0, 1);



// STAGE 2
let fragmentShaderPass2 = `
        precision highp float;
        precision highp int;
        precision highp sampler2D;

        uniform sampler2D inColor0;
        uniform sampler2D inColor1;

        void main( void )
        {
            gl_FragColor = texture2D(inColor0, vec2(0.5));
        }
    `;
let pass2_prog = createProgram(gl, globals.vertexShader, fragmentShaderPass2);

gl.bindFramebuffer(gl.FRAMEBUFFER, null);

gl.useProgram(pass2_prog);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
gl.uniform1i(gl.getUniformLocation(pass2_prog, "inColor0"), 0);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.uniform1i(gl.getUniformLocation(pass2_prog, "inColor1"), 1);

ext.drawBuffersWEBGL([
  gl.BACK,
]);

gl.drawArrays(gl.POINTS, 0, 1);


// ---
function createProgram(gl, vSrc, fSrc) {
  return twgl.createProgram(gl, [vSrc, fSrc]);
}
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

而且我很确定您需要将drawBuffers设置回以将绘图绘制到画布上

    ext.drawBuffersWEBGL([
      gl.BACK,
    ]);
© www.soinside.com 2019 - 2024. All rights reserved.