Depth Field - Bluring

Hi guys!



Anyone knows how can I fix it?

See image attached…



There are 3 boxes and just one don't have depth field characteristc.

The problem is that the blur of the box which is behind, affect the box that has no blur.



Thanks,


Looks like you need to do your DepthOfField pass before you do the actual render…

This is the source code of DepthOfFiled and RenderPass… What should I do?


            //Setup renderpasses
         RenderPass rootPass = new RenderPass();
         rootPass.add(node);
         rootPass.add(node1);
         rootPass.add(node2);
         pManager.add(rootPass);

         dofPass = new DepthOfFieldRenderPass(cam, 1);
         dofPass1 = new DepthOfFieldRenderPass(cam, 1);
          
         if(!dofPass.isSupported()) {
               Text text1 = new Text("Text", "GLSL Not supported on this computer.");
               text1.setRenderQueueMode(Renderer.QUEUE_ORTHO);
               text1.setLightCombineMode(LightCombineMode.Off);
               text1.setLocalTranslation(new Vector3f(0,20,0));
               fpsNode.attachChild(text1);
           } else {
              dofPass.add(node1);
              dofPass.setNearBlurDepth(0);
              dofPass.setFarBlurDepth(100);
               pManager.add(dofPass);
           }
          
         if(!dofPass1.isSupported()) {
               Text text1 = new Text("Text", "GLSL Not supported on this computer.");
               text1.setRenderQueueMode(Renderer.QUEUE_ORTHO);
               text1.setLightCombineMode(LightCombineMode.Off);
               text1.setLocalTranslation(new Vector3f(0,-20,0));
               fpsNode.attachChild(text1);
           } else {
              dofPass1.add(node);
              dofPass1.setNearBlurDepth(0);
              dofPass1.setFarBlurDepth(100);
               pManager.add(dofPass1);
           }

         RenderPass fpsPass = new RenderPass();
         fpsPass.add(fpsNode);
         pManager.add(fpsPass);

Try adding the rootPass after the depthOfField Passes…

I tried this way:


          //Setup renderpasses
         dofPass = new DepthOfFieldRenderPass(cam, 1);
         dofPass1 = new DepthOfFieldRenderPass(cam, 1);
          
         if(!dofPass.isSupported()) {
               Text text1 = new Text("Text", "GLSL Not supported on this computer.");
               text1.setRenderQueueMode(Renderer.QUEUE_ORTHO);
               text1.setLightCombineMode(LightCombineMode.Off);
               text1.setLocalTranslation(new Vector3f(0,20,0));
               fpsNode.attachChild(text1);
           } else {
              dofPass.add(node1);
              dofPass.setNearBlurDepth(0);
              dofPass.setFarBlurDepth(100);
               pManager.add(dofPass);
           }
          
         if(!dofPass1.isSupported()) {
               Text text1 = new Text("Text", "GLSL Not supported on this computer.");
               text1.setRenderQueueMode(Renderer.QUEUE_ORTHO);
               text1.setLightCombineMode(LightCombineMode.Off);
               text1.setLocalTranslation(new Vector3f(0,-20,0));
               fpsNode.attachChild(text1);
           } else {
              dofPass1.add(node);
              dofPass1.setNearBlurDepth(0);
              dofPass1.setFarBlurDepth(100);
               pManager.add(dofPass1);
           }

         RenderPass rootPass = new RenderPass();
         rootPass.add(node);
         rootPass.add(node1);
         rootPass.add(node2);
         pManager.add(rootPass);

         RenderPass fpsPass = new RenderPass();
         fpsPass.add(fpsNode);
         pManager.add(fpsPass);



But now I dont't have depthOfField anymore..  ://

Might have to set a z-offset for the pass (or set an explicit z-buffer state), I will look at it (briefly) in a little while if you haven't gotten it figured out…

I have tried it before setting DepthOFiled components:


         RenderPass rootPass = new RenderPass();
         rootPass.add(node);
         rootPass.add(node1);
         rootPass.add(node2);
         
         rootPass.setZFactor(0f);
         rootPass.setZOffset(-5f);

         pManager.add(rootPass);

          //Setup renderpasses
         dofPass = new DepthOfFieldRenderPass(cam, 1);
         dofPass1 = new DepthOfFieldRenderPass(cam, 1);



I have tested a lot of numbers as paramenters for ZFactor and ZOffset, but the problem of the blur of a box affecting another box still remains.

Do you have any idea how to fix it?

Can you post a simple, complete test?

nvm, here ya go:



import com.jme.app.SimplePassGame;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Spatial;
import com.jme.scene.Node;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.Text;
import com.jme.scene.shape.Box;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jmex.effects.glsl.DepthOfFieldRenderPass;



public class DepthOfFieldTest extends SimplePassGame {

    public static void main( String[] args ) {
        new DepthOfFieldTest().start();
    }

    @Override
    protected void simpleInitGame() {

        Node textNode = new Node( "text" );

        Spatial node = getBox( "box1" );
        Spatial node1 = getBox( "box2" );
        Spatial node2 = getBox( "box3" );

        node.getLocalTranslation().set( -25, -15, -20 );
        node1.getLocalTranslation().set( -26, -16, -60 );
        node2.getLocalTranslation().set( -27, -17, -100 );

        rootNode.attachChild( node );
        rootNode.attachChild( node1 );
        rootNode.attachChild( node2 );
        rootNode.updateGeometricState( 0, true );
       
        RenderPass rootPass = new RenderPass();
        rootPass.add( rootNode );
        pManager.add( rootPass );

        // Setup renderpasses
        DepthOfFieldRenderPass dofPass = new DepthOfFieldRenderPass( cam, 1 );
        if( !dofPass.isSupported() ){
            Text text1 = new Text( "Text", "GLSL Not supported on this computer." );
            text1.setRenderQueueMode( Renderer.QUEUE_ORTHO );
            text1.setLightCombineMode( LightCombineMode.Off );
            text1.setLocalTranslation( new Vector3f( 0, 20, 0 ) );
            textNode.attachChild( text1 );
        } else{
            dofPass.setNearBlurDepth( 0 );
            dofPass.setFarBlurDepth( 100 );
            dofPass.add( node );
            dofPass.add( node1 );
            dofPass.add( node2 );
            pManager.add( dofPass );
        }

        RenderPass fpsPass = new RenderPass();
        fpsPass.add( textNode );
        pManager.add( fpsPass );
    }

    private Spatial getBox( final String name ) {
        final Spatial node = new Box( name, Vector3f.UNIT_XYZ.clone().mult( 10 ).negateLocal(), Vector3f.UNIT_XYZ.clone().mult( 10 ) );
        final TextureState ts = display.getRenderer().createTextureState();
        ts.setEnabled( true );
        ts.setTexture( TextureManager.loadTexture(
                DepthOfFieldTest.class.getClassLoader().getResource( "jmetest/data/images/Monkey.jpg" ),
                Texture.MinificationFilter.Trilinear,
                Texture.MagnificationFilter.Bilinear ) );
        node.setRenderState( ts );
        return node;
    }
}



Looks like you need to add all your stuff to a single DOF pass, and it should be after the actual render...

(also, this is for jME 2.0; but should give you an idea of how it should be in 1.0...)

What I'm trying to do is to set blur (using Depth of Field, could be other way…) for each box. So, each box would have a different blur.



That's why I'm trying to code using 1 or more DepthOfFieldRenderPass, Ok?



The problem that I've been facing is that the blur (higher) of one box affects the blur of another box which has lower or no blur.



This is a sample code that you are able to see it:


import com.jme.app.SimplePassGame;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Spatial;
import com.jme.scene.Node;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.Text;
import com.jme.scene.shape.Box;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jmex.effects.glsl.DepthOfFieldRenderPass;



public class DepthOfFieldTest extends SimplePassGame {

    public static void main( String[] args ) {
        new DepthOfFieldTest().start();
    }

    @Override
    protected void simpleInitGame() {

        Node textNode = new Node( "text" );

        Spatial node = getBox( "box1" );
        Spatial node1 = getBox( "box2" );
        Spatial node2 = getBox( "box3" );

        node.getLocalTranslation().set( -25, -15, -20 );
        node1.getLocalTranslation().set( -26, -16, -60 );
        node2.getLocalTranslation().set( -27, -17, -100 );

        rootNode.attachChild( node );
        rootNode.attachChild( node1 );
        rootNode.attachChild( node2 );
        rootNode.updateGeometricState( 0, true );
       
        RenderPass rootPass = new RenderPass();
        rootPass.add( rootNode );
        pManager.add( rootPass );

        DepthOfFieldRenderPass dofPass = new DepthOfFieldRenderPass( cam, 1 );
        if( !dofPass.isSupported() ){
            Text text1 = new Text( "Text", "GLSL Not supported on this computer." );
            text1.setRenderQueueMode( Renderer.QUEUE_ORTHO );
            text1.setLightCombineMode( LightCombineMode.Off );
            text1.setLocalTranslation( new Vector3f( 0, 20, 0 ) );
            textNode.attachChild( text1 );
        } else{
            dofPass.setNearBlurDepth( 0 );
            dofPass.setFarBlurDepth( 100 );
            dofPass.add( node );
            dofPass.add( node2 );
            pManager.add( dofPass );
        }

        DepthOfFieldRenderPass dofPass2 = new DepthOfFieldRenderPass( cam, 1 );
        if( !dofPass.isSupported() ){
            Text text1 = new Text( "Text", "GLSL Not supported on this computer." );
            text1.setRenderQueueMode( Renderer.QUEUE_ORTHO );
            text1.setLightCombineMode( LightCombineMode.Off );
            text1.setLocalTranslation( new Vector3f( 0, 20, 0 ) );
            textNode.attachChild( text1 );
        } else{
            dofPass2.setNearBlurDepth( 0 );
            dofPass2.setFarBlurDepth( 100 );
            dofPass2.add( node1 );
            dofPass2.setBlurSize(0.02f);
            pManager.add( dofPass2 );
        }

        RenderPass fpsPass = new RenderPass();
        fpsPass.add( textNode );
        pManager.add( fpsPass );
    }

    private Spatial getBox( final String name ) {
        final Spatial node = new Box( name, Vector3f.UNIT_XYZ.clone().mult( 10 ).negateLocal(), Vector3f.UNIT_XYZ.clone().mult( 10 ) );
        final TextureState ts = display.getRenderer().createTextureState();
        ts.setEnabled( true );
        ts.setTexture( TextureManager.loadTexture(
                DepthOfFieldTest.class.getClassLoader().getResource( "jmetest/data/images/Monkey.jpg" ),
                Texture.MinificationFilter.Trilinear,
                Texture.MagnificationFilter.Bilinear ) );
        node.setRenderState( ts );
        return node;
    }
}



Thanks in advance!

Umm, the blur is already setting 'levels' based on distance, that's why you supply these:



              dofPass.setNearBlurDepth(0);
              dofPass.setFarBlurDepth(100);



I don't think the DoF passes are not designed to 'interact' with each other, therefore you get what you see. You need to either have all the nodes you want blurred added to a single DoF pass (or write your own GLSL blur effect that supports what you want)...