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

时间:2022-03-25 03:26:55

I'm trying to draw to a texture, so that the rendering keeps getting compounded on top of each other. I'm using two textures and two framebuffers. texture[0] is attached to framebuffer[0], and texture[1] is attached to framebuffer[1].

我正在尝试绘制一个纹理,这样渲染就会在彼此之上复杂化。我正在使用两个纹理和两个帧缓冲区。 texture [0]附加到framebuffer [0],而texture [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);

The issue, is that I'm not seeing the previous renders get saved into the textures. I thought that bindframebuffer() would make it render to the texture. my fragment shader:

问题是,我没有看到之前的渲染被保存到纹理中。我认为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 is set to default 0, the active texture.

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

Is there something I'm overlooking? Why won't the previous renders get compounded on top of each other? It is just showing the latest render as if the textures haven't been altered.

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

here is the vertex shader:

这是顶点着色器:

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 个解决方案

#1


0  

I tried to emulate what you are doing:

我试图模仿你在做什么:

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
    );
};

Here is what it looks like (gl.POINTS instead of circle): 如何在两个纹理之间交替?

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

Here are the gl commands: 如何在两个纹理之间交替?

以下是gl命令:

You should check if your framebuffers are setup correctly first. Since that part isnt shown its hard to say.

你应该先检查你的framebuffers是否设置正确。由于那部分没有显示,很难说。

Also consider to separate your shader. You should have one shader in the pingpong stage to copy/alter the result of previous texture to the current pingPong FBO texture. And another shader to draw the new stuff to the current pingPong FBO texture.

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

#2


0  

Issue seemed to be with getting the wrong texture coordinate and also flipping the texture. It's working as expected now.

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

here's the updated vertex/fragment shaders:

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

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
    }

`;

#1


0  

I tried to emulate what you are doing:

我试图模仿你在做什么:

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
    );
};

Here is what it looks like (gl.POINTS instead of circle): 如何在两个纹理之间交替?

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

Here are the gl commands: 如何在两个纹理之间交替?

以下是gl命令:

You should check if your framebuffers are setup correctly first. Since that part isnt shown its hard to say.

你应该先检查你的framebuffers是否设置正确。由于那部分没有显示,很难说。

Also consider to separate your shader. You should have one shader in the pingpong stage to copy/alter the result of previous texture to the current pingPong FBO texture. And another shader to draw the new stuff to the current pingPong FBO texture.

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

#2


0  

Issue seemed to be with getting the wrong texture coordinate and also flipping the texture. It's working as expected now.

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

here's the updated vertex/fragment shaders:

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

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
    }

`;