-
Notifications
You must be signed in to change notification settings - Fork 719
[css-images-3] Allow dithering as a gradient-painting strategy #4793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
In theory, I agree. In practice, how do we write tests for gradients after that? Is fuzzy matching of ref-tests actually workable here? I don't think we need to enforce the quality of the dithering, but I do thing it'd be unfortunate if the flexibility introduced to allow dithering made it impossible to test the color math at all, and we could no longer reliably test for (for example) whether a gradient is being computed in sRGB vs Lab. |
Maybe we can follow the lead of the box-shadow spec and say that it must be within 5% of the ideal model described by the spec? |
I guess that leaves room for low quality implementations as well as nice dithering, without really allowing for outright wrong. 5% is kind of arbitrary, but why not. |
It was arbitrary for box-shadow too, but eh. And yes, allowing for low-quality impls is fine; the whole point is to provide a better-quality image, and so if you're screwing that up that's your problem. |
In practice, we already don't write reftests for gradients, and there is no API to sample the color at a given point because security/privacy |
Dithering on gradients is a long-established and common practice. It should not be seen as low quality (although it can be used on low quality devices, such as those with effectively 6 bits per component). Rather, a small amount of noise added to the gradient helps prevent mach banding. |
5% of what? the RGB values? Those aren't uniform; 5% at the dark parts of the curve are a lot, while 5% in the light parts is a lot less visible. If we want to legislate on allowed differences of color, there are already specifications for that. Delta-E (several formulae of varying complexity and accuracy, the simplest being Euclidean distance in Lab/LCH) already predicts just noticeable differences. |
While 5% (distance in RGB) is a lot and non-uniform, (1) it should be well more than any reasonable dithering strategy causes, and (2) we already use the exact same spec limitation to define how shadow blur works, by defining the "ideal" blur as a gaussian and allowing 5% deviation from that (which admits reasonable box-blurs, but not things that are way off), and shadows cover the full spectrum of dark to light. |
Maybe that's a policy we should change, especially if we introduce features like alternative interpolation spaces? I assume it's that's way because we didn't have a good standard for measuring a “good enough” gradient in a fuzzy reftest.
Ideally: 5% of the change in color along the gradient vector. E.g., represent the color at this point as a vector in the correct color-space, then the absolute distance/magnitude between that value and colors at the nearest color stops should be ±5% of the mathematical value. That means, no dithering that is more extreme than the actual change in color stops, no dithering at all in solid stripe gradients (5% of 0 is 0 allowed deviation), but on the other hand, some variation in the “direction” of the interpolation is allowed so long as the magnitude change is reasonable (e.g., a gradient between grays could use “pseudogray” effects: very, very unsaturated colors to create finer progressions of luminance). |
The allowed range would actually need to be expressed something like [floor(ideal - 5%), ceil(ideal + 5%)], where floor/ceil are applied per display color channel, extending to the next value the display can represent. The whole point of dithering is to soften changes between the color values that the display can actually represent. |
I'd actually been meaning to write up some tests for gradients to test the decision (edit: actually it's still merely a suggestion) in #4647, that gradients interpolate in the colorspace of their components if they're all the same, and Lab otherwise. The approach I had in mind was this: https://jsbin.com/nowiwil/1/edit?html,css,output Broadly: with 8-bit color, a wide enough gradient and no dithering, the mid-point of the gradient is effectively a solid block of color. Of course if dithering is introduced this approach won't be possible. (aside: we use simple RGB-differencing when we compare our renderings against the reference images in our test harness. We did try switching to Delta-E, but the slowdown was absurd - a factor of 10 or so. No doubt things would be better in C, but there's bound to be a cost if you require Delta-E for differences) |
The CSS Working Group just discussed
The full IRC log of that discussion |
So the outcome is just that impls that are already testing their dithered gradients, please share details of your testing strategy so we can put some testing requirements into the spec that'll make gradients testable without overly constraining implementations. |
Currently, the Images spec strictly defines the color of each pixel in a gradient - the gradient-line is colored according to the defined interpolation between color stops, and then the image is painted according to what point on the gradient line a given pixel is closest to.
However, WebKit apparently dithers its gradients to produce a smoother overall appearance. I think this should be allowed! Random dithering is a great rendering strategy for making gradients look even smoother, especially when the endpoints are fairly close in color-space; it avoids the hard line where the color shifts up or down one channel-unit, which can be pretty visible in some circumstances.
So I propose that we add some normative text to allow dithering as a rendering strategy. I don't think we need to put in any strict requirements on how far from ideal the dithering is allowed to be; we can leave that up to QoI and just rely on reasonable fuzzy-matching for reftests.
The text was updated successfully, but these errors were encountered: