Preliminary results for volume rendering using point clouds

In order to render volumes in Renderman, one has two options. The first is to render a large amount of points (several million to get good results) or ray march through a volume using some density function to compute the volume’s accumulated color and opacity along the ray. In this work, I am attempting to produce a hybrid approach. By sampling density from a relatively sparse point cloud (several thousand points rather than several million) in a ray marching shader rather than a density function, volumes can be modeled or simulated in external applications and rendered in Renderman using Ray-marching. See older posts on the subject for more details.  The following is based on Ian Stephenson.

How do we sample density from a cloud of points? Given a position in the cloud, we need the number of points within a given radius. Dividing this by the volume sampled, density can be approximated. Renderman has two data structures for storing point data: point clouds and brick maps. Brick maps are the most attractive solution, as they store point data in an octree for easy spatial look. However, the function for accessing data from a brick map from within a shader, texture3d(), returns an interpolated value of all the samples within a given radius, not an accumulated one. This necessitated the creation of a custom data structure and interface in the form of a DSO shadop.

Here are the source files:

particlemap.h

particlemap.c

pmapdso.c

converter.c

A simple volume shader samples the kd-tree while ray-marching. Here are some preliminary renders:

Cloud 1Cloud 2Cloud 3

Each of these renders uses a increasingly large sampling radius when calculating density from the kd-tree. As the sample radius increases, the volume begins to converge to a shape with hard edges along what I think are the kd-tree cell boundaries. I’m still investigating how to fix these artifacts. More later.