Volumetric Light Scattering in three.js

Recently I wanted to use volumetric lighting for a sketch in three.js. In the past I have used Thibaut Despoulain’s (WebGL) Volumetric Light Approximation in Three.js with some updates to get it running in the latest version of three. This time I wanted to dig in and try an implementation directly from the original source, Kenny Mitchell’s Volumetric Light Scattering as a Post-Process in GPU Gems 3.

The general technique remains the same across all the implementations:

  1. Render the scene, with the light source as white and all occluding objects as black, to a texture.

All the magic comes from the shader. In the Gems article Mitchell gives a detailed explanation of the math used ( most of which I don’t understand ) and how he ends up, finally, at his solution to

…estimate the probability of occlusion at each pixel by summing samples along a ray to the light source in image space. The proportion of samples that hit the emissive region versus those that strike occluders gives us the desired percentage of occlusion…

He then adds a series of parameters to this summation to control the effect produced.

  • exposure controls the overall intensity / brightness.

Each of these becomes a uniform in the shader that can be used to manipulate the effect. For my implementation I also included a uniform to adjust the number of samples along the ray, up to a max of 100. Both to see how the effect is built up and to tune the performance. A higher number of samples makes for a more expensive shader and slower frame rates.

To improve performance Mitchell recommends downsampling the effect by rendering it at a smaller scale than the screen and the blurring the result. For the sake of clarity I’m doing the scaled rendering but leaving out the blur.

Additionally, if you don’t like the streaking artifacts that are produced he recommends reducing the contrast in the occlusion scene. In his example images the sun is a mid gray sphere.

front end code and graphics programming.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store