Attach geometry to sky

Hi guys,



(What I tried before)

I’m trying to add a moon and a sun to my dynamic sky system. I tried adding a transparent sky sphere on which I map the moon and it works, but it’s not quite good enough. First of all, it takes a lot of vertices just to display a 2D image, so not very efficient. On top of that to make the moon move in the sky I rotate the sky sphere, so the moon moves in the sky but it changes angle and it does not seem always perfectly round. The angle of the camera distorts the moon shape. So I dropped that approach.



(What I’m trying now)

I decided to add a simple Picture with a billboard control to display the moon. It’s always facing the camera so it’s always round. But it stays where it is. If the camera moves away the moon fades in the distance.



(The problem)

Is there a way to emulate the sky material definition with the sky moving along with the camera with all kind of geometries that must not be centered at the camera location? I can’t find any way to accomplish this. Has anybody done this before? If not, I’m thinking of a “.vert” shader that would add the camera location to each vertex location so the geometry would follow the camera. I don’t know if this is a viable approach and my many attempts at this were unsuccessful. I don’t see how to extract the camera location in the world in the shader or add it the vertex location. I read some documentation about GLSL shaders but I don’t understand much. I don’t know C and I’m horrible at math. :stuck_out_tongue:



Can anyone give me a hand? Any clues and suggestions would be appreciated.



Thanks!

Hi.



I’m gonna come clean first - this is an awful approach, and those other approaches you mention are insane, quite frankly.



If you want a starting point tho, without having to worry too much about shaders or different projections, I suggest this. It is very easy to do.


  1. Use a directional vector for the sun. Initialize it.



    protected static Vector3f sunDirBase = new Vector3f(500,100,0);



    Note rotation will be around the x-axis.


  2. Create a quaternion.



    protected Quaternion rot = new Quaternion().


  3. Create a timer variable, and a multiplier.



    protected float time;

    protected float timeMult = 0.05f;


  4. Do this every update.





    public void update(tpf){

    time += tpf;

    rot.fromAngleNormalAxis(time*timeMult, Vector3f.UNIT_X);

    // Rotate the sun vector so the sun moves in an arc across the sky.

    Vector3f sunPos = rot.mult(sunDirBase);

    // Add the location of the camera to the sun vector, so it moves along with

    // the viewer. Don’t add the viewing position height tho, or else the height

    // of the sun will change when the viewer moves up and down…

    Vector3f camDir = camera.getLocation().clone();

    camDir.y = 0;

    // Update the sun billboard position.

    weirdBillboard.setLocalTranslation(camDir.add(sunPos));

    }





    Now every update your sun will be at a fixed distance from the viewer (same as the length of sunBaseDir), and thus will not change in size. It will move in a circle. You can do the same thing for the moon, but make it start at maybe (500,-100,0) instead, so it goes up when the sun goes down etc. This of course is an extremely idealized model.
2 Likes

@vincent just set the position of the moon to be based on camera position. E.g the moon follows the camera.



[java]

sky.setLocalTranslation(Scene.getScene().getPlayer().getPosition().add(0,-100f,0));

[/java]

1 Like

@androlo:

Thanks! I’m glad you told me these approaches are insane. I had the same feeling but I couldn’t find a better way to do it. Also, I’m happy to see there is a shaderless approach to this situation. I’m going to try it out.



@tralala;

This seems even easier to implement, but unless I’m missing something (which is probably the case), the moon won’t move following time of day it will always remain in the same position in the sky.



Thanks a lot for the help guys! I really appreciate this. :slight_smile: