如何在两个纹理之间交替?

时间:2016-08-07 20:54:01

标签: javascript textures webgl framebuffer

我正在尝试绘制一个纹理,这样渲染就会在彼此之上复杂化。 我正在使用两个纹理和两个帧缓冲区。 texture [0]附加到framebuffer [0],纹理[1]附加到framebuffer [1]。

    var gl = webgl.context;

    gl.useProgram(this.program);

    gl.bindTexture(gl.TEXTURE_2D, this.texture[this.pingpong]);
    this.pingpong = (this.pingpong==0?1:0);
    var pp = this.pingpong;

    gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer[pp]);

    gl.drawArrays(gl.TRIANGLES, 0, 6);              //primitiveType, offset, count

    gl.bindTexture(gl.TEXTURE_2D, this.texture[pp]);        //bind to the texture we just drew to
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);               //render the above texture to the canvas

    gl.drawArrays(gl.TRIANGLES, 0, 6);

问题是,我没有看到之前的渲染被保存到纹理中。 我认为bindframebuffer()会使它渲染到纹理。 我的片段着色器:

precision mediump float;                                    // fragment shaders don't have a default precision so we need to pick one. mediump is a good default

    varying vec2 v_texCoord;                                    // the texCoords passed in from the vertex shader.

    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;

    uniform sampler2D u_image;                              // this isn't set, so it will default to 0 (the current active texture)
void main() {       

        vec4 texColor = texture2D(u_image, v_texCoord);         // Look up a color from the texture.

        vec2 coord = vec2(gl_FragCoord.x,u_resolution.y-gl_FragCoord.y);

        vec4 color = step(distance(coord,u_mouse),100.0)*vec4(1,0,0,1) + step(100.0,distance(coord,u_mouse))*texColor;


        gl_FragColor = color;                   // gl_FragColor is a special variable a fragment shader is responsible for setting
    }

u_image设置为默认值0,即活动纹理。

我有什么东西可以俯瞰吗?为什么之前的渲染不能相互叠加?它只是显示最新的渲染,好像纹理没有被改变。

这是顶点着色器:

precision mediump float;

    attribute vec2 a_position;                                  // an attribute will receive data from a buffer
    attribute vec2 a_texCoord;
    varying vec2 v_texCoord;                                    // a varying 
    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    // all shaders have a main function
    void main() {
        v_texCoord = a_texCoord;                                // pass the texCoord to the fragment shader.The GPU will interpolate this value between points

        vec2 zeroToOne = a_position / u_resolution;     // convert the position from pixels to 0.0 to 1.0
        vec2 zeroToTwo = zeroToOne * 2.0;               // convert from 0->1 to 0->2
        vec2 clipSpace = zeroToTwo - 1.0;                   // convert from 0->2 to -1->+1 (clipspace)

        // gl_Position is a special variable a vertex shader is responsible for setting
        gl_Position = vec4(clipSpace * vec2(1, u_flip), 0, 1);
    }

2 个答案:

答案 0 :(得分:0)

我试图模仿你在做什么:

loop.flexStep = function(){
    gl.clear(gl.COLOR_BUFFER_BIT);

    pingPong.pingPong().applyPass( //pingPong() just swaps the FBOs and return the current FBO being draw to
        "outColor += src0 * 0.98;",
        pingPong.otherTexture() // the src0 texture
    );
    points.drawPoint([mouse.x, mouse.y, 0 ]);
    points.renderAll(camera); 

    screenBuffer.applyPass(
        "outColor = src0;",
        pingPong.resultFBO  // src0
    );
};

这是它的样子(gl.POINTS而不是圆圈): enter image description here

以下是gl命令: enter image description here

您应该首先检查您的帧缓冲区是否设置正确。由于那部分没有显示,很难说。

还要考虑分离您的着色器。你应该在乒乓球阶段有一个着色器将先前纹理的结果复制/改变为当前的pingPong FBO纹理。另一个着色器将新东西绘制到当前的pingPong FBO纹理中。

答案 1 :(得分:0)

问题似乎是获取错误的纹理坐标并且还会翻转纹理。 它现在按预期工作。

这里是更新的顶点/片段着色器:

this.vertex = `
    precision mediump float;

    attribute vec2 a_position;                                  // an attribute will receive data from a buffer
    attribute vec2 a_texCoord;
    varying vec2 v_texCoord;                                    // a varying 
    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    // all shaders have a main function
    void main() {
        v_texCoord = a_texCoord / u_resolution;                             // pass the texCoord to the fragment shader.The GPU will interpolate this value between points

        vec2 zeroToOne = a_position / u_resolution;     // convert the position from pixels to 0.0 to 1.0
        vec2 zeroToTwo = zeroToOne * 2.0;               // convert from 0->1 to 0->2
        vec2 clipSpace = zeroToTwo - 1.0;                   // convert from 0->2 to -1->+1 (clipspace)

        // gl_Position is a special variable a vertex shader is responsible for setting
        gl_Position = vec4(clipSpace * vec2(1, u_flip), 0, 1);
    }

`;

this.fragment = ` 

    precision mediump float;                                    // fragment shaders don't have a default precision so we need to pick one. mediump is a good default

    varying vec2 v_texCoord;                                    // the texCoords passed in from the vertex shader.

    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    uniform sampler2D u_image;                              // this isn't set, so it will default to 0 (the current active texture)
    uniform sampler2D u_texture0;
    uniform sampler2D u_texture1;

    void main() {       

        vec4 texColor = texture2D(u_image, v_texCoord);         // Look up a color from the texture.

        vec2 coord = vec2(gl_FragCoord.x, step(0.0,u_flip)*gl_FragCoord.y + step(u_flip,0.0)*(u_resolution.y-gl_FragCoord.y) );

        vec4 color = step(distance(coord,u_mouse),100.0)*vec4(1,0,0,1) + step(100.0,distance(coord,u_mouse))*texColor;


        gl_FragColor = color;                   // gl_FragColor is a special variable a fragment shader is responsible for setting
    }

`;