Back in 1988 I wrote FOFT, at the start of the game I did a little
sequence where you started out viewing a galaxy from a long way away.
The galaxy rotated in 3D. After a short while the camera zoomed into a
single solar system, then through the solar system to a single planet.
Of course in those days my “galaxy” only had 256 stars, and no dust but
it still took a lot of work to get all the bits to work real time.
I want to do the same sequence again, but I now want it to look great.
My target platform is OpenGLES 1.0, so no shaders, and a very basic form
of GLES, so no point sprites or render to texture.I also need it to run
on mobile devices, so ram is limited.
With these limitations, I am struggling to come up with a design for the
I am thinking of storing my galaxy as a sparse 2D array with each
element containing dust density, star density, and thickness.
However rendering that structure real time is going to be tough.
For the distant view I could run a marching cubes algo and texture each
poly from an atlas, but that won’t work when the camera is inside the
With shaders I would probably look at a ray marching algo, but I don’t
think I can get that real time without them.
Any ideas guys?
Please log in or register to post a reply.
I would probably try regular ol’ billboard particles first, before
trying to take a volume rendering approach.
I think you’re pretty much on the right path. Transitioning from distant
billboards to 3D objects when up close can be tricky, but it can be
done. It’s all about cross fading at the right time, which just means
you have to keep experimenting until you find the sweet spot. I would
basically implement my own software mipmapper and treat level “0” as the
moment when I should start the transition. It helps to throw some dust
in there or pass through a nebula when you really need to pull off some
smoke and mirror magic.
Another alternative would be to use deep zoom. It’s more FMV then actual
programming effort on your part, but it’s easy to setup and allows for
more flexibility than a basic video. Since you mention this is a
sequence and probably won’t need to do much more than present it, it’s
an option I thought I would throw out there. You can see an example of
it here, or if you
have Silverlight installed you can check out the world
While I want it to be good looking for the front end, I’m thinking I
need a cut down version for the navigation display.
So pre-rendering is not really what I want to do.
Bill boarding always looks a little strange to me when you have a lot of
movement, it’s fine for linear zoom, but once you add rotation… iffy.
My thoughts at the moment are heading towards a voxel solution. Each
voxel will be subdivided as they get closer to the camera, At large
distances each voxel would be rendered as a billboard sprite with the
dust and star density used to select which sprite to draw. At closer
distance several sprites. One for the dust and one for each star.
I am worried about the speed though, I think to get the speed I will
have to use too large a scale when all the galaxy is displayed. I
suppose the only way to find out is to try.
Before I do that I will have a play with some ray-casting techniques.
They are easier to implement
Still not sure though. I feel like I’m missing a trick. I have that kind
of itch in the back of my head I get when an idea is trying to fight
it’s way through the day to day rubbish stacked in my head.
Okay I’ve raycast a 256 by 128 image in software
Doesn’t look too bad, I could possibly work with it but I would need to
do a lot of tweaking
Needs a lot of tidying up, but I’m not sure it’s worth it. The code is
very slow. 300-400 mS at a guess
Need to think about it, any ideas?
the code basically does ….
for (int y=0; y<STARVIEW_HEIGHT; y++)
for (int x=0; x<STARVIEW_WIDTH; x++)
float fx = tanHalfFovX * (float)(2*x - STARVIEW_WIDTH)/(float)STARVIEW_WIDTH;
float fy = tanHalfFovY * (float)(2*y - STARVIEW_HEIGHT)/(float)STARVIEW_HEIGHT;
CVec3 d = front - lup * fy - left * fx;
if( castRay( eye, d, t , u) )
starview[pos++] = terrainColor( d, t , u );
starview[pos++] = 0xff0000ff;
Looks puffy, but otherwise neat :)
Raycasting should be fast if the problem set is simple enough, but even
faster would be to reduce your problem to a simple 2D scanline algorithm
with mathematical formulas (spiral, spherical falloff) and cached perlin
noise texture to dictate the denser regions. Even then, if you’re
planing on rendering a dozen unique rotating galaxies then you’re
pushing the limits. If your target hardware is limited to GLES 1.0, I’m
going to guess the CPU is probably not that good either. I would say
this would be more interesting approach if the end result is to render
high quality galaxies, but I’m not so sure for real-time gaming.
Have you considered something more like how Spore does it?
Using a simple particle simulator and billboards, you can pull off a
decent looking galaxy. They used a rather large radial distance in their
game, but it would be trivial to reduce that and get a more tight look.
Best of all, it would be hardware accelerated and you can throw in some
animation effects such as simulating pulsars, animating star luminosity,
create nebulous regions (randomly placed billboards; I know you luv
billboards so much!), and transitioning would be simpler (IMO) when
you’re already dealing with 3D objects.
My galaxy is defined by a 128 by 128 array. Each cell has a byte for
star density, a separate array has dust and colour information.
At the moment I ray cast the star density table to find the intersection
point, then extract colour information from the other table.
Using this approach I can move the camera to anywhere, which is what I
want, but it looks crap and is slow.
I guess I can try the particle system idea, though it’s going to be a
lot of work since I don’t have point sprites.
I’m just thinking aloud here… :D
My galaxy is densely packed, over 75% of the 128 by 128 cells are
occupied. That’s some 12288 cells, I think that’s going to be too much
for a particle approach.
I could easily split it down into some kind of bsp tree, but it’s how to
render the cells when they are at the low level of detail setting that
I’m struggling with.
If I just create an atlas of 2d sprites and work out which to draw based
on view direction….. maybe
How about this,
I use the dust density map to generate 16 textures in each view
Create slices along the x, y, and z axes.
then I draw the 48 textures with additive blending enabled and depth
but I’ll need to do something about edge artifacts…….. how about
using the dot product between the camera and the surface normal as the
alpha value for the blit.
That sounds worth a try. I used something kinda like that for ground fog
in one of our games and it was moderately successful. Would be
interesting to see if it works better for your case.
I’m guessing you might want 1 - (1 - dot product)\^n for some power n as
the alpha value. Then by adjusting n you can get some control over how
quickly the slices fade out when they get toward edge-on.
just done x and y planes at the moment, but looking promising.
Runs real time, still a lot of artifacts, but since the source is only
128 by 128 I don’t expect anything else.
Damn I wish I could use shaders :(
Kind of looks like whip cream :D
:D …. yummie
I compressed the volume in the y plane and it looks a hell of a lot
I am just adding another term, it occurred to me that the dust clouds
are only visible from a long way away. As you get closer the dust
density is so low it disappears.
This term also serves as a switch for adding individual stars.
It’s not as good as I hoped, but it runs in real time and I don’t think
I am going to be able to come up with anything better given the
When I get this extra term in I’ll try and grab a video so we can pull
it apart and come up with something better. ;)
well I added third plane of textures, turned on additive blending,
played with alpha values, looks crap.
especially when zoomed
I really want to avoid having a multi-stage display, 2d long range, 3d
Played with star density table and getting better, but some nasty
artifacts showing up
Mmmm, upgraded from whip cream to a Danish sweet roll :D
Looks like you’re getting closer to perfecting your solution. It’s hard
to tell from just the one photo, but the artifacts seem weird given that
you disabled depth testing and are using additive blending. Maybe the
texture’s you’re producing are not smoothed out? Using a radial gradient
to fade out the texture before it reaches the borders might do the
Damn… why do people talk about food when you are hungry? :D