Jump to content
  • Advertisement
Sign in to follow this  

Drawing voxels in Direct3D

This topic is 3059 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

You'd draw them the same way as any other hardware 3D API, which is to say entirely on your own. (However that works. Google time?)

Share this post

Link to post
Share on other sites
You could render the voxels as point primitives. "Surface normals" for the voxels on the boundary of an object can be calculated by checking the density value (e.g., on/off) of neighbouring voxels.

You could also convert the voxel field to a mesh using Marching Cubes or some other surface reconstruction algorithm. If the resolution of the range of densities is low (e.g., only 2 possible densities, on/off, for a binary field), then the resulting mesh will look very blocky. Calculating surface normals from the resulting triangle set is google-stuff, as is the rendering of triangles in general.

You could also use some kind of volume visualization technique to render the voxel field. This would likely involve coding some kind of ray tracing / ray casting shader, where you essentially treat the voxel field like a fog that the camera rays march through.

There are other options, I'm sure.

Share this post

Link to post
Share on other sites
I recently wrote a volume renderer. It's D3D10 but it could run in D3D9.

Here you can find a couple of shots and an useful link to graphicsrunner blog.

The rendering part is a standard (and simple) raymarcher.

To put it simple you draw the backfaces and the frontfaces of the volume in two RTs, as huge as the screen. By "draw" I mean: you save the volume UVW coords to the RTs.

Then you draw again the backfaces and use the two RTs as texture inputs. In the pixel shader you calculate the ray step by dividing backfaceUWV-frontfaceUWV by a fixed number of steps.

You start marching from frontfaceUWV adding the ray step at each iteration and sampling the volume.
Then just accumulate density/opacity until you get very close to 1.0f (it is explained very well in graphicsrunner's blog) or until you reach backfaceUWV.

The problem with this technique is you can't enter the volume (you'd miss the frontfaceUWV) and the volume doesn't mix with the surrounding scene.

I suggest you to give a look at an interesting chapter in GPU Gems 3 to see how you can perfectly integrate the volume inside a 3D scene.

Hope this helps..

Share this post

Link to post
Share on other sites
Sorry for posting again, but I have the doubt you want to render a voxel terrain and not a generic voxel dataset.

If you want to render a terrain, things are a bit different (and tricky).

You need an heightmap texture and a color texture.

Draw a fullscreen quad, then for each pixel calculate the view ray. Start marching from the near plane and sample the corresponding texel at the height map until the current ray position is <= than the texel height. When the ray intersects the heightmap, return the corresponding texel in the color map.

I got a cool "comanche:maximum overkill" effect with point sampling:

To smooth the heightmap you should write a filtering routine interpolating heights:

You can also add fake lighting if you like, calculate the normal from the slope and play with a virtual light.

If you have an heightmap texture you can accelerate rendering by creating a "distance field" texture, so that the raymarching steps will be as large as needed.

Another powerful solution is not to use an heightmap but to fake it using a function returning the height at a given point in 2D space.

There's a lot of great stuff about that on IQ's website.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!