First depth of field test

started working with shadow maps and I wanted soft shadows and got into blurring stuff which lead to this.  Please look at and make suggestions thanks.  I can't find anything to put into clean up.  Haven't actually tested it either.  Stole from ShadowRenderPass and ATI RenderMonkey IDE Depth of Field.  Renders the scene 4 times first time to "sharp image" ,2nd time to blur "shape image",3rd time to blur the blur, and 4th time to combine shape and blur(the 2nd one).  It suppose to work on pinhole and all the varibles are preset for testing purpose.  In RenderMonkey after the first render it used a screen alligned quad and just put the texture from previous pass on the quad.  How much of a proformance boost would that give me?  I imagine that render 40verts then 4 ,4 ,4 would be better than 40 verts four times.



import java.net.URL;

import com.jme.image.Texture;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.pass.*;
import com.jme.scene.Spatial;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.RenderState;
import com.jme.system.DisplaySystem;

public class depth_of_field_pass extends Pass {

   private DisplaySystem display;
   
   private static float focus =(float) 0.48,
                   Ks = (float) 0.94,
                   sampleDist0 = (float) 0.0198,
                   distanceScale = (float) 0.0035,
                   range = (float) 4.6,
                   sampleDist1 = (float) 0.192,
                   Kd =(float) 0.96;
   
   private Renderer renderer;
   
   //blur scene 1
   private GLSLShaderObjectsState blur0Shader;
   private Texture blur0Tex;
   
   //blur scene 2
   private GLSLShaderObjectsState blur1Shader;
   private Texture blur1Tex;
   
   //Origanal scene
   private GLSLShaderObjectsState RTShader;
   private Texture RTTex;
   
   private TextureRenderer TR;
   
   private RenderState[] preStates;
   
   private GLSLShaderObjectsState combineShader;
   
   private static final long serialVersionUID = 1L;
   
   protected void doRender(Renderer arg0) {
      init();
      setupShaders();
      saveEnforcedStates();
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(RTShader);
      TR.setupTexture(RTTex);
      TR.updateCamera();
      renderScene(renderer);
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(blur0Shader);
      TR.setupTexture(blur0Tex);
      TR.updateCamera();
      renderScene(renderer);
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(blur1Shader);
      TR.setupTexture(blur1Tex);
      TR.updateCamera();
      renderScene(renderer);
      TR.cleanup();
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(combineShader);
      renderScene(renderer);
      replaceEnforcedStates();
   
   }
   protected void renderScene(Renderer r) {
          for (int i = 0, sSize = spatials.size(); i < sSize; i++) {
              Spatial s = (Spatial)spatials.get(i);
              s.onDraw(r);
          }
          r.renderQueue();
      }
   protected void replaceEnforcedStates() {
          for (int x = RenderState.RS_MAX_STATE; --x >= 0; ) {
              Spatial.enforcedStateList[x] = preStates[x];
          }
      }
   protected void saveEnforcedStates() {
          for (int x = RenderState.RS_MAX_STATE; --x >= 0; ) {
         preStates[x] = Spatial.enforcedStateList[x];
          }
      }
   protected void init()
   {
      display = DisplaySystem.getDisplaySystem();
      renderer = display.getRenderer();
      
      RTShader = renderer.createGLSLShaderObjectsState();
      TR = display.createTextureRenderer(512,512,false,true,false,false,TextureRenderer.RENDER_TEXTURE_2D,0);
      TR.setBackgroundColor(ColorRGBA.black);
      TR.getCamera().setLocation(renderer.getCamera().getLocation());
      
      RTTex = new Texture();
      RTTex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      
      blur0Tex = new Texture();
      blur0Tex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      blur0Shader = renderer.createGLSLShaderObjectsState();
      
      blur1Tex = new Texture();
      blur1Tex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      blur1Shader = renderer.createGLSLShaderObjectsState();
      
      combineShader = renderer.createGLSLShaderObjectsState();
   }
   protected void cleanup()
   {
      
   }
   protected void setupShaders()
   {
      URL RTVert,RTFrag,blur0Vert,blur0Frag,blur1Vert,blur1Frag,combineVert,combineFrag;
      try{
      
                RTVert = new URL("Render.vert");
      RTFrag = new URL("Render.frag");
      
               blur0Vert = new URL("Blur0.vert");
      blur0Frag = new URL("Blur0.frag");
      
                blur1Vert = new URL("Blur1.vert");
      blur1Frag = new URL("Blur1.frag");
      
                combineVert = new URL("Combine.vert");
      combineFrag = new URL("Combine.frag");
      }
      catch(Exception e)
      {
         System.out.println(e.printStackTrace());
      }
      RTShader.load(RTVert,RTFrag);
      RTShader.setUniform("distanceScale",distanceScale);
      
                blur0Shader.load(blur0Vert,blur0Frag);
      blur0Shader.setUniform("RT",RTTex.getTextureId());
      blur0Shader.setUniform("sampleDist0",sampleDist0);
      
                blur1Shader.load(blur1Vert,blur1Frag);
      blur1Shader.setUniform("RT",blur0Tex.getTextureId());
      blur1Shader.setUniform("sampleDist1",sampleDist1);
      
                combineShader.load(combineVert,combineFrag);
      combineShader.setUniform("Range",range);
      combineShader.setUniform("RT",RTTex.getTextureId());
      combineShader.setUniform("blur1",blur1Tex.getTextureId());
      combineShader.setUniform("focus",focus);
   }

}



Render.vert shader code

uniform float distanceScale;

varying vec3 vNormal;
varying vec3 vViewVec;

void main(void)
{
   gl_Position = ftransform();
  
   // Eye-space lighting
   vNormal = gl_NormalMatrix * gl_Normal;
  
   // We multiply with distance scale in the vertex shader
   // instead of the fragment shader to improve performance.
   vViewVec = -vec3(distanceScale * gl_ModelViewMatrix * gl_Vertex);

}



Render Frag Shader code

uniform vec4 lightDir;
uniform float Ks;
uniform float Kd;

varying vec3 vNormal;
varying vec3 vViewVec;

void main(void)
{
   // Basic lighting
   float diffuse = dot(lightDir.xyz, vNormal);
   float specular = pow(clamp(dot(reflect(-normalize(vViewVec), vNormal), lightDir.xyz),0.0, 1.0), 16.0);
   vec3  light = Kd * diffuse + Ks * specular;

   // We'll use the distance to decide how much blur we want
   float dist = length(vViewVec);

   gl_FragColor = vec4( light, dist);
}



Blur0 Vert Shader Code


varying vec2 vTexCoord;

void main(void)
{
   // Clean up inaccuracies
   vec2 Pos = sign(gl_Vertex.xy);

   gl_Position = vec4(Pos.xy, 0, 1);
   // Image-space
   vTexCoord.x = 0.5 * (1.0 + Pos.x);
   vTexCoord.y = 0.5 * (1.0 + Pos.y);


}



Blur0 Frag Shader Code

uniform float sampleDist0;
uniform sampler2D RT;
varying vec2 vTexCoord;
/*
const vec2 samples[12] = {
   -0.326212, -0.405805,
   -0.840144, -0.073580,
   -0.695914,  0.457137,
   -0.203345,  0.620716,
    0.962340, -0.194983,
    0.473434, -0.480026,
    0.519456,  0.767022,
    0.185461, -0.893124,
    0.507431,  0.064425,
    0.896420,  0.412458,
   -0.321940, -0.932615,
   -0.791559, -0.597705,
};
*/

void main(void)
{
   vec2 samples00 = vec2(-0.326212, -0.405805);
   vec2 samples01 = vec2(-0.840144, -0.073580);
   vec2 samples02 = vec2(-0.695914,  0.457137);
   vec2 samples03 = vec2(-0.203345,  0.620716);
   vec2 samples04 = vec2( 0.962340, -0.194983);
   vec2 samples05 = vec2( 0.473434, -0.480026);
   vec2 samples06 = vec2( 0.519456,  0.767022);
   vec2 samples07 = vec2( 0.185461, -0.893124);
   vec2 samples08 = vec2( 0.507431,  0.064425);
   vec2 samples09 = vec2( 0.896420,  0.412458);
   vec2 samples10 = vec2(-0.321940, -0.932615);
   vec2 samples11 = vec2(-0.791559, -0.597705);

   vec2 newCoord;
   vec4 sum = texture2D(RT, vTexCoord);
  
   /*
   for (int i = 0; i < 12; i++)
   {
      sum += tex2D(RT, texCoord + sampleDist0 * samples[i]);
   }
   */
  
   newCoord = vTexCoord + sampleDist0 * samples00;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples01;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples02;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples03;
   sum += texture2D(RT, newCoord);
  
   newCoord = vTexCoord + sampleDist0 * samples04;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples05;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples06;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples07;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples08;
   sum += texture2D(RT, newCoord);
  
   newCoord = vTexCoord + sampleDist0 * samples09;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples10;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist0 * samples11;
   sum += texture2D(RT, newCoord);

   sum /= 13.0;

   gl_FragColor = vec4( sum);
}



Blur1 Vert Shader Code


varying vec2 vTexCoord;

void main(void)
{
   // Clean up inaccuracies
   vec2 Pos = sign(gl_Vertex.xy);

   gl_Position = vec4(Pos.xy, 0, 1);
   // Image-space
   vTexCoord.x = 0.5 * (1.0 + Pos.x);
   vTexCoord.y = 0.5 * (1.0 + Pos.y);


}



Blur1 Frag Shader Code

uniform float sampleDist1;
uniform sampler2D RT;
varying vec2 vTexCoord;
/*
const vec2 samples[12] = {
   -0.326212, -0.405805,
   -0.840144, -0.073580,
   -0.695914,  0.457137,
   -0.203345,  0.620716,
    0.962340, -0.194983,
    0.473434, -0.480026,
    0.519456,  0.767022,
    0.185461, -0.893124,
    0.507431,  0.064425,
    0.896420,  0.412458,
   -0.321940, -0.932615,
   -0.791559, -0.597705,
};
*/

void main(void)
{
   vec2 samples00 = vec2(-0.326212, -0.405805);
   vec2 samples01 = vec2(-0.840144, -0.073580);
   vec2 samples02 = vec2(-0.695914,  0.457137);
   vec2 samples03 = vec2(-0.203345,  0.620716);
   vec2 samples04 = vec2( 0.962340, -0.194983);
   vec2 samples05 = vec2( 0.473434, -0.480026);
   vec2 samples06 = vec2( 0.519456,  0.767022);
   vec2 samples07 = vec2( 0.185461, -0.893124);
   vec2 samples08 = vec2( 0.507431,  0.064425);
   vec2 samples09 = vec2( 0.896420,  0.412458);
   vec2 samples10 = vec2(-0.321940, -0.932615);
   vec2 samples11 = vec2(-0.791559, -0.597705);

   vec2 newCoord;
   vec4 sum = texture2D(RT, vTexCoord);
  
   /*
   for (int i = 0; i < 12; i++)
   {
      sum += tex2D(RT, texCoord + sampleDist1 * samples[i]);
   }
   */
  
   newCoord = vTexCoord + sampleDist1 * samples00;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples01;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples02;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples03;
   sum += texture2D(RT, newCoord);
  
   newCoord = vTexCoord + sampleDist1 * samples04;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples05;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples06;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples07;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples08;
   sum += texture2D(RT, newCoord);
  
   newCoord = vTexCoord + sampleDist1 * samples09;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples10;
   sum += texture2D(RT, newCoord);

   newCoord = vTexCoord + sampleDist1 * samples11;
   sum += texture2D(RT, newCoord);

   sum /= 13.0;

   gl_FragColor = vec4( sum);
}



Combine Vert Shader Code


varying vec2 vTexCoord;

void main(void)
{
   // Clean up inaccuracies
   vec2 Pos = sign(gl_Vertex.xy);

   gl_Position = vec4(Pos.xy, 0, 1);
   // Image-space
   vTexCoord.x = 0.5 * (1.0 + Pos.x);
   vTexCoord.y = 0.5 * (1.0 + Pos.y);


}



Combine Frag Shader Code

uniform float range;
uniform sampler2D RT;
uniform sampler2D Blur1;
uniform float focus;

varying vec2 vTexCoord;


void main(void)
{
   vec4 sharp = texture2D(RT,    vTexCoord);
   vec4 blur  = texture2D(Blur1, vTexCoord);

   gl_FragColor = mix(sharp, blur, clamp(range * abs(focus - sharp.a), 0.0, 1.0));
}

yes, with a model that has 100.000 polys that really mean something :wink:



anyways, a blur with high sampledist is not the same as a blur of a blur…the latter is heavily preferred as it gives smooth blur and not visible copies in all directions at high sampledists…many blurs with small sampledist is best…

I have a test program that I'll post soon.  I just have all the varibles set for testing purposes I plan to expose them.  Also there is a error in the code on Render.frag  the original code textured the object I left the base varible in Render.frag but It's been fixed so it will work now. The model I was using I thought I had just the code in wrong but it does take awhile for it to load the model.  Also only using the model for testing purposes.  For the other type of combine would I just use blur after a certain depth is reached like objects that are so far away.

Ran into a few problems

1: I wasn't actually rendering to the pbuffer

2: another error in Render.frag I didn't change the varible to a float after removing the base varible

3: did not  have init and setup shaders check if already setup



new doRender code

protected void doRender(Renderer arg0) {
      init();
      setupShaders();
      saveEnforcedStates();
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(RTShader);
      TR.setupTexture(RTTex);
      TR.updateCamera();
      TR.render(spatials,RTTex);
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(blur0Shader);
      TR.setupTexture(blur0Tex);
      TR.updateCamera();
      renderScene(renderer);
      TR.render(spatials,blur0Tex);
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(blur1Shader);
      TR.setupTexture(blur1Tex);
      TR.updateCamera();
      TR.render(spatials,blur1Tex);
      TR.cleanup();
      
      Spatial.clearCurrentStates();
      Spatial.enforceState(combineShader);
      renderScene(renderer);
      replaceEnforcedStates();
   
   }


new error

java.lang.IllegalStateException: Pbuffer is destroyed
        at org.lwjgl.opengl.Pbuffer.checkDestroyed(Pbuffer.java:214)
        at org.lwjgl.opengl.Pbuffer.makeCurrent(Pbuffer.java:234)
        at com.jme.renderer.lwjgl.LWJGLTextureRenderer.activate(Unknown Source)
        at com.jme.renderer.lwjgl.LWJGLTextureRenderer.updateCamera(Unknown Sour
ce)
        at depthOfFieldPass.doRender(depthOfFieldPass.java:58)
        at com.jme.renderer.pass.Pass.renderPass(Unknown Source)
        at com.jme.renderer.pass.BasicPassManager.renderPasses(Unknown Source)
        at com.jme.app.SimplePassGame.render(Unknown Source)
        at com.jme.app.BaseGame.start(Unknown Source)
        at testBlur.main(testBlur.java:29)


Line 58 is the first render of the scene under doRender it's the line that goes RT.updateCamera();
I don't know much about pbuffers and such so any help would be great.

got past all that now it just eats up memory like crazy again any ideas?

got past all the trails and tribulations and it runs only thing left is optimising I had a few ideas.  First ascreen alined quad it basicly a quad that is always taking up all of the cameras view.  Another idea is since the pbuffer renders 3 times in a row is there anyway to keep it from setting it's self current and restoring the render context intill the last render?  Another question I must have my test program setup wrong because all i have it drawing is a cube and it says I have 96 verts, that means there enough for 24 cubes and i'm rendering 4 times a frame. 

Another question I was looking thur the RenderTexture source and if you do  setupTexture it copies the frame buffer, and if you do render it renders then copies the the frame buffer would it be faster to is the renderer in jme same as in RenderTexture?  anyways in my source I had it setupTexture then render so it would copy frame buffer,render , and copy frame buffer again.  So i can't that to render only.  Moved the fps from 0 to 6 pretty sad.  I ran the RenderTexture test to make sure it wasn't drives or my card and I got ~300 fps on that.

don't really understand what you are saying…but setupTexture is only used to setup a new texture, and should not be used in rendering…just look how the testrendertotexture does…

took out the sencond blur pass and it ran showing that i’m not a failure! woo hoo anyways here is the image





I still don’t know why it shows so many verts that will be a problem when it comes to big models if it’s actually pushing like 20 times more verts than there is to the card.  Blur looks bad but it’s missing a pass,  cpu hits the wall and memory use keeps rising intill the virtual machine falls apart.  Would it be recommend to go outside jme for that pbuffer support that I’ve talked about?  Without any new ideas this is probly gonna fall cracks intill a fresh set of eyes look at it.



after program crashes due to memory use

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x690cb5fb, pid=3768, tid=3824
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode, sharing)
# Problematic frame:
# C  [atioglxx.dll+0xcb5fb]
#
# An error report file with more information is saved as hs_err_pid3768.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

just a quick observation that that image is totally unseeable  whoops.  FPs it at 14 and again it falls to 0 then crashes rest goes as follows

Count: Mesh(3) Triangle(36) Vertex(72) (vertex normal at 96 with 3 renders) The only conclusion i can come to is that i need to reset something but what the should i null out the textures every time?  If i was to null out the TextureRenderer the cpu would spend more time doing activate() deactivate().  Should I make shaders only tempory varibles?  I don't see how 8 kb of shader code can turn into 300mb of ram used.  I'll try taking a memory screenshot right before it crashes see if i can fingure it out.

solved another problem  XD at this rate you guys won’t ever reply and i’ll have given you alot of credit.  Got a new new problem this one is more bizar than the last.  Oh quick update i changed something around and the fps shot up to 100+ good news huh.  In these pictures i’m still using 1 blur not 2.  I can do 2 and still get 100+.  Anyways problem is that it cuts it off.  Its like the screen is section into quarters and my stuff fits in the first quarter.











::edit:: forgot you still can’t read the stuff



first picture fps 124 - Count: Mesh(3) Triangle(36) Vertex(72)



second picture fps 124 all the same as above

would be good if you told what you changed to fix your problems, in case anyone else runs into the same thing…

i'm pretty sure it's when i removed the garbage collector method  still don't know why my 3rd render won't work thou.  I load the radeon model and it didn't do the same quarter screen thing.  Don't know about the 3rd render why it won't work.  The screen is just black.



Looks like i'm down to the last few bugs then I release all this next will be soft shadow mapping(haven't even posted that i got shadow mapping done)

I'm giving up on it so I am going to post the code and be done with it.  Don't even know where i went wrong.  If you could just look at the doRender method and tell my if you see anything wrong.  Otherwise this might just be a springboard for somebody else.  Ask and i'll send the shaders over but I already posted them only minor changes where made.



depthOfFieldPass.java


import java.net.URL;
import java.util.ArrayList;

import com.jme.image.Texture;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.pass.*;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;

public class depthOfFieldPass extends RenderPass {

   protected DisplaySystem display;
   
   protected TextureState ts;
   
   protected static float focus =(float) 0.48,
                   Ks = (float) 0.94,
                   sampleDist0 = (float) 0.0198,
                   distanceScale = (float) 0.0035,
                   range = (float) 4.6,
                   sampleDist1 = (float) 0.192,
                   Kd =(float) 0.96;
   
   protected Renderer renderer;
   
   //blur scene 1
   protected GLSLShaderObjectsState blur0Shader;
   protected Texture blur0Tex;
   
   //blur scene 2
   protected GLSLShaderObjectsState blur1Shader;
   protected Texture blur1Tex;
   
   //Origanal scene
   protected GLSLShaderObjectsState RTShader;
   protected Texture RTTex;
   
   protected TextureRenderer TR;
   
   protected Node quadNode = new Node("quadNode");
   
   protected ArrayList scene = new ArrayList();
   protected ArrayList temp = new ArrayList();
   
   protected RenderState[] preStates = new RenderState[RenderState.RS_MAX_STATE];
   
   protected GLSLShaderObjectsState combineShader;
   
   protected boolean doneInit=false,doneShaderSetup=false;
   
   protected static final long serialVersionUID = 1L;
   
   public void doRender(Renderer arg0) {
      init();
      setupShaders();
      saveEnforcedStates();
      

      super.doRender(renderer);
      
      
      replaceEnforcedStates();
   
   }
   protected void replaceEnforcedStates() {
          for (int x = RenderState.RS_MAX_STATE; --x >= 0; ) {
              Spatial.enforcedStateList[x] = preStates[x];
          }
      }
   protected void saveEnforcedStates() {
          for (int x = RenderState.RS_MAX_STATE; --x >= 0; ) {
         preStates[x] = Spatial.enforcedStateList[x];
          }
      }
   protected void init()
   {
      if(doneInit)
         return;
      
      doneInit = true;
         
      display = DisplaySystem.getDisplaySystem();
      renderer = display.getRenderer();
      
      Quad q = new Quad("quad",512,512);
      quadNode.attachChild(q);
      scene.add(quadNode);
      
      RTTex = new Texture();
      RTTex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      RTTex.setRTTSource(Texture.RTT_SOURCE_RGBA);
      RTShader = renderer.createGLSLShaderObjectsState();
      
      blur0Tex = new Texture();
      blur0Tex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      blur0Tex.setRTTSource(Texture.RTT_SOURCE_RGBA);
      blur0Shader = renderer.createGLSLShaderObjectsState();
      
      blur1Tex = new Texture();
      blur1Tex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      blur1Tex.setRTTSource(Texture.RTT_SOURCE_RGBA);
      blur1Shader = renderer.createGLSLShaderObjectsState();
      
      TR = display.createTextureRenderer(512,512,false,true,false,false,TextureRenderer.RENDER_TEXTURE_2D,0);
      if(TR.isSupported())
      {
         TR.setBackgroundColor(ColorRGBA.black);
         TR.setCamera(renderer.getCamera());
         TR.setupTexture(RTTex);
         TR.setupTexture(blur0Tex);
         TR.setupTexture(blur1Tex);
      }
      
      combineShader = renderer.createGLSLShaderObjectsState();
   }
   protected void cleanup()
   {
      
   }
   protected void setupShaders()
   {
      if(doneShaderSetup)
         return;
      
      doneShaderSetup = true;
      
      URL RTVert = null,RTFrag = null,blur0Vert = null,blur0Frag = null,blur1Vert = null,blur1Frag = null,combineVert = null,combineFrag = null;

      RTVert = depthOfFieldPass.class.getResource("Render.vert");
      RTFrag = depthOfFieldPass.class.getResource("Render.frag");
      blur0Vert = depthOfFieldPass.class.getResource("Blur0.vert");
      blur0Frag = depthOfFieldPass.class.getResource("Blur0.frag");
      blur1Vert = depthOfFieldPass.class.getResource("Blur1.vert");
      blur1Frag = depthOfFieldPass.class.getResource("Blur0.frag");
      combineVert = depthOfFieldPass.class.getResource("Combine.vert");
      combineFrag = depthOfFieldPass.class.getResource("Combine.frag");
      
      RTShader.load(RTVert,RTFrag);
      RTShader.setUniform("distanceScale",distanceScale);
      RTShader.setEnabled(true);
      
      blur0Shader.load(blur0Vert,blur0Frag);
      blur0Shader.setUniform("RT",RTTex.getTextureId());
      blur0Shader.setUniform("sampleDist0",sampleDist0);
      blur0Shader.setEnabled(true);
      
      blur1Shader.load(blur1Vert,blur1Frag);
      blur1Shader.setUniform("RT",RTTex.getTextureId());
      blur1Shader.setUniform("sampleDist1",sampleDist1);
      blur1Shader.setEnabled(true);
      
      combineShader.load(combineVert,combineFrag);
      combineShader.setUniform("Range",range);
      combineShader.setUniform("RT",RTTex.getTextureId());
      combineShader.setUniform("blur1",blur0Tex.getTextureId());
      combineShader.setUniform("focus",focus);
      combineShader.setEnabled(true);
   }

}