Skip to content
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

Open
RazrFalcon opened this issue Nov 7, 2020 · 4 comments
Open

Add dithering support #11

RazrFalcon opened this issue Nov 7, 2020 · 4 comments

Comments

@RazrFalcon
Copy link
Collaborator

Makes gradients nicer, afaiu.

@virtualritz
Copy link

virtualritz commented Dec 7, 2020

It's enough to add 0.5 * random([0..1]) to the value before rounding it.
This is from an unpublished crate with color utilities I'm working on atm:

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.

@RazrFalcon
Copy link
Collaborator Author

I plan to use Skia's implementation.

@virtualritz
Copy link

virtualritz commented Dec 7, 2020

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 tiny-skia for creating art exported e.g. as OpenEXR and which is color-graded afterwards, they don't want the dither pattern to show up.
I.e. for generative art etc. (check e.g. valora).

I'd suggest making the dither algo pluggable somehow – if that's not too much work (closure, maybe?).

@RazrFalcon
Copy link
Collaborator Author

I'd suggest making the dither algo pluggable somehow

Not possible. The rendering pipeline is very low-level and vectorized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants