Friday, July 20, 2012

Rendering Imrod

I was compelled to try and render the Imrod model that Jon Olick (worked for ID Software at one point) rendered with voxels. Below is a video of Jon's render, and below that is mine. Jon's is better...

800x600 ~60 fps - SVODepth(10) ~ 2 Million visible voxels
1x GTX 680

I have been optimizing all that I can without the ability to even debug my parallel code, as the Nvidia Cuda Development site has been down from a malicious attack for the past week. I have been in dire need of the Nvidia Parallel Nsight 2.2 debugging app.

I plan to implement voxel contours so that the voxels no longer have the cubical shape when viewed up close, but rather have a smoother surface that better represents the high poly source model.

Disclaimer: This model is the intellectual property of Dmitry Parkin -

Wednesday, July 11, 2012

Optimization Underway

I have been slaving away at this thing for a while now in an effort to optimize the heck out of it. I am making some progress.

640x480 - ~50 fps - SVO Depth(9)
1x GTX 580

OBJ polygon count: 6,615,041
SVO voxel count: 1,484,810 (22% the detail of OBJ)
OBJ file size: ~500 MB
SVO file size: ~88 MB (17% the size of OBJ) 
5% relative size difference over OBJ

My goal is to get the SVO files compressed down much further. Due to the hierarchical nature of sparse voxel octrees, much of the data I am currently saving to the file can actually be rebuilt at load time. I believe I can cut out at least 16 MB of data from the above example.

Sunday, July 8, 2012

Octree Depth Visualization and Dynamic LOD

Here is something to help you wrap your head around how a Sparse Voxel Octree (SVO) is organized.

I rendered the model with each empty octant somewhat visible as a transparent shade of gray. As each primary raycast traverses into a deeper subdivision level within the octree, the rendered pixel gets brighter. If the ray intersects a terminal voxel (visible part of model), it returns the color to draw that pixel. I also show what reducing the maximum subdivision level rendered looks like (Inherent LOD).

First Real Voxel Model

This will probably be the first post anyone will see, as I don't think anyone would be impressed by the first two. This one has a little bit more eye candy. Not as boring as looking at meaningless cubes...

600x480 - ~60 fps - SVO Depth (7)
1x GTX 580

I wrote a Wavefront .obj file converter for getting polygonal models into a voxel format. All the converter does right now is it places a single leaf node (visible voxel) in the center of each quad polygon. The .obj file was exported from ZBrush with no UV map or textures; only polypaint was used to color it. ZBrush exports polypaint color information within the .obj file in a rather large mess of hex color codes. I am rendering this particular model with Blinn-Phong style lighting from within the Cuda kernel. 

I will be focusing on optimising what I have right now for the next week or so. I should be able to increase the detail and frame rate quite a bit.

Wednesday, July 4, 2012

Renderer ported to CUDA

Here is the same setup running in CUDA. I am using a recursive traversal algorithm.

1024x768 - 180 fps - SVO Depth (20)
1x GTX 580
A little more interesting this time.

The smallest Subdivision level shown above is only one millionth the size of the whole octree. A 1km x 1km x 1km scene subdivided 20 times would result in voxels of size 1mm x 1mm x 1mm.

Getting the Directx 11 / Cuda interoperability working was fairly straight forward. I also optimized the traversal algorithm so that it would traverse the voxel hierarchy in order from front to back.

My next goal is to write a converter that will take a high polygon count (~5 million) .obj exported from ZBrush with vertex color information, and compile a sparse voxel octree from this data. From there, I will attempt to load this data into my renderer to see how it performs rendering a single ~5 million voxel model.