2016-08-07 53 views
0

Ich versuche, auf eine Textur zu zeichnen, so dass das Rendering immer wieder übereinander gelegt wird. Ich verwende zwei Texturen und zwei Framebuffer. Textur [0] ist an Framebuffer [0] angehängt und Textur [1] ist an Framebuffer [1] angehängt.Wie kann man zwischen zwei Texturen wechseln?

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

Das Problem ist, dass ich rendert in die Texturen gerettet werden den vorherigen nicht zu sehen bin. Ich dachte, dass bindframebuffer() es auf die Textur rendern würde. meine Fragment-Shader:

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 gesetzt 0, die aktive Textur auf Standard.

Gibt es etwas, das ich übersehen habe? Warum werden die vorherigen Rendern nicht miteinander kombiniert? Es zeigt nur den neuesten Render, als ob die Texturen nicht verändert wurden.

hier ist der 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); 
    } 
+0

Können Sie erklären, was Sie erwarten, dass der Shader zu tun? Zeichnen Sie einen roten (+ Farbe aus einer anderen Textur) Kreis um den Mauszeiger? –

+0

Ja, es zieht einen roten Kreis um den Mauszeiger, wenn ich die Maus bewege. Ich möchte, dass es die vorherigen Züge behält, aber es tut es aus irgendeinem Grund nicht, deshalb erhalte ich nur einen roten Kreis und nicht eine Reihe von Kreisen, aus denen die Maus gezogen ist. Ich verwende zwei Texturen und zwei Framebuffer, von denen ich dachte, dass sie zum Zeichnen des Kreises verwendet werden könnten, und wechsle dann zwischen ihnen, sodass die vorherigen Zeichnungen erhalten bleiben, aber es funktioniert nicht. Ich verstehe nicht warum. – user3591153

+0

Was mich betrifft ist, dass es scheint, als ob die Texturen ihre Daten nicht erhalten. Wenn ich zu ihnen zeichne, wenn ich den Framebuffer binde, dann, wenn ich später die Textur binde, um die Farbe zu erhalten, sollte es das vorher gerenderte Bild haben, richtig? Aber wenn ich ihre Farbe lese, scheint sie nicht das zu haben, was vorher gerendert wurde - sie ist einfach leer. – user3591153

Antwort

0

Ich habe versucht, was Sie tun, zu emulieren:

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

Hier ist, wie es ist (gl.POINTS statt Kreis) aussieht: enter image description here

Hier sind die gl Befehle: enter image description here

Sie sollten zuerst überprüfen, ob Ihre Framebuffer korrekt eingerichtet sind. Da dieser Teil nicht gezeigt wird, ist es schwer zu sagen.

Denken Sie auch daran, Ihren Shader zu trennen. Sie sollten einen Shader in der Pingpong-Phase haben, um das Ergebnis der vorherigen Textur in die aktuelle pingPong FBO-Textur zu kopieren. Und ein weiterer Shader, um die neuen Sachen in die aktuelle pingPong FBO Textur zu zeichnen.

+0

danke- Ich habe es geschafft, das Problem zu finden. Es wurde nicht die richtige Texturkoordinate ausgewählt, und es mussten auch einige Probleme beim Umblättern behoben werden. – user3591153

+0

Froh, dass Sie Ihr Problem behoben haben. Ich denke, dass Sie die oben beschriebene Struktur implementieren sollten, wenn Sie Pingpong-Puffer verwenden möchten, um andere interessante Effekte zu implementieren. –

+0

Ich werde versuchen, Ihre Struktur zu verstehen- Ich bin relativ neu zu Webgl, und ich habe Schwierigkeiten, die Muster in Ihrer Form zu erkennen. Es scheint etwas fortgeschrittener zu sein als das, was ich im Moment handhaben kann. Vielleicht können Sie mich auf ein gutes Tutorial oder einen Lösungsvorschlag für die Art der Strukturierung hinweisen, die Sie vorschlagen? – user3591153

0

Problem schien mit der falschen Textur Koordinate zu bekommen und auch die Textur spiegeln. Es funktioniert jetzt wie erwartet.

hier die aktualisierten Vertex/Fragment-Shader:

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 
    } 

`;