Multicolor fog (or fog affected by light color)?

Is it possible to change fog color for a certain area, to give the impression of a glowing light of a certain color brightening the fog with that color?

Or maybe there’s another way to do it: is it possible to make multiple fogs/clouds of multiple color to achieve a similar effect?

Seems I might need to learn “volumetric lighting” to make this happen. Is that right?

Fog shaders were written to only consider the depth of the geometry from the camera. They do not calculate distance to any lights, nor do they take more than one color into consideration. In order to do so, you could take a look at this shader chunk, and modify it with your desired behavior:

Vertex shader:

Fragment shader:

Thanks! Indeed it doesn’t seem too hard for an initial simple approach: make sure shaders have light colors, positions, intensities, and for the given fragment calculate the color change based on those plus fog intensity and color.

The tricky part for me would be coming up with the math formula. I’d bet someone has tried this before.

Oh, wait, but that covers only the color on objects surfaces. This varying object color will look bad if the scene background is a single color and not a gradient, i.e. similarly bad when we currently set the fog to be a different color than the scene background.

We would need to make the background color dynamic as well. Like how the sky gradient changes in this image:

JMP_LEC_311016SWEATHERPIC_01JPG

I wonder if there’s a trick to that. Like maybe a quad in the background of the whole scene, that we color with gradients based on light positioning, then apply the first idea to objects, all drawn on top of the quad. The fogged colors of the objects would match with the part of the background they are over.

I wonder if someone has tried this in any engine.

EDIT: I found this, and it looks good:

https://ijdykeman.github.io/graphics/simple_fog_shader

Screenshot from the article:

5 Likes

Yes, something detail will be dodge.

Hmm, but what the article doesn’t mention is how the background is colored. I think it only mentions coloring the fragments of the objects. I guess the quad-background idea would be needed?

That article looks promising, but he does mention that he uses a deferred rendering pipeline:

I was able to implement this shader in my deferred shading pipeline without making any serious modifications.

… and Three.js DeferredRenderer was removed several years ago.

In principle I think it’s easy. But you would have to ray-trace the scene. You don’t necessarily need the full deferred rendering, just the depth buffer, and you could just keep that potentially from your opaque pass.

You’d trace a ray from each pixel into the scene (this is actually very cheap) against spheres that approximate point lights. You could go beyond that with cones for spotlights and other light types. The basic idea is fairly straight-forward I think.

Personally I think you would need more than just the standard three.js fog model to make this look good, as uniform fog is a bit lackluster and offers little artistic control.
You could experiment with volumetric fog, approximated by particles, and then you’d be illuminating the particles. I think it’s less work overall to get something good looking. You would need “soft particles” implementation, but provided good particle size choice and suitable texture/opacity you’d get something pretty good looking

3 Likes

@Usnul Nice, thanks for the ideas.

@marquizzo I think it can be done with a forward renderer, with either the background quad idea, or a render pass on top of normal scene (the author replied by email, said his was a pass on top).

I think either approach would be effectively the same, but the total number of fragments used in fog calculation would be less in a render pass than with a background quad, because with the quad it will calculate fragments behind objects and end up discarding them.

1 Like

I think volumetric lighting is the right approach here. Either as a postprocessing pass
http://bkcore.com/blog/3d/webgl-three-js-volumetric-light-godrays.html
(very old example, the demo doesn’t work anymore)

Or directly implementing volumetric lighting

http://jeromeetienne.github.io/threex.volumetricspotlight/examples/basic.html

I’m not sure how these would look with fog, but it should be easy enough to test both of those example with colored lights and fog.

3 Likes

Those are really good examples. Thanks! The first demo does work for me:

http://demo.bkcore.com/threejs/webgl_tron_godrays.html

(It would be great if these features existed out of the box for the high-level API users who have no idea how to dive into shaders yet).

1 Like

Yes, the first demo works on Chrome.
That image with the clock tower inspired me to experiment with fog and create such a shader, thanks for sharing.

Another amazing kind of fog (affected by light too) that I’m interested in, is the heavy, dense type:
https://webgl2fundamentals.org/webgl/webgl-shadertoy.html
Imagine this as a dry-ice version, flowing with turbulence on the ground…

2 Likes

Then maybe this example can be a starting point: three.js examples

2 Likes

@prisoner849
Interesting, thanks, although I suspect the technique is very different, but I have to study both (and I have a third idea of my own…)
These are more like art-challenges rather than code-challenges, as the result has to be aesthetically pleasing to be successful, no matter how good the code is, and when you create something beautiful, it’s always rewarding.

Haha! Being a developer would be so much easier if someone else did the work for us :grin:

2 Likes