Rendering a starfield with XEN

Mar 2, 2009 at 11:10 PM
Hi,

First of, congratulations on bringing this 1.5 version out. I see the effort and it's great tool to learn how to program with XNA in a well organized code.

Now, I'm trying to create a Starfield composed of multiple quads colored differently (randomly from white to gray to simulate star shining) and positioned in  a virtual sphere using some vertex and pixel shaders. I wonder what would be the best way to do that.

I would also like your advice on the particle system: wouldn't that be a good system to simulate my starfield?

Thanks,

Philippe
Coordinator
Mar 3, 2009 at 6:35 AM
Edited Mar 3, 2009 at 6:36 AM

Hi, thanks for the positive feedback :-)

The particle system would probably not be a good fit for this problem, as the particle system is intended for temporary effects (it actually has a hard coded limit of 10 minute life span for particles :-) Although it'd be perfect for a 'space particles' type effect for showing how fast you are.

There are a few problems you need to tackle to get a star field to work. The trickiest will probably be the distribution of the stars (so they don't cluster on an axis, or appear to form a cube, that sort of thing). I'm sure there are good algorithms out there to do it.

I'd suggest you draw them first, so they are behind everything (you could draw them last, and use some vertex shader trickery to force their z-depth to 1.0, but drawing them first is probably easiest). Make sure z-writes are disabled though.
I'd suggest you also consider just using Points to draw them (or even lines to simulate motion as you rotate*). It will be easier to setup, as you won't have to generate quads that face the centre point.

*In such a case you'd need to store the previous frames world*view*projection matrix..

Given all your stars in a sphere, in a single vertex/index buffer, the trick will be rendering. When you do render them, you want them to not move when the camera changes position.
The simplest way to do this, would be to set the world position (but not rotation) of the world matrix to the camera position when you draw them, eg:

Vector3 position;
state.Camera.GetCameraPosition(out position);
state.PushWorldTranslate(ref position);
...
state.PopWorldMatrix();

The next tricky problem would be making the stars twinkle... This would actually be fairly tricky to get right (so it doesn't have a noticeable pattern) but the solution would most likely involve a per-vertex (per-star) random value (eg, stored in a texture coordinate or colour) and a time value passed into the vertex shader. How you'd actually generate the twinkle effect would depend heavily on what you are wanting, for example a very slow sin() wave may be enough, or totally inappropriate.

Beyond that it's pretty simple. If you used Points, then it's just a vertex buffer storing Position and Colour data, it doesn't even need indices. Quads are certainly a bit trickier, and would involve a bunch of maths to align them to face the origin correctly (cross products, etc).

Is that the sort of info you were after?