Skybox problem

Hello all,



I'm new to JME, so I thought I'd try something easy to start with. What I've started with was one of the tutorial classes and now I'm trying to recreate is step by step and see if I understand everything correctly. I ran into some trouble when working with a Skybox tough. I have the following code:





package com.ractoc.threedtest;



import java.net.URL;



import com.jme.app.AbstractGame;

import com.jme.app.SimpleGame;

import com.jme.image.Texture;

import com.jme.renderer.Renderer;

import com.jme.scene.Skybox;

import com.jme.scene.state.TextureState;

import com.jme.scene.state.ZBufferState;

import com.jme.util.TextureManager;



public class CameraTest extends SimpleGame{



/**

  • @param args

    */

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    CameraTest app = new CameraTest();

    app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);

    app.start();

    }



    @Override

    protected void simpleInitGame() {

    // TODO Auto-generated method stub

    Skybox sky = new Skybox("sky", 400, 400, 400);



            URL monkeyLoc = CameraTest.class.getClassLoader().getResource(

    "jmetest/data/texture/clouds.png");

            TextureState ts = display.getRenderer().createTextureState();

            Texture t = TextureManager.loadTexture(monkeyLoc, Texture.MM_LINEAR,

            Texture.FM_LINEAR);

            t.setWrap(Texture.WM_WRAP_S_WRAP_T);

            ts.setTexture(t);

            sky.setRenderState(ts);

            rootNode.attachChild(sky);

    }



    }





    This works fine. But when I change the dimensions of my Skybox to 800, 800, 800 I get great black gaps in the corners. I'm using the clouds image from the jme CVS distribution.



    If anyone can tell me what's causeing this and how I can fix it. Because as far as I could tell, it should just tile my texture to cover the entire surface of the side of the skybox.



    Mark

Is it the far plane of the camera clipping it away? Try to increase the far clipping plane.

Ok, I tried setting the frustum and the frustum perspective, but this doesn't seem to fix the problem. It doesn't apear to be frustum related anyway, since from what I read, frustum clipping clips the edges of the screen, and for me the black part is in the center.

it doesn't only clip "the edges of the screen". it also clips everything behind a certain distance from the camera (the far plane). could you post a screenshot?

Here’s the screenshot of my problem:

http://www.ractoc.com/images/3dtest.bmp

It’s a bit big because it’s a bitmap, so I didn’t post it in the post but as a hyperlink.



One thing though to dhdd, it’s nice to hear that it’s an easy problem to solve, but as I said earlier, I’m new to jme, so some example code would be nice, just stating that it’s easy to fix and dropping some technical terms doesn’t really help me that much.

the nice thing about skyboxes is that it does not really matter how big they are. make them 10x10x10 and when updating you just have to translate the skybox by the Camera.getLocation() Vector3f.



there, teh done

@dhdd: maybe that should happen by default.

@ractoc: in your update loop (that would be simpleUpdate() in your example), make sure you match your skybox location with the camera location.

something like skybox.getLocalTranslation().set(camera.getLocalTranslation()).

btw: can't open the screenshot. i get a dns lookup failure (at work).

Sorry bout that, there was a typo in the URL, I fixed it now in the above post.



and yes, I know I should set the location of the skybox to the location of the camera to make sure I always stay within the skybox. I just wanted to fix this issue first. But after 2 hours of tinkering I still couldn't get it to work right.

Unless you're doing something really funky one of the two above suggestions should fix it.

Ah, I think I found my problem. I added the following two lines of code:



cam.setFrustum(1.0f, 2000.0f, -0.55f, 0.55f, 0.4125f, -0.4125f);

cam.setFrustumPerspective(45.0f,(float) display.getWidth() / (float) display.getHeight(), 1, 1000);



The first line sets the far plane to the correct distance, but the second sets it again to a distance to close to the camera.

After altering it to:



cam.setFrustumPerspective(45.0f,(float) display.getWidth() / (float) display.getHeight(), 1, 2000);



(just the second line), everything works as it should.



Thanx all for the help.



I also added the code to keep the camera in the center of the skybox, this code should be



sky.getLocalTranslation().set(cam.getLocation());

ractoc said:

everything works as it should.


:)

i'm glad you got it working :wink:

Right…  Farplane clipping distance must be greater than the distance from the center of the box to the corner or you'll get corner gaps.  IOW:



farplane > sqrt(skybox_x^2 + skybox_y^2 + skybox_z^2)



(Where skybox_? is the params you passed into the skybox constructor; they are actually half distances, so it works out nicely.)



So in the case of 800,800,800 you get sqrt((3*(800^2))) or farplane should be greater than ca. 1386 units.



Hope that clears it up.

renanse said:

Right...  Farplane clipping distance must be greater than the distance from the center of the box to the corner or you'll get corner gaps.  IOW:
...

Hope that clears it up.


:?...things just got more complicated for me. In all tutorials it is said that Frostrum is like a pyramid with cut of top (top being closer plane). If I understood correctly, what are you telling now is that Frostrum is more like a piece of Sphere, like a slice of pizza in 2D terms (mmmm... now I'm hungry). If you can see normally distant wall at a straight line, but that same wall gets cut of in the corners of your screen (distance to the wall there is greater and exceeds far clipping plane), then Frostrum in not pyramid like?

The frustum is like a pyramid with the top cut off, but if you point that pyramid at the corner of your skybox (the most extreme case), the distance from your eye to the corner of the box is still going to be as stated in my post above, thus the farclip needs to be at least that distance to prevent corner issues on the skybox.

i hope this helps:



it’s a view from “above” and the red part is the part which doesn’t fit in the frustrum

Thanks sfera.  Your pictures are worth thousands of my words!  :slight_smile:

thank you guys



but that raises another problem, doesn't this mean that you can see farther away in the corners of the screen then with the center? I know it's a OpenGL thing, but do modern games solve this somehow?

no you don't see farther away in the corners. "you" is the near plane and the far plane defines how far you can see. the distance between 2 parallel planes is constant.



do you mean the "corners" of the frustum which are outside the skybox in the image?  the frustum defines like how far "you" can see. let's say you can see 10 km far. if you have a wall in front of you at let's say 1 km, there will be a distance of 9 km which you could see (if the wall wouldn't be there) but you don't. that's what those "corners outside the skybox" are.



i hope i didn't confuse you more :stuck_out_tongue:

sfera said:

the distance between 2 parallel planes is constant.


mathematicly, this is true, but we don't deal with planes, only part of them, and those parts are not same size...

sfera said:

do you mean the "corners" of the frustum which are outside the skybox in the image?  the frustum defines like how far "you" can see. let's say you can see 10 km far. if you have a wall in front of you at let's say 1 km, there will be a distance of 9 km which you _could_ see (if the wall wouldn't be there) but you don't. that's what those "corners outside the skybox" are.

i hope i didn't confuse you more :P


this has nothing to do with skybox now, only with frostrum. I'll wrote an example, since I started to draw and did nothing usefull :)
You, the viewer, are standing at fixed position. The far away clipping plane is at 100m (units, whatever). Object A, let's say a soldier, is standing directly in front of you at 101m. You can't see him. You rotate your view 22.5 degrees to the right, and he should be now at you left corner of the screen. My statement is that now you can see him. Why? Because trapezoid sides are at 22.5 degree angle so they are longer then the closest direct line from near plane to far plane.
Ok I deceided to try to do a picture afterall, in the picture I set the angles much more then they should be so I can clearly show you what I mean:



Edit: I remebered that this can be calculated... if far clipping plane is 100 units away, the length of clipping plane at corners will be:
cos(22.5deg)=100/x  =>  x~108.2
Conclusion: 2 red dots are at same distance from viewer, but the one in corner is in our sight

Edit2: more stuff