Two programs were used in the final implementation. The first performs the scattering and was written in C* [15] for a 16k processor CM2. The second code did the final ray traced step and was built into a flexible C++ ray tracer that already existed and runs on single processor workstations, under CMMD on the CM5 and on the ANU's prototype MIMD parallel Fujitsu AP1000.

The following algorithm in *pseudo-C** outlines the inner loop of
the code of the scattering code:

shape [NX][NY][NZ]volume; float:volume I[n_directions]; float:volume integral,temp; float:volume kappa_rho; bool:volume interior; /* setting up */ ... /* main loop */ while ( error > tol ) { error = 0.0; with (volume) { /* for each propagation direction */ for ( s=0 ; s < n_directions ; s++) { integral = 0.0; for (ss = 0 ; ss < n_directions ; ss++) integral += iv[ss] * p(s,ss) * I[ss]; integral /= FOUR_PI; where (light_sources()) temp = I[s]; else temp = I[s] + h[s] * kappa_rho * (integral - I[s]); where (interior[s]) temp = [.-xd[s]][.-yd[s]][.-zd[s]]temp; where (interior[s] && !light_sources()) { error += ( += (temp - I[s])* (temp - I[s])); /* update intensity */ I[s] = temp; } } error = sqrt(error); } } /* interpolate to find I in the eye direction */ ...The ``

`shape [][][]volume;`

'' statment describes the
dimensions of a parallel ```shape`

''. Then `````
float:volume
<var>;
```

'' declares `<var>`

to be floating point variable with
shape `volume`

. The unary and binary operators operating on the
parallel variables run in parallel (at least notionally).
The function is calculated using a precomputed lookup table for all possible combinations of , and phase functions. The CM2 and CM5 have routines which support fast table lookup by making copies of the table on each sprint node (CM2) or processor node (CM5).

Thu Nov 17 10:01:16 EST 1994