Skip to content

Latest commit

 

History

History
96 lines (79 loc) · 5.01 KB

README.md

File metadata and controls

96 lines (79 loc) · 5.01 KB

dvr.diderot: basic direct volume rendering of a scalar field

Note that this example is heavily based on the mip example, especially for the basic set-up of camera, rays, and strands; some of the variables and code are better documented there.

This program needs a dataset vol.nrrd to render; fs3d-scl is one way to generate this. Some examples:

  • Sphere:
    ../fs3d/fs3d-scl -which dparab -width 5 -sz0 30 -sz1 32 -sz2 35 | unu save -f nrrd -o vol.nrrd
  • XYZ axes indicator:
    ../fs3d/fs3d-scl -which frame -width 3.5 -sz0 93 -sz1 94 -sz2 95 | unu crop -min 30 30 30 -max M M M -o vol.nrrd

The program also uses a univariate colormap cmap.nrrd (not for any important purpose, just to show how it could be used). This can be created via (here we are desaturating the isobow.nrrd colormap):

unu 3op lerp 0.5 ../cmap/isobow.nrrd 1 -o cmap.nrrd

The program can then be compiled with:

diderotc --exec dvr.diderot

Because the program names a proxy volume (vol.nrrd), compilation is specialized on the volume data sizes and sample type. Recompilation is required to operate on new input data with different sizes or type.

Some example invocations, organized according to dataset examples above (still in-progress...):

  • Sphere:
    ./dvr -camEye 10 20 5 -camAt 0 0 0 -camUp 0 0 1 -camNear -2 -camFar 2 -camFOV 8 -iresU 400 -iresV 400 -thick 0.1 -refStep 0.1 -rayStep 0.01 -isoval 0.0 -cmin -1 -cmax 1
  • XYZ axes indicator:
    ./dvr -camEye 3.1 4.0 2.1 -camAt 0.2 0.0 0.4 -camUp 0 0 1 -camNear -0.7 -camFar 0.5 -camFOV 20 -iresU 560 -iresV 480 -thick 0.015 -rayStep 0.005 -maxAlpha 0.95 -isoval 1 -mcnear 1.1 0.9 0.7 -mcfar 0.5 0.7 0.9

All of these will generate an RGBA image as saved as rgba.nrrd, which can be viewed with another Teem utility (peer to unu) called overrgb:

overrgb -i rgba.nrrd -b 1 1 1 -g 1.2 -o out.png

For the sphere dataset (via fs3d-scl -which dparab), this should produce sphere.png. For the XYZ axes indicator dataset (via fs3d-scl -which frame) this should produce axes.png; make sure you get the same.

Volume rendering is one setting in which we can make sure Diderot is doing all the right transformations for measuring derivatives: derivatives measured in volume index-space have to be transformed to get the derivative in world-space. The mip example tested for this kind of invariance in reconstruction of values, but not derivatives. The following generates three different samplings of a rotationally symmetric paraboloid dataset, and then renders each of them with the same parameters, including a little fog to see the shape of the volume domain itself. For this to work as intended, one must comment out field#2(3)[] V = bspln3 ⊛ vol; and uncomment field#1(3)[] V = ctmr ⊛ vol;: the Catmull-Rom accurately reconstructs quadratic functions, but the cubic B-spline does not.

../fs3d/fs3d-scl -which dparab -width 3.8 -sz0 20 -sz1 22 -sz2 25 | unu save -f nrrd -o sphere-0.nrrd
../fs3d/fs3d-scl -which dparab -width 3.8 -sz0 55 -sz1 29 -sz2 12 -angle -30 | unu save -f nrrd -o sphere-1.nrrd
../fs3d/fs3d-scl -which dparab -width 3.8 -sz0 30 -sz1 80 -sz2 19 -angle -30 -axis 1 -1 1 -shear 0.5 -0.6 0.9 | unu save -f nrrd -o sphere-2.nrrd
for I in 0 1 2; do
   cp sphere-$I.nrrd vol.nrrd
   echo "compiling with sphere-$I.nrrd ..."
   diderotc --exec dvr.diderot
   echo "rendering with sphere-$I.nrrd ..."
   ./dvr -camEye 10 20 5 -camAt 0 0 0 -camUp 0 0 1 \
      -camNear -4 -camFar 4 -camFOV 12 -iresU 400 -iresV 300 \
      -phongKa 0 -phongKd 0.8 -phongKs 0.3 \
      -thick 0.03 -rayStep 0.01 \
      -isoval 0.0 -fog 0.5 0.5 0.5 0.012 -o rgba-$I.nrrd
   overrgb -i rgba-$I.nrrd -b 1 1 1 -g 1.2 -o sphere-$I.png
done
unu join -i sphere-?.png -a 0 -incr | unu slice -a 1 -p 0 -o sphere-compare.png

Looking at the individual sphere-?.png, one should see the same sphere (with the same shading and same specular hightlight), surrounded by different foggy regions. These show how sphere-1.nrrd is sampled on a rotated grid, and how sphere-2.nrrd is sampled on a rotated and sheared grid. The sphere-compare.png image puts these three images into the red, green, and blue channels, providing another way to confirm that the sphere itself is the same in each. Try changing the reconstruction kernel to c1tent to see the results of inaccurate reconstruction.

Note that this program approximates the volume rendering integral by updating two variables at each sample along the ray (going front to back):

rgb += transp*sampleA*sampleRGB;
transp *= 1 - sampleA;

where rgb is the (pre-multiplied) color of the ray so far, transp is the transparency (1-opacity), and sampleRGB and sampleA are the color and opacity of the current sample being composited. While such an inner loop is common for volume rendering, one could ask why couldn't Diderot have figured out how transform a high-level mathematical statement of the volume rendering integral into such an implementation. This is a topic of current research.