Skip to content

Latest commit

 

History

History

lic

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

lic.diderot: 2D line integral convolution (LIC) of a flow field

This example performs naive line integral convolution (LIC) in a 2D flow field. The contrast of the result is modulated by the flow magnitude (lower contrast at lower velocity), and the coloring is according to the flow vorticity.

For demonstration purposes, some variables and inputs for this program are specific to a particular flow field (../data/sqflow2D.nrrd), which we symlink to with flow.nrrd. First we need the noise texture that will be convolved by streamlines along the flow. This generates rand.nrrd:

ln -s ../data/sqflow2D.nrrd flow.nrrd
unu slice -i flow.nrrd -a 0 -p 0 | # get a scalar image
  unu resample -s x4.167 x3.125 | # upsample to ~isotropic image
  unu 1op nrand -s 42 -o rand.nrrd # randomize with seed 42

The values generated by upsampling are irrelevant; the point of the upsampling is just to create a new grid that lives in the same world-space location as the flow data. Different random values would be generated by different random seeds.

Then we need a colormap for the vorticity; this generates cmap.nrrd.

echo "0 1 0   1 1 1   1 0 1" |
  unu reshape -s 3 3 |
  unu resample -s = 300 -k tent -c node | # now a 3x300 array
  unu 2op pow - 1.5 | # brighten a bit
  unu axinfo -a 0 -k rgb | # its an array of colors
  unu axinfo -a 1 -mm -1 1 | # covers [-1,1]
  unu dnorm -i - -o cmap.nrrd

With these files in place, we can compile and run lic.diderot:

diderotc --exec lic.diderot
./lic

The output rgb.nrrd needs some post-processing because the results of LIC on the upstream and down-stream halves of the streamline, which were computed by separate strands, need to be combined (by averaging). Looking at the initially statement at the very end, the two halves are indexed last, so they are the fastest axis of the per-strand output grid. The output array, however, contains RGB values on the fastest axis, so it is along axis 1 (length 2) that the averaging of the results of each half are done, followed by quantizing to an 8-bit image:

unu project -i rgb.nrrd -a 1 -m mean |
  unu quantize -b 8 -min 0 -max 1 -o lic.png

The assertion of quantization range [0,1] is based on the smarts used within the program to anticipate what the contrast of the output will be, based on the assumption of each streamline sampling normally-distributed noise. We can use oversampling to anti-alias (but in this case it comes at 9 times the computational cost):

OVSMP=3
./lic -ovsmp $OVSMP
unu project -i rgb.nrrd -a 1 -m mean |
  unu resample -s = /$OVSMP /$OVSMP |
  unu quantize -b 8 -min 0 -max 1 -o lic-$OVSMP.png