Multilayered moving starfield background problem

I want to create a multilayered starfield. Something like this:





The layers would be transparent except for the stars themselves and would be placed with some space between them. The result wouold be that when I zoom in and out, the stars on different layers also move in relation to eachother, as if I was actually moving through space a little.



At this point the only way I can think of doing it is using 3 quads behind my scene with one texture rendered on each of them in transparent render queue. However this would mean that my textures would have to be mighty large and detailed for it to look nice. Since I want to use several layers, I assume I cannot use the Skybox’s trick of disabling the z-buffer. This leaves me wondering what my options are.



I was almost ready to give up and go with the 3 quads idea, but decided for let you smart-guys help me out  :smiley: If you understand the problem I am facing from this description - what do you think my best option would be?



EDIT: Rotation is locked - the view is fixed in only one direction - along 1 axis, so it does not have to be a fully 3d solution

Personally I'd use a shared node of a textured quad (as high or low rez as you like) for every star… That way you can add them at different Z (into the screen) to vary the size a little… If you add these to a different node for every layer positioned at the bottom center of the screen, you can set the scale of this node, or move it closer and further away to the screen…



Oh another thing… Those stars dont seem very transparent, so you may be able to speed up transparency if you can implement single colour transparency rather than alpha value.



One trick I did once with was having stars as small objects (spheres, billboards, points, whatever) about 1-3 pixels wide on screen, and then moving a group around in space by a small fraction… It made for a realistic scintillating effect… Low performance for the amount of stars to make it look real though! :smiley:

Thank you for the ideas. The image visible above is just a rough scetch so that people would understand what I mean… its not the real texture  Also I do not want to make every star a separate quad or whatever because that would run up the object count in the scene, which I want to keep as low as possible. Also the stars do not have to simulate a real 3d space - just 2 or 3 layers would be fine.


jiminy said:

One trick I did once with was having stars as small objects (spheres, billboards, points, whatever) about 1-3 pixels wide on screen, and then moving a group around in space by a small fraction.. It made for a realistic scintillating effect.. Low performance for the amount of stars to make it look real though! :D


Unfortunately I do not know for sure what 'scintillating effect' is as I am not a native English-speaker. However from the description of the process I believe it is quite similar to what I want to achieve. Just the difference is that I hope to use a smaller number of objects - say just 1 quad for each layer, if it is feasible.

Thanks again

Scintillating is where stars appear to shine and flicker, I think its an atmosphere effect. To me it looks like the stars change their brightness sometimes.



Heres some code, it should work the same if you place your single textured quads on each layer node (adding transparency to them). SharedMesh seemed to ease my performance issues with my mini-quads, but I understand why you'd keep objects to the minimum.



If you're using 3 quads, i'd suggest that your texture is different sizes for each quad, rather than the same size. This should give the layers a different repeat phase, and mean you have to use a smaller size to stay random.



I'm not sure if FastMath.nextRandomInt(int, int) is Jme 2.0 only.



import com.jme.app.SimpleGame;
import com.jme.math.FastMath;
import com.jme.scene.Node;
import com.jme.scene.SharedMesh;
import com.jme.scene.shape.Quad;

public class SharedStars extends SimpleGame {
    public static void main(String[] args) {
        SharedStars app = new SharedStars();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }

    Node[] layers = new Node[3];
    float flickerNess = 0.01f;
   
    public void simpleUpdate() {
       
       layers[FastMath.nextRandomInt(0,2)].setLocalTranslation(FastMath.nextRandomFloat()*flickerNess, FastMath.nextRandomFloat()*flickerNess, FastMath.nextRandomFloat()*flickerNess);
   }
   
    protected void simpleInitGame() {
       
       lightState.setEnabled(false);
       Quad q = new Quad("Quad", .0015f, .0015f);
       q.initialize(0.1f, 0.1f);
       
       layers[0] = new Node("Layer1");
       layers[1] = new Node("Layer2");
       layers[2] = new Node("Layer3");
       
       for (int i = 0; i<100; i++){
          SharedMesh mesh = new SharedMesh("Twinkly Star " + i, q);
          int level = FastMath.nextRandomInt(0,2);
          mesh.setLocalTranslation(FastMath.nextRandomFloat()*50f, FastMath.nextRandomFloat()*50f, (float) (level*-10));
          layers[level].attachChild(mesh);
       }
       rootNode.attachChild(layers[0]);
       rootNode.attachChild(layers[1]);
       rootNode.attachChild(layers[2]);
    }
}

Thanks :slight_smile:



I was initially hoping there was clever way of doing what I wanted perhaps with custom passes, but somewhy (lol) I never thought of just having the textures tile. I was afraid I'd have to make a texture with size 4096x4096 or whatever. It helps so much often when someone else looks at the same problem with a slightly different perspective and state of mind  :smiley: