I've been playing around with the zbuffer state and I seem to be missing something. Lets say I have two objects, a planet and an atmosphere effect (both spatials). I want the atmosphere to always render in front of the planet, yet I want both to still render properly in 3d space per their distance to the camera and in relation to other spatials. Is this possible? It seems to me it's an all or nothing proposition when using zbuffer states.
Many thanks if anyone can shed some light on this.
i assume your athmosphere is not solid and a little bigger than the plant, so you should put it in the "transparent bucket" or what it's called. (setRenderMode or setRenderQueue). this way, the planet + rest of the scene is rendered first and the athmoshere is added later (and won't prevent the planet from being rendered)
I assume (maybe incorrectly!) that you are using a slightly larger, semi-transparent second sphere for the atmosphere effect? Try setting the queue mode of your planet to OPAQUE and the effect as TRANSPARENT. Then set the planet's zbuffer to less_equals and zbuffer write = true. Set the atmosphere's zbufferstate to less_equals and zbuffer write to false.
The key to this is the oversized atmo sphere. But maybe you are doing this some entirely different way.
Thanks guys. Well I do have a model that wraps around the outside of the planet. But ideally I'd like to use a model that looks more like a contact lens for the atmo. The trick is to get it to render behind the planet, but still correctly in 3d space. I was pretty close and everything was working correctly, except that when I would fly around 2 planets and they intersected each other, where the atmo intersected the second planet you could see the skybox stars where they shouldn't be.
Anyway, what would the setup look like, or is it possible to render that atmo in front of the planet geom and still have everything else work correctly?
Regular transparency should still do the trick. Try removing the skybox for kicks and see if the 2nd planet and atmo look correct.
Using your method as shown below, the atmo renders behind the planet:
ZBufferState zbuff = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
zbuff.setWritable(true);
zbuff.setEnabled(true);
zbuff.setFunction(ZBufferState.CF_LEQUAL);
planetModel.setRenderState(zbuff);
planetModel.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
planetModel.updateRenderState();
AlphaState as = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
as.setBlendEnabled(true);
as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as.setDstFunction(AlphaState.SB_ONE_MINUS_SRC_ALPHA);
as.setTestEnabled(true);
as.setTestFunction(AlphaState.TF_GREATER);
ZBufferState zbuff2 = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
zbuff2.setWritable(false);
zbuff2.setEnabled(true);
zbuff2.setFunction(ZBufferState.CF_LEQUAL);
atmoBillboardNode = new BillboardNode("atmo_" + name);
atmoBillboardNode.setType(BillboardNode.CAMERA_ALIGNED);
atmoBillboardNode.attachChild(atmoModel);
atmoBillboardNode.setRenderState(as);
atmoBillboardNode.setRenderState(zbuff2);
atmoBillboardNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
atmoBillboardNode.updateRenderState();
this.attachChild(planetModel);
this.attachChild(atmoBillboardNode);
this.setLocalScale(size * 2);
this.updateGeometricState(0, true);
this.setLightCombineMode(LightState.INHERIT);
If that is the case, then the atmosphere geometry is further away from your camera than the planet. You will need to move it so it sits just on the camera side of your planet as the camera moves. Either that, or use the sphere technique described above.
Yup. I actually have moved to a solution that places the atmo completely in front of the planet. But just out of curiousity is it at least theoretically possible to render one piece of geom in front of another with them being equal in terms of translation? Also what does the camera use to determine zorder? Does it look just at the worldtranslation of the object or is it the closest piece of geometry to the camera?
You can't use zbuffer alone to solve a problem like that… sorting has to be done. That's what the queue does, it sorts things by queue type (opaque, transparent, ortho) and then either by distance to camera (back to front for transparent, front to back for opaque) or the zorder field (ortho).