3
$\begingroup$

I've been making a simple game in OpenGL, and implemented a screen fade-out using the old 'draw a black fullscreen quad and ramp up the alpha' trick. I'm doing all my shaders in linear space and using GL_FRAMEBUFFER_SRGB to automatically apply gamma. When fading out the screen I noticed that the alpha blending also becomes nonlinear - to fade to ~25% brightness I need to use an alpha of ~0.95.

I fired up Unity for comparison, and its alpha blending also seems to work this way - when rendering in linear mode most of the opacity is bunched towards the top of the alpha range.

Is this expected behaviour? Is it correct from a PBR point of view? It seems very unintuitive. As a workaround, to get more intuitive blending, would it be reasonable to apply gamma correction of 0.45 to the alpha channel before blending?

EDIT: this is the result I get after blending a .95 alpha black quad over a pure white button. It could be bad gamma on my display as Simon F suggested in the comments, but it looks a lot brighter than 5% to me.

enter image description here

$\endgroup$
5
  • $\begingroup$ IMHO, the alpha channel should always be linearand treated as such, though I've no idea what Unity is doing. Oh! It just occurred to me: are you expecting a perceptually linear fade-out? I.e. Over, say, 16 frames, frames 4, 8, & 12 should look, respectively, 3/4s, 1/2, and 1/4 as bright as the original? $\endgroup$
    – Simon F
    Jul 9, 2018 at 8:24
  • $\begingroup$ Yeah that's what I mean. When using the gamma rendering mode that's what happens, but in linear mode it gets bunched to one end - rendering a black quad over a white one at .95 alpha gives a final pixel value of 63,63,63. $\endgroup$
    – russ
    Jul 9, 2018 at 8:34
  • $\begingroup$ So blending a black over white with alpha=0.95 implies you want something that's only 5% of "fully bright"? Assuming an sRGB mapping, then 61 (i.e. hex 3D) is 5% brightness. If your display is reasonably calibrated, you can verify this by creating a, say 5x4 black image, set one pixel to white, and then tile that to a suitable size, e.g 200x200 pixels. Then draw a, say, 50x50 square in the middle and fill it with 0x3D3D3D. Take a few steps back, squint, and they should be almost indistinguishable. (Again it relies on your monitor behaving correctly). Maybe I should post the image. $\endgroup$
    – Simon F
    Jul 9, 2018 at 13:37
  • $\begingroup$ RE: "EDIT: this is the result I get after blending a .95 alpha black quad over a pure white button. It could be bad gamma on my display as Simon F suggested in the comments, but it looks a lot brighter than 5% to me." Ahh but our visual system is non-linear - much as our hearing is too. For example, the analogue volume control on a hifi amplifier will use a logarithmic potentiometer rather than a linear one (electronics.stackexchange.com/questions/101191/…). You simply need to change your per-frame alpha non-linearly. $\endgroup$
    – Simon F
    Jul 10, 2018 at 10:47
  • 1
    $\begingroup$ Ok that makes sense. So a pixel value of 63 would be physically around .05 brightness on a properly calibrated monitor, but perceptually it will appear brighter. Thanks for your help. $\endgroup$
    – russ
    Jul 10, 2018 at 11:15

1 Answer 1

3
$\begingroup$

Just turning the comments into a fully-fledged answer as it may prove useful to others.

IMHO, the alpha channel should always be linear and treated as such.

You described blending a black quad over a white background using alpha=0.95, and mapping the result back to non-linear space. We'd expect a resulting, physical intensity value of 0.05.

If the non-linear space is sRGB, then a linear value of "0.05" would correspond to an sRGB value of "0.248" which, when mapped to 8-bit, is around 63 (or hex, 3D)

If your display is reasonably calibrated, you can verify this by creating, say, a 5x4 black image, setting one pixel to white, and then tiling that to a suitable size, e.g 200x200 pixels. Then draw a, say, 50x50 square in the middle and fill it with 0x3D3D3D. Here's an example:

enter image description here

If you take a few steps back from your monitor and squint, the centre grey region and the dithered outer should be almost indistinguishable, demonstrating a correct physical model.

The problem you are describing appears to be related to the fact that our visual system is non-linear, much as our hearing is too (though probably not with the same curve). For example, the analogue volume control on a hifi amplifier will use a logarithmic potentiometer rather than a linear one .

You thus 'simply' need to change your per-frame alpha non-linearly to get a perceptually even fade out.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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