Point cloud experiments with Sunflow

This is just a quick heads up about my ongoing efforts to create a Processing library to integrate Sunflow, an opensource global illumination renderer, into my tool chain. Initially, I'm only after exporting generated 3D scenes/geometry, shaders and various render specific settings to Sunflow's scene description format.

using a glass shaderAmbient_occlusion (AO)AO & depth of field

This series and the previous images (with the random triangles) were fully rendered outside Processing. Currently this is far more flexible than my other plan to have Sunflow wrapped in a PGraphics. For one, the export option allows for easier tweaking the scene parameters (the global illumination lighting models have a lot of parameters and options to explore) as well as batch rendering frame sequences from the command line. This is far more resource friendly and efficient than handling the rendering directly from within a PApplet context, especially with high quality rendering times often lasting several hours per frame (you can get decent preview within seconds/minutes though).

So the library currently only supports triangulated geometry and I still need to make a decision & come up with a better mechanism to support various Sunflow primitive object types. This decision might involve breaking away from the restrictions imposed by my current implementation, which is based on Processing's beginRaw() mechanism, just like the existing DXF/PDF export libraries. What's fine for these other formats is not quite good enough for my case. For example, using sphere() together with beginRaw() in Processing will currently export a triangulated version of the sphere, not the pure mathematical surface. The problem is, there don't seem to be any API hooks in PGraphics for various drawing commands and or state changes (box() is similar, but not problematic in this case). Unless I'm really missing something quite obvious, “recorder” PGraphics classes only get involved with and get access to the final, world transformed geometry. For my purposes I'd also like to get access to the current fill/stroke colours and transform matrices. Because PGraphics has “protected” access and doesn't provide any getters for these properties, users are currently forced to duplicate some of these drawing commands in order to keep the library in synch with the “main” PGraphics instance used. So am still wading through the source(s) and trying to come up with a more user friendly solution…

By popular demand, here's some more background info about the making of the 3 images above.

The lastest version of Sunflow (still unreleased, need to check out from SVN) is featuring a new ParticleSurface object primitive, which is the basis for the images above. Reading through the source code, I quickly figured out this type of object is only based on 2 parameters: a “point cloud” of 3d particles and a global radius size used for each particle. In order to quickly test drive & define some point clouds of my own, I wrote this absolute basic generator script below:

// point cloud generator for
// Sunflow's (v0.7.0+) ParticleSurface primitive
void setup() {
  try {
    FileOutputStream fs = new FileOutputStream("c:/molecule_"+(System.currentTimeMillis()/1000)+".pointcloud");
    DataOutputStream ds = new DataOutputStream(fs);
    float x=0,y=0,z=0; // start at origin
    float scl=0.25;
    float dim=50;
    for (int i = 0; i < 250000; i++) {
      // randomly progress within the bounding box
      x=max(-dim,min(dim,x+random(-1,1)*scl));
      y=max(-dim,min(dim,y+random(-1,1)*scl));
      z=max(-dim,min(dim,z+random(-1,1)*scl));
      // write out coordinates as raw floats
      ds.writeFloat(x);
      ds.writeFloat(y);
      ds.writeFloat(z);
    }
    ds.flush();
    ds.close();
    println("done.");
  } 
  catch (Exception e) {
    e.printStackTrace();
  }
}

The next step then is to reference this generated data from a Sunflow scene file (You'll need to edit the file name near the end)…

/*
pointcloudtest.sc
sunflow test scene skeleton
2006-12-13 toxi.co.uk
*/
image {
   resolution 768 432
   % resolution 1920 1080
   aa 1 2
}

background {
    color 1 1 1
}

accel kdtree
filter gaussian 2 2
bucket 128 hilbert

%% camera definitions

% uncomment this one to enable depth-of-field
/* camera {
   type thinlens
   eye 0 10 70
   target -20 -20 0
   up 0 1 0
   fov 60
   aspect 1.7777777
   fdist 27
   lensr 0.85
} */

camera {
   type pinhole
   eye    0 10 70
   target -20 -20 0
   up 0 1 0
   fov 60
   aspect 1.7777777
}

%% define a simple area light for soft shadows

light {
   type meshlight
   name l1
   emit 1 1 1
   radiance 48
   samples 32
   points 3
      -60 20 60
      0 60 -60
      60 20 60
   triangles 1
      0 1 2
}

shader {
  name a
  type amb-occ
  bright   .4 .9 1
  dark     0 0 0
  samples  128
  dist     16
}

object {
    shader a
    type dlasurface
    % need edit this file path
    filename c:/molecule_1166058556.dat
    radius 0.125
}

Save this file using the ”.sc” extension and open it in Sunflow. Use the “IPR” renderer for easier previewing. You might need to adjust camera settings to better fit your generated particles.

If you end up successfully rendering something and have a flickr account, please do submit images to the newly created Sunflow group pool. Thanks!

Finally, I'm no expert in global illumination (in fact playing around with Sunflow are my very 1st baby steps with that technology). Everything I know so far about the SC file format is collected from examining the source code of the SCParser class and the demo files you can download. If you have any questions about rendering with Sunflow (not related to the tie-in with Processing), please check the official forum @ Sourceforge…

Last modified: 2009/03/23 12:52