Multipass rendering with glsl

Hi,

I have these shaders:

vertex2.vert:


void main()
{
   gl_Position = ftransform();
   gl_TexCoord[0]  = gl_MultiTexCoord0;
}


fragment2.frag:


void main ()
{
   gl_FragColor=vec4(0.0,0.0,1.0,1.0);
}


fragment3.frag


uniform sampler2D texSampler;
void main ()
{
   vec4 color=texture2D(texSampler, gl_TexCoord[0].st);
   gl_FragColor=color+vec4(0.0,1.0,0.0,0.0);
}


and simpleSetup():


public void simpleSetup() {
         Quad oQuad=new Quad("myQuad",width,height);
         Texture oTexture=new Texture();
         TextureState oState=renderer.createTextureState();
         oState.setEnabled(true);
         oState.setTexture(oTexture,0);
         FloatBuffer texCoords = BufferUtils.createVector2Buffer(4);
         texCoords.put(-1).put(-1);
           texCoords.put(-1).put(1);
           texCoords.put(1).put(1);
           texCoords.put(1).put(-1);
         oQuad.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         oQuad.setTextureBuffer(0, texCoords);
                        oQuad.setRenderState(oState);
         so=renderer.createGLSLShaderObjectsState();
         so.load(getClass().getClassLoader().getResource(
            "vertex2.vert"),
            getClass().getClassLoader().getResource(
                    "fragment2.frag"));
         so.setEnabled(true);
         RenderPass rp1 = new RenderPass();
         rp1.setPassState(so);
         rp1.add(oQuad);
         rp1.setEnabled(true);
         GLSLShaderObjectsState so2=renderer.createGLSLShaderObjectsState();
         so2.setUniform("texSampler", 0);
         so2.load(getClass().getClassLoader().getResource(
            "vertex2.vert"),
            getClass().getClassLoader().getResource(
                    "fragment3.frag"));
         so2.setEnabled(true);
         RenderPass rp2=new RenderPass();
         rp2.add(oQuad);
         rp2.setEnabled(true);
         rp2.setPassState(so2);
         
         passManager = new BasicPassManager();
         passManager.add(rp1);
         passManager.add(rp2);
         rootNode.attachChild(oQuad);
         rootNode.updateRenderState();
      }



The first shader (fragment2.frag) makes the quad blue and that works. The second one (fragment3.frag )should take the color of the first one and add a value with cyan als result. With that, I get a green screen. Here is, what I have done with rendermonkey:
I also tried something like rp1.setPassState(oState);, but it doesn't work. How do I set render targets correctly or what do I have to fix that I get a cyan image and not a blue or a green one?

Best,
Andreas

What you are seeing is the second pass replacing the first one. You will need to set an alpha state so that the two passes are added together.



EDIT: Your oTexture is empty, so its not not used for anything. If you want to render the first pass to that texture and use it in the second pass, then you need to use TextureRenderer.

perhaps render to a texture and use the texture as input for the next pass… Should be able to do that all on the graphics card  :?

yup, render the stuff to a texture, then feed that texture to the next shader.

look in WaterRenderPass.

Hi,

thx to all for your help! Here is my solution:



public void simpleSetup() {
         oTexture=new Texture();
         TextureState oState=renderer.createTextureState();
         oState.setEnabled(true);
         oState.setTexture(oTexture,0);
         FloatBuffer texCoords = BufferUtils.createVector2Buffer(4);
         texCoords.put(-1).put(-1);
           texCoords.put(-1).put(1);
           texCoords.put(1).put(1);
           texCoords.put(1).put(-1);
           oQuad=new Quad("myQuad",width,height);
           oQuad.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         oQuad.setTextureBuffer(0, texCoords);
         oQuad.setRenderState(oState);
         oTextureRenderer=DisplaySystem.getDisplaySystem().createTextureRenderer(width, height,TextureRenderer.RENDER_TEXTURE_2D);
         oTextureRenderer.setupTexture(oTexture);
         so=renderer.createGLSLShaderObjectsState();
         so.load(getClass().getClassLoader().getResource(
            "vertex2.vert"),
            getClass().getClassLoader().getResource(
                    "fragment2.frag"));
         so.setEnabled(true);
         oQuad2=new Quad("myQuad2",width,height);
         oQuad2.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad2.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         oQuad2.setTextureBuffer(0, texCoords);         
         oQuad2.setRenderState(so);
         oQuad2.updateRenderState();

         GLSLShaderObjectsState so2=renderer.createGLSLShaderObjectsState();
         so2.load(getClass().getClassLoader().getResource(
            "vertex2.vert"),
            getClass().getClassLoader().getResource(
                    "fragment3.frag"));
         so2.setEnabled(true);
         so2.setUniform("texSampler", 0);
         
         oQuad3=new Quad("myQuad3",width,height);
         oQuad3.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad3.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         oQuad3.setTextureBuffer(0, texCoords);
         oQuad3.setRenderState(so2);
         oQuad3.updateRenderState();
         rootNode.attachChild(oQuad);
         rootNode.updateRenderState();
         oTextureRenderer.render(oQuad2, oTexture, true);
         oTextureRenderer.render(oQuad3, oTexture, false);
      }


simpleUpdate() and simpleRender() stay empty. I need that for fractals. That means, something with alphastate would not help. With an iterative algorithm, oTextureRenderer.render(oQuad3, oTexture, false); would be executed again and again. The texture would function as a buffer.

Best,
Andreas