-
Notifications
You must be signed in to change notification settings - Fork 71
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
Add dithering support #11
Comments
It's enough to add 0.5 * random([0..1]) to the value before rounding it. use clamped::Clamp;
use core::ops::Mul;
use num_traits::{float::Float, identities::Zero};
use oorandom;
pub fn quantize<T>(
value: T,
one: T,
min: T,
max: T,
dither_amplitude: T,
rng: &mut oorandom::Rand32,
) -> T
where
T: Float + Mul<f32, Output = T>,
{
(one * value + dither_amplitude * rng.rand_float())
.round()
.clamped(min, max)
} To go from 0..1 to 0..255 with dithering: let quantized_value = quantize::<f32>(value, 255.0, 0.0, 255.0, 0.5) as u8; min/max are for conversion of HDR with headroom and you may not need this. For example, going to 15 bit with one bit of headroom: let quantized_value = quantize::<f32>(value, 32767.0, 0.0, 65535.0, 0.5) as u16; If deterministic results are not needed, the rng can be initialized inside the function ofc. |
I plan to use Skia's implementation. |
Yes, that one will work for many cases. Not sure if those bitshift ops will end up being faster than a rng lookup though. However, after you add #12 and someone wanted to use I'd suggest making the dither algo pluggable somehow – if that's not too much work (closure, maybe?). |
Not possible. The rendering pipeline is very low-level and vectorized. |
Makes gradients nicer, afaiu.
The text was updated successfully, but these errors were encountered: