Background disappears depending on camera location

I create two backgrounds for my game using the same texture. To create a 3D effect, place one space background very far from the camera with a fairly low transparency level, and the other background above and shifted to the right a bit with a high transparency level.



As I’m flying around in my spaceship (camera moving as well), depending on which way I go (it’s not the same distance in all directions), the back-background (furthest away) will disappear. I’m not sure what happens to it, but I can no longer see it.



Here’s before I reach this imaginary “border”: http://www.kinostudios.com/images/bg_there.jpg



And after I pass a certain distance in a certain direction: http://www.kinostudios.com/images/bg_gone.jpg



And here’s the code that I use to create these backgrounds:

private void addBackground() {
   float size = 100000f;
   float n = size/35f;
   float distance = -3000f;
   Vector3f[] coords = new Vector3f[] {
                     new Vector3f(size, size, distance),
                     new Vector3f(-size, size, distance),
                     new Vector3f(-size, -size, distance),
                     new Vector3f(size, -size, distance)
   };
   
   Vector2f[] texCoords = new Vector2f[] {
                     new Vector2f(0f, 0f),
                     new Vector2f(size/n, 0f),
                     new Vector2f(size/n, size/n),
                     new Vector2f(0f, size/n)
   };
   
   
   AlphaState as1 = display.getRenderer().createAlphaState();
   as1.setBlendEnabled(true);
   as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
   as1.setDstFunction(AlphaState.DB_ONE);
   as1.setTestEnabled(true);
   as1.setTestFunction(AlphaState.TF_GREATER);
   as1.setEnabled(true);
   
   
   Quad bg1 = new Quad("bg1", size, size);
   Quad bg2 = new Quad("bg2", size, size);
   bg1.setVertices(coords);
   bg1.setTextures(texCoords);
   bg2.setVertices(coords);
   bg2.setTextures(texCoords);
   
   TextureState bgtex = Utility.createTextureWrap(imageDir+"space007.jpg");
   bg1.setSolidColor(new ColorRGBA(1,1,1,0.5f));
   bg2.setSolidColor(new ColorRGBA(1,1,1,0.9f));
   bg1.setRenderState(bgtex);
   bg2.setRenderState(bgtex);
   bg1.setRenderState(as1);
   bg2.setRenderState(as1);
   bg2.setLocalTranslation(new Vector3f(5000f,5000f,distance));
   bg1.setLightCombineMode(LightState.OFF);
   bg2.setLightCombineMode(LightState.OFF);
   bg1.setForceView(true);
   bg2.setForceView(true);
   bg1.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
   bg2.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
   solarSystem.attachChild(bg1);
   solarSystem.attachChild(bg2);
}


Any help is much appreciated.

basically, because they are always going to be there, you either want them to be rendered Orthogonally with the z-buffer write disabled, like so:



Quad q = new Quad("Bg1", 1024, 768);
q.setRenderQueueMode(Renderer.Queue_Ortho);
ZBufferState zWriteDisabled = display.getRenderer().createZBufferState();
zWriteDisabled.setEnabled(true);
zWriteDisabled.setWritable(false);
q.setRenderState(q);
....



Thats the neat way of doing it, orr, if you still want to do it your way:


Quad q = new Quad("bg1, 1024, 768);
q.setModelBound(new BoundingBox());
q.updateModelBound();
q.setForceView(true);
....



Whichever is easier/fits more with your code. I personally prefer the first one as rendering buckets are sooo cool! but if you still want to be in object space, then use the second.

Hope this helps

Thanks! That did it, except I had to keep the RenderQueue to QUEUE_TRANSPARENT because otherwise the background wouldn’t show at all (since it’s transparent).

btw… what exactly did that do? I only have a vague understanding of the zbuffer; why did this fix it?

Just curious but how are you handling when the ship flies past the texture?



Are you constantly moving the textures back under the ship?

No, the texture stays in place, it’s the ship and camera that move :slight_smile:

Although… when I get the chance I’m going to make it so that the texture “jumps” with the camera (make it unnoticable too), so that I don’t have to make a gigantic plane to hold it, and also so that it seems never ending.

No, the texture stays in place, it's the ship and camera that move Smile


Right ... but can you fly off the edge of your texture right now?

Yes, sorry, read the edit :slight_smile:

The queue defines the order for rendering. Opaque (normal) objects are rendered front to back (faster), transparency renders back to front (accuracy) and ortho renders in orthographic mode. The queue makes sure they are rendered in the correct order based on where the camera is. Otherwise, things are rendered in the order that they were put in the tree.



So, my guess is (just a guess as I don’t have all the details of your app), is as the camera was moving the order of rendered changed enough that your transparent layer was rendered BEFORE the opaque behind it. Because it’s transparent and in front of this other layer, the bottom one must be rendered first, otherwise it won’t be seen through the transparent layer. When you set the render queue, the order never got messed up.

"mojomonk" wrote:
The queue defines the order for rendering. Opaque (normal) objects are rendered front to back (faster), transparency renders back to front (accuracy) and ortho renders in orthographic mode. The queue makes sure they are rendered in the correct order based on where the camera is. Otherwise, things are rendered in the order that they were put in the tree.

So, my *guess* is (just a guess as I don't have all the details of your app), is as the camera was moving the order of rendered changed enough that your transparent layer was rendered BEFORE the opaque behind it. Because it's transparent and in front of this other layer, the bottom one must be rendered first, otherwise it won't be seen through the transparent layer. When you set the render queue, the order never got messed up.
Well, actually both textures are transparent (the bottom one less than the top), and I was setting them both with QUEUE_TRANSPARENT, but that still didn't work. DarkProphet's suggestion to use a ZBufferState that had write disabled and apply it to the two Quad's worked, though I don't understand why.

I’ve written a class that does this. It takes 9 quads arranged into a square and then always moves the quads so that you remain in the middle. If you’d like to use it just let me know. I’ll have to add some more comments.



It’s designed to work assuming your ships are traveling in the xz plane and your camera is looking down on it. Might need some changes depending on how your camera is set up.



It’d be a good reason for me to clean it up though.



It might not be the best way to do things but so far it’s worked for me :slight_smile: We seem to have very similar games going hehe.

"shochu" wrote:
I've written a class that does this. It takes 9 quads arranged into a square and then always moves the quads so that you remain in the middle. If you'd like to use it just let me know. I'll have to add some more comments.

It might not be the best way to do things but so far it's worked for me :) We seem to have very similar games going hehe.
Hey that'd be awesome! Maybe we can discuss our games too (if you have AIM, ICQ, or MSN i just added my contact info).

basically, not writing it to the z-buffer will keep it as far back as possible. I.e the furtherest it can be (even behind the far clip plane). Thats my understanding of it anyway.



DP

Not writing to the zbuffer will prevent it from blocking the drawing of other objects that are deeper into the screen than it is. Not testing the zbuffer for an object will draw the object regardless of whether of not a closer object was already drawn.