Easy Papervision3D space dust tutorial and source


Many space shooters use this concept where you are the pilot that looks out from the front window, lasering down enemies for bounty, right. Ever noticed spacedust? It’s very subtle when it is used, but it adds to the realism of outer space, making the space feel less empty, less static.

Here’s how you can do that in Papervision3D, using ParticleFields. I’ve used the trunk of the papervision code repository, revision 851, but it should work with the last release without to much hassle. Note that I’m no PV3D guru; I just started to learn this stuff and I’m just sharing what I’ve learned so far.

(note: space dust uses the skybox from the skybox tutorial)
    Here’s how it works:

  • divide space into a 3d grid and parts of the spacedust cloud on 8 gridpoints directly around the camera (the ship), we’ll call these dustpockets
  • when the camera moves, dustpockets are removed and created to keep only the 8 gridpoints around the ship occupied

Divide space into a 3d grid and snap dust pockets on it

We’re not actually creating a grid, but we’re going to say things like: “Give me the closest 3d point behind the ship in the upper left corner on the invisible grid”, so that we can create a dust pocket in that position. Sounds complicated? Luckily, the math is easy:

Let’s say there’s only the x-axis. Now from 0 to 100, I want the gridpoint on the left of 32 on grid with size 5. Here is how it would look:

gridpoint 30 lies left of x-value 32 on a grid of size 5

As you can see, the x-value 30 is the value to the left of 32 on a grid with size 5. Here’s the equation to get to that answer:

gridpoint left: Xgrid = Xvalue - (Xvalue % gridsize)
gridpoint right: Xgrid = Xvalue - (Xvalue % gridsize) + gridsize

Example gridpoint left for value 32 and grid size 5:
gridpoint left: Xgrid = 32 - (32 % 5)
gridpoint left: Xgrid = 32 - (2)
gridpoint left: Xgrid = 30

Example gridpoint right for value 32 and grid size 5:
gridpoint left: Xgrid = 32 - (32 % 5) + 5
gridpoint left: Xgrid = 32 - (2) + 5
gridpoint left: Xgrid = 35

We’re going to apply this kind of math to find all 8 gridpoints around the camera. So not just the x-axis, but y and z-axis as well.

The reason we need these 8 gridpoints is because we can’t just create a single cloud. Since the ship can move in any direction and look in any direction, but we can’t fill all of space with dust particles due to memory restrictions, we need to dynamically ‘move’ the cloud with the ship, while keeping the dust particles on the same place. The only way to do this is by dividing the single dust cloud into several small ones and create them as the ship goes. At the same time we need to keep the number of particles down, so we need the minimum dust pockets and still cover all sides by create 8 small clouds that together form a big cloud and can grow in any direction without draining too much memory and cpu power.

Here’s how we’re going to place the clouds:

space dust pockets around the ship on a grid

Here’s the code to do this:

This is really all there is to it. The only thing we need to do now is create new dust pockets for gridpoints without one and remove dust pockets for points that are not within range anymore. Over and over again. Here’s the entire Spacedust class:

Notice the particel fields we’re using to create the eight dust pockets with.

new ParticleField(dustMaterial, particlesPerPocket, 2, fieldsize, fieldsize, fieldsize);

Also, the Basic3DSetup class I’ve used is simply a convenience class with default camera, scene, viewport etc. It’s much like Papervision’s own BasicView -which I didn’t know about at the time- except even cleaner.

The Spacedust class accepts an optional camera to position the dust cloud around. Since this approach is meant to create the illusion of infinite space dust, it doesn’t make sense to create clouds on non-camera’s. Also, you can specify your own particle count and dust material in the constructor of the Spacedust class. The example at the top of the page uses only the defaults.

  • JBrookes

    You don’t need all that.
    create a single particleField

    then in the renderloop


    loop through the particles and move the z position
    reset z position when particle goes behind camera.

    You can do all that and the skybox in under 100 lines.
    post on the forum PV forum if you want to know more.


  • Benny Bottema Post author

    Thank you for taking time to response JBrookes, but I’m not sure I follow. In your snippet, you seem to position the particles around the camera and then moving the particles past the camera, while the idea is to have a moving camera (ship) and then particles that sit still in space which you go past, in any direction, not just z.

    I feel I’m missing something obvious here.


Leave a Reply