Blur Radius Comparison
bjango.com
bjango.com
GPUs and most game engines get this correct, maybe because in animated 3D graphics, you'd notice this immediately. But browsers are ridiculously bad at understanding this -- there was an article a while back that demonstrated some pathological cases.
Developers assuming that RGB is a triplet of 8-bit numbers and that maths can be naively done to those numbers is one of my favourite examples of the Dunning Kruger effect.[1]
It's such a rarity to see a tool correctly implement color management or linear light for transforms by default that it always jumps out as far out of the norm.
> animated 3D graphics
You'd think so... but no. It's a persistent error in 3D games as well, as well as 3D renderers like Blender.
A common question posted in game-dev forums is "textures look brighter/lighter/faded in game compared to Photoshop". This is because most image editors use the sRGB non-linear gamma, but the game engine uses linear light because it's essentially a physical optics simulator. Beginner game developers load the sRGB 8-bit pixel values and then use them as-is without first undoing the gamma to bring them into the linear light space. This results in over-bright textures. The Quake engine and its derivatives were notorious for this kind of thing, made even worse by OpenGL accelerators like the 3dfs Voodoo card doing more incorrect things on top of that.
Similarly, "Cinematic" mode in Blender should be renamed to "not broken" or simply "correct" color management mode.
[1] I'm guilty of making all of the mistakes I've listed here, in a 3D engine, a ray tracer, and several other graphics utilities. We're all beginners at some point!
[2] The "best" video colorist tool on the planet is not color managed on Windows or Linux. It outputs "whatever" to the screen and ha-ha... good luck. On a HDR screen, with HDR on, if you enable HDR in Resolve you get a washed-out incorrect mess. That just blows my mind.
Well, your first counter examples are beginner mistakes (obviously) and a graphics card that the younger half of HN readers have never heard of.
Blender getting it wrong would be inexcusable, though. Maybe I was overly optimistic.
My laptop can output 8K HDR @ 60 fps, which no Decklink card can achieve, at any price. I can get a "clean feed" by simply ticking the "Override to reference mode" checkbox in the NVIDIA driver. Several people have confirmed that this produces bit-accurate output indistinguishable from what a Decklink card outputs.
> fullscreen view on a second monitor
Yes, but it's still not color managed or even enabled for HDR under anything but MacOS! It just outputs the values as-is and lets the OS deal with it, which will treat it as Rec 709 SDR.
I don’t even know what you mean about Outlook and Teams, are you saying the text gamma is wrong? Or they display images wrong?
> Developers assuming that RGB is a triplet of 8-bit numbers and that maths can be naively done to those numbers is one of my favourite examples of the Dunning Kruger effect. [1]
RGB is a triplet of numbers, and you can do naive math on them, to convert to another color space for example. RGB in fact is a naive color space in the first place, not well defined, and does not have a defined gamma, so all math on RGB is de facto naive. sRGB is not RGB.
BTW, please don’t invoke Dunning Kruger snidely to suggest someone’s wrong. It’s a bad meme because DK is widely misunderstood, and suggesting someone’s an example because they’re wrong, ironically, perpetuates the misunderstanding. People making assumptions, or doing something wrong, or even being incompetent, are not examples of Dunning Kruger. People being over-confident is also not an example of Dunning Kruger: they showed in the paper that there is a positive correlation between confidence and competence for the tasks they measure. Therefore, you cannot know when something is an example of DK or not. The paper has rather poor methodology, it is full of priming and leading questions, including the title, and it went viral not because it’s right but because people love to believe the mistaken idea that someone who’s very confident might be incompetent, even though that’s not what the paper demonstrated. Also the Dunning Kruger effect probably doesn’t even exist, plus replication attempts have shown the opposite effects for more difficult tasks, like, say, engineering.
https://talyarkoni.org/blog/2010/07/07/what-the-dunning-krug...
I agree, but defaults also matter. I’d like our tools to not assume everyone’s an expert, which means the default should be to provide good results. Photoshop can definitely work with linear profiles, and the 32-bit mode is good when you need it.
(QuickLook on macOS hasn’t shown correct colours for a while now. FB12602125 and FB13475690 if anyone from Apple is reading this and wants to take a look!)
The main thing to remember is that mathematical operations like blur and resize ought to be done in a linear space, but everything else needs to be non-linear in some way.
- Nonlinear gamma improves storage efficiency because it allocates bits more effectively “where it matters”.
- CRT displays had a nonlinear response curve as well, and this has been baked into standards like sRGB and all video standards.
- The human perception of color is also nonlinear.
These gamma curves are all generally different now, especially with modern HDR display pipelines.
So a correct pipeline is:
1. Undo the source curve into a linear format. E.g.: camera raw formats are usually logarithmic.
2. Do special effects like blending, sharpen, resize, Etc… in linear format.
3. Show grading controls that use a perceptual space to the human user.
4. Encode the output with the appropriate gamut and gamma for the output format, such as sRGB, or some HDR format. Tag it correctly.
As an example of what not to do, the chap that recently invented the “quite okay” image format[1] just ignored all this and encodes RGB 8-bit triples as-is with no indication of color space.
This is simple, clear, and wrong.
In the case of 3D graphics the RGB triples are a direct measurement of luminosity, and go to infinity. The common sRGB format goes from zero to one and represents the input to a function that maps that to an actual intensity. They’re not compatible! This is why mixing these in a game engine results in faded colours. Similarly, the linear output of a ray tracer can’t be sent to a screen as-is, it’ll look wrong.
Similarly ask yourself: which red, green, and blue? Each format defines these with differently! The “red” of Display P3 used by most Apple devices and HDR cinema projectors is very visibly different to the “red” of lsRGB!
These aren’t platonic ideals but points in space that can be measured, defined, and mapped into other color spaces.
Photoshop will also add noise when you convert from 16 bit to 8 bit. The reason for doing this is to prevent visible banding when blurring things, or just working with gradients (like blue skies). This is really important when printing things, because sometimes banding that wasn’t visible on your screen will show up clearly in your prints. Also really important if you scale the colors of a gradient or blurred region later… small steps between colors become larger and there’s no way to get back to smooth.
I only became sensitive to whether software does blur math in higher precision, and whether it dithers, after working with prints and wasting $100 a pop on a large format print that came out with ugly unexpected banding. Last time I checked, Image Magick’s blur and 16->8 conversion was terrible, and has for a long time been one reason stuck in my head why I avoid Image Magick for serious work.
I don’t know how effective adding noise in 8 bits is. It’s better to work in a higher bit-rate colorspace, and only dither at the last second when converting the final to 8 bits. Well, it’s better to never use 8 bits if you can, but that’s not always possible. Hopefully Figma’s noise is at least added during the higher-precision blur operation before storing the results in 8-bit colors. Figma’s noise bias might be a simple mistake, and it might also be the reason they chose to clamp the blacks, if a developer was seeing -1s (which depending on the implementation, might underflow and suddenly show up as a saturated bright color).
Yes, I completely agree. Injecting white noise is a pretty terrible way to avoid banding, given there’s better dithering options available. The blur should be a shader, and the dithering could be done within the shader as long as it’s not error diffusion dithering. I don’t really see why there would be a big perf difference. I think even pattern dithering with a small kernel would give better results than white noise.
In that case, Chrome was the culprit, and since I had mentioned that we were working around the problem, the Chrome devs originally refused to fix the issue, but eventually they did the only right thing and fixed it.
Lots of insights in the comments for this issue: https://bugs.chromium.org/p/chromium/issues/detail?id=179006
https://m2.material.io/design/environment/light-shadows.html
Notice how there are actually two shadows that must be combined. The point light source shadow rendering depends on the object position on screen.
(I’m using roughly SVG’s terminology: fePointLight has x, y and z, which can be approximately infinitely far away but it’ll only be approximately so, and feDistantLight, which has azimuth and elevation, and projects from infinity.)
In this screenshot all the views have the exact same spec: 8dp elevation.
It would be surprising for the key light to be so close to the screen (rather than nearer infinity), given that the design document linked elsewhere seems to expect consistency at particular elevations.
So when QA say that the shadow is too weak, you have to tell your designer this and they have to come up with something different, or you have to increase elevation to compensate, or fall back to a pre-rendered 9-patch, or something else... As i said, annoying :\
They're probably aligned better now.