Passing through a plane (a thin box geometry)

Hello all,



Why is it that when the camera goes through a plane made by a really thin box geometry there is a gap where the plane isn’t rendered?



Here’s the code:

[java]package water;



import jme3test.helloworld.*;

import com.jme3.app.SimpleApplication;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.material.RenderState.BlendMode;

import com.jme3.material.RenderState.FaceCullMode;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.scene.shape.Sphere;

import com.jme3.renderer.queue.RenderQueue.Bucket;



public class CubeWater extends SimpleApplication {



public static void main(String[] args) {

CubeWater app = new CubeWater();

app.start();

}



@Override

public void simpleInitApp() {

Box boxshape4 = new Box(new Vector3f(3f, -1f, 0f), 1f, 1f, 1f);

Geometry cube_leak = new Geometry(“Leak-through color cube”, boxshape4);

Material mat_tl = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat_tl.setColor(“Color”, new ColorRGBA(1f, 0f, 1f, 0.5f)); // purple

mat_tl.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

cube_leak.setMaterial(mat_tl);

cube_leak.setQueueBucket(Bucket.Transparent);

rootNode.attachChild(cube_leak);



Box seaLevel = new Box(new Vector3f(0f, -1f, 0f), 10f, 0.01f, 10f);

Geometry geo_seaLevel = new Geometry(“Sea level”, seaLevel);

Material mat_seaLevel = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat_seaLevel.setColor(“Color”, new ColorRGBA(0f, 0f, 1f, 0.5f)); // blue

mat_seaLevel.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

geo_seaLevel.setMaterial(mat_seaLevel);

geo_seaLevel.setQueueBucket(Bucket.Translucent);

rootNode.attachChild(geo_seaLevel);



DirectionalLight sun = new DirectionalLight();

sun.setDirection(new Vector3f(1, 0, -2).normalizeLocal());

sun.setColor(ColorRGBA.White);

rootNode.addLight(sun);



Sphere ball = new Sphere(32, 32, 2f);

Geometry ballGeom = new Geometry(“Ball Name”, ball);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, new ColorRGBA(0, 1, 1, 0.5f));

mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

mat_tl.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);

ballGeom.setMaterial(mat);

ballGeom.setQueueBucket(Bucket.Transparent);

rootNode.attachChild(ballGeom);



}

}[/java]



Here’s what I’m talking about:

I’m not sure whether I understand what you mean. Maybe this will help?



cam.setFrustumNear(0);

That just turned everything black.

If I use cam.setFrustumNear(0.1); I get funny fish eye effects.



But the camera tip is good.

I’ll go learn some more about this topic maybe I’m just making the image being formed too far away.

You have transparency there, you sure you set your buckets up correctly? Check the manual about “transparency”.

@memonick said:
I'm not sure whether I understand what you mean. Maybe this will help?

cam.setFrustumNear(0);

Noooo!!!
read this http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html you'll understand why 0 is not a valid value.

@kotoko if you divide your frustum near, you should divide your frustum far by the same amount to keep the same ratio.

@kotoko, Actually, I searched using the Google tool, and found this code:



[java]cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 1000f);

[/java]



Sorry if I confused you.



@nehon, I divided both by 10, but the same thing happens. As kotoko described it, I get funny fish eye effects.

The default frustum is 1 to 1000

Just to be sure 1 / 10 = 0.1 and 1000 / 10 = 100.

That’s not what you wrote in your example.

In my last example?



I tried cam.setFrustumNear(0.1) and cam.setFrustumFar(100) but I still got the warp effect.

Using the last code I posted, if I reduce the last value, that only means that objects beyond 1000 units of the camera are not rendered. Am I missing something?

@memonick said:
Am I missing something?

you missed to read the link i posted http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html
Or you would know that it affect more than that.

As for the fisheye effect maybe you have to play with the fov

Ok, I think I understood :slight_smile: Just one question - should I aim an application towards a 16 bit Z buffer, or towards a 24 bit Z buffer? Just how common are 24 bit Z buffers and 32 bit Z buffer? And how do I check what my PC has?

@nehon from reading the link I understand that the default should be enough for me and the problem should be somewhere else.



I’ll look into the rendering buckets and transparency/translucent stuff.

Do you know a nice explanation about rendering buckets? The words “render bucket” tutorial in google don’t get me much.

@normen I assumed that by manual you mean how_to_use_materials and materials_overview.



In the first link is a bit strange that mat_seaLevel.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); is suggested both at step 2 and 4.

The second link doesn’t suggest any order.



I ended up with the code like this:

[java]Box boxshape4 = new Box(new Vector3f(3f, -1f, 0f), 1f, 1f, 1f);

Geometry cube_leak = new Geometry(“Leak-through color cube”, boxshape4);

Material mat_tl = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat_tl.setColor(“Color”, new ColorRGBA(1f, 0f, 1f, 1f)); // purple

mat_tl.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

cube_leak.setQueueBucket(Bucket.Transparent);

cube_leak.setMaterial(mat_tl);

rootNode.attachChild(cube_leak);



Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, new ColorRGBA(0, 1, 1, 1f));

mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

Sphere ball = new Sphere(32, 32, 2f);

Geometry ballGeom = new Geometry(“Ball Name”, ball);

ballGeom.setQueueBucket(Bucket.Transparent);

ballGeom.setMaterial(mat);

rootNode.attachChild(ballGeom);

mat_tl.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);





Material mat_seaLevel = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat_seaLevel.setColor(“Color”, new ColorRGBA(0f, 0f, 1f, 0.5f)); // blue

mat_seaLevel.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

Box seaLevel = new Box(new Vector3f(0f, -1f, 0f), 10f, 0.01f, 10f);

Geometry geo_seaLevel = new Geometry(“Sea level”, seaLevel);

geo_seaLevel.setQueueBucket(Bucket.Translucent);

geo_seaLevel.setMaterial(mat_seaLevel);

rootNode.attachChild(geo_seaLevel);

mat_seaLevel.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);



/** Must add a light to make the lit object visible! */

DirectionalLight sun = new DirectionalLight();

sun.setDirection(new Vector3f(1, 0, -2).normalizeLocal());

sun.setColor(ColorRGBA.White);

rootNode.addLight(sun);[/java]



This gives the same result.



Also I couldn’t find any explanation on what are render buckets. If anyone knows a link it would be awesome.

@memonick said:
Ok, I think I understood :) Just one question - should I aim an application towards a 16 bit Z buffer, or towards a 24 bit Z buffer? Just how common are 24 bit Z buffers and 32 bit Z buffer? And how do I check what my PC has?

It depends, most recent card has a 32 bit depth buffer, but i guess ~ 2004 harware could still have a 16 bit depth buffer.
I don't know about intel GMA that are shipped on some lap top i wouldn't be surprised that they have a 16 bit buffer. Some old mac book too.

But for sure....most of android devices have a 16 bit depth buffer.

Anyway, don't make too many fancy stuff with your frustum and you shouldn't have any issue.
1 Like

Cool. Thanks a lot :slight_smile:

After re-reading everything, this was the life saver:

[java]cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.2f, 100f);[/java]

@nehon, if I want to increase the view distance (the distance up to which is rendered), must I also increase/decrease the frustums in proportion?



[java]cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 2f, 2000f);[/java]

Sure, else you get a distorted lens effect (lines are not straight, “door spy” effect). Frustum isn’t a jme spcific topic, theres lots of info out there.

Thanks normen.