Weighted Averaging in Ray Tracing
- Dominant language
- JavaScript
- Stars
- 745
- Forks
- 212
- PR merge metrics
- No merged PRs in 30d
Description
Some general comments on the lighting and transparency:
Currently AMI is using additive color mixing, meaning that RGB values are multiplied by the alpha value and added to an RGB accumulator, and the alpha value is added to an alpha accumulator. Once the alpha accumulator hits 1 (total opacity), rendering stops. Although this has the advantage of not requiring voxels to be blended in any particular order, it does mean that semi-transparent voxels will always increase (brighten) the color as the ray passes through the volume. A more visually pleasing way to do this is with weighted averaging, which only works if you render the far voxels before you render the near voxels. In GLSL, the code would look like this:
```GLSL
vec4 color = vec4(0.0, 0.0, 0.0, 0.0); // accumulated color, starting with black
// in raytrace loop:
vec4 newColor = // calculate color for the current voxel here, including lighting
// now mix the accumulated color and the new color
color.rgb = mix(color.rgb, newColor.rgb, newColor.a); // == color.rgb*(1.0-newColor.a) + newColor.rgb*newColor.a
color.rgb = clamp(color.rgb, 0.0, 1.0); // not strictly required, but just in case
color.a = clamp(color.a + newColor.a, 0.0, 1.0); // optional, if you're drawing your volume on top of something else
```
This will allow transparent areas to darken, as well as lighten, the areas behind them.
One downside is that there is no "fast exit" condition in the raytrace when you reach an opaque area, because raytracing is done from back to front and there is always a potential occluder in front that can hide the colors you've already calculated in the back.
/CC @smartin4c
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.