I like the general direction this project is going :)

>From my point of view, 3D plotting with maximum interactivity of large data
sets is a good thing to focus on.  By "large" I mean anything up to the
size of main memory on a single machine, or at least up to the available
GPU memory.  Publication quality export is a much lower priority
personally, and as Tobias says could be catered for simply by exporting the
pixels.

I suppose 3D plotting of objects can be broken down by dimensionality: 0D
points, 1D lines, 2D surfaces and 3D volumes.  Each category has distinct
visualization techniques and distinct demands of the plotting API.
Matlab's plotting interface mixes up the plotting of 0D and 1D objects
together into the same API, though there's no fundamental reason this has
to be the case.

I've spent quite some effort on the 0D case recently for visualizing point
cloud data from airborne lidar platforms.  (You can find example data in
various places on the web, usually in .las point cloud format, for example
here http://www.liblas.org/samples/autzen/autzen.laz.  There's a few
projects which allow you to extract las data into a more julia-friendly
form - I'd suggest liblas because it has very few dependencies.  Just use
the command line tools and avoid the API if possible, it's a bit nasty ;-)

Here's some things I've found worked for me for visualizing this kind of
data.  It's helpful to have:

* Per-point colour, marker shape, marker size, etc.  (In fact, /arbitrary/
  per-point information which is mapped into the shader via vertex
  attributes are very useful in the system I've developed so far, though
  this might be less of a big deal if the CPU side of things could happen
  in a language with an actual repl.)

* By default, marker size should scale properly with distance to the
  camera.  This is an important depth cue for interactive use which is
  often overlooked.

* Points can be rendered as various marker shapes using the fragment
  shader and glsl discard statement.  It's pretty simple to do proper
  antialiasing based on distance so they don't disappear/shimmer when far
  from the camera.

* It can be helpful to render points as small spheres so they correctly
  hide each other when they're bunched together.  This can be achieved in
  the fragment shader by setting gl_FragDepth.

The above tricks are pretty much summarised in the shader here:
https://github.com/c42f/displaz/blob/master/shaders/las_points.glsl

* Visualizing the full numeric range of a type like Float64 on a GPU is a
  tricky task.  Obviously GPUs tend to work in Float32, but input Float64
  data may have a large offset from the origin; details will be lost when
  naively truncating to Float32.  To be honest, I don't know a good general
  solution to this.  For the geospatial data I work with, I just offset
  the data to a new origin when converting to Float32, and put that origin
  into the camera transformation instead.

* For my use case, It's critical that the interface should make it very
  easy to centre the camera rotation/zoom point on a given part of the
  point cloud.  If this is overlooked, inspecting a part of the 3D scene in
  detail becomes very difficult.  (Matlab's 3D window gets this very, very
  wrong!)

* Hiding and showing individual data sets via the GUI is quite useful, and
  being able to pick those data sets in 3D is also helpful.  When comparing
  two data sets, it's very useful to be able to invert the selection
  (toggle one off and the other on) with a single click or button press:
  This maps the differences into a change in time, which makes assessing
  the differencees much more straightforward for unstructured data like a
  point cloud.  (In matlab I see people hiding a data series by clicking on
  it and pressing delete, and then later undoing that to bring it back!
  There's probably a better way, but for a fundamental operation in
  interactive data exploration it should be more obvious.)


I think these last two points probably generalise to 1D, 2D and 3D data.
IMO there's a case to be made for a simple default GUI with a capable
camera model and control over data set visibility.  This would go a long
way toward making interactive exploration of 3D data a joy rather than a
chore.

I haven't spent so much time with the 1D and 2D cases recently, and even
less on 3D data.  If you're thinking about API choices - about the kinds of
things people might want to render and about how they should communicate
them to the renderer - I suggest having a look at the Gelato techref as an
interesting point of reference
http://film.download.nvidia.com/techref.pdf
(Gelato is a sadly defunct film SFX renderer from Nvidia, with a carefully
considered API which brought along the best points of Pixar's RenderMan
Interface without a lot of the legacy cruft.)

Check out sections 2.1.5--2.1.7 and the intro of 2.8 which deals with how
"primitive variable" parameters are passed to the renderer.  A primitive
variable defines a scalar or vector field to be interpolated over the
surface of the geometric primitive, and the means for the interpolation;
interpolated primitive variables are then accessible in the shader.

It's all rather similar to the way vertex attributes and shaders work
together in modern OpenGL, but with a more convenient higher level
API.  Obviously it's still not high level enough for simple interactive
use, but some of the ideas might form a good substitute for base
OpenGL as an intermediate level API.

~Chris

Reply via email to