2
$\begingroup$

When a source of colored light is very bright, it's center appears white. What is the term I need to look for so I can implement this in my shader? I have added an image which is an example of what I mean. Obviously there is also some bloom going on but that alone doesn't cut it. The search results for "opengl glow" don't seem vey promising either, that just gives me more bloom, not white centers.

I have thought about blending a white emission with the desired color like in this question/answer. However, as you can see that turns the emission pink, not red.

So what I'm really after is a tinted light, glowed, with high (color) contrast.

example of effect

$\endgroup$
3
$\begingroup$

In general this is caused by HDR tone mapping. Tonemap curves typically decrease saturation as the input light gets brighter, so that very bright lights are rendered closer to white on the display. If bloom is rendered in HDR (prior to tonemapping) then the bloom around the light can still be highly saturated since it is of a lower intensity than the light itself, and so doesn't get desaturated by tonemapping as much.

You can see some good examples of this on the UE4 Color Grading and Filmic Tonemapper docs page. Unreal uses the ACES tone mapping curve, which is a pretty good default tone curve that you can easily hook up in your own shader code as well.

That said, lightsabers in Star Wars games are probably a special case visual effect that's tuned specifically to reproduce how they look in the movies. :)

$\endgroup$
0
$\begingroup$

[Disclaimer: I'm a hobbyist, not well-read in computer graphics techniques. I may be unfamiliar with common terminology or methods.]

It's possible to explain and reproduce this effect entirely in a “physically-based” manner, simulating the imperfections of physical objects:

  • Many objects do not emit or reflect single wavelengths of light, but some spectrum, even if one wavelength dominates.
  • Light sensors, whether they are cameras or the human eye, do not have perfect RGB color filters which reject all light outside of non-overlapping bands.

These two effects combined mean that if we make an object bright enough, well past the point of “overexposing” the image, all colors will become perceptually white. All you need to do to implement this is:

  • Specify the monochromatic color of your glow such that none of its color channels are exactly zero.
  • While you're doing your floating-point color calculations in your fragment shader, multiply your glow by a number much greater than 1, causing clipping in the final output image.

A potential disadvantage of this technique is that, if the hue of the glow is not one of the six primary or secondary colors, then there will be a hue shift in the segment between where one color channel saturates and two do; it'll shift some amount towards cyan/magenta/yellow before proceeding to white. This is not unrealistic, but it might be unaesthetic.

Even if there is not a hue shift, the points where individual color channels saturate might be noticeable due to the sharp change in the spatial derivative; this could be improved by introducing a “soft clipping” nonlinearity that slows down the approach to the maximum value of each channel (which is a form of global tone mapping).


As an example of the results of this strategy, here is a simple simulation of a CRT oscilloscope trace that I programmed. The algorithm is:

  1. Draw many dim 1-pixel points overlaid with additive blending.

    (It would be more efficient and precise to use a line with variable brightness, but throwing lots of points at the problem was easy to implement, though it produces artifacts such as dotted lines which are visible in this example.)

  2. Blur.

  3. Multiply by (R=0.1 G=1.0 B=0.5) × a configurable brightness parameter.

enter image description here

Notice that the dark areas (vertical lines) are mostly green and the bright areas (horizontal lines and peaks, where the simulated beam moves slower) have a white core.

$\endgroup$
3
  • $\begingroup$ That looks really neat! Here's what I gathered: render in hdr and blur, now the core pixels and surrounding pixels will have brightness > 1, tonemap (render) that as white. $\endgroup$
    – AnnoyinC
    Dec 29 '20 at 10:12
  • $\begingroup$ @AnnoyinC No blur is needed; you can also draw a designed gradient, and this will be more efficient for large halos. The blur is just a fitting approach for the example, not for all cases. $\endgroup$
    – Kevin Reid
    Dec 29 '20 at 21:09
  • $\begingroup$ @Kevin_Reid that might be useful for billboards and maybe textures, but not bright surface lights, unless I do the cliche "paste a billboard over lights" thing, which I don't want. $\endgroup$
    – AnnoyinC
    Dec 30 '20 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.