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

broken ColorTest with cpu rendering #6

Open
yjh0502 opened this issue Jan 29, 2023 · 4 comments
Open

broken ColorTest with cpu rendering #6

yjh0502 opened this issue Jan 29, 2023 · 4 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@yjh0502
Copy link

yjh0502 commented Jan 29, 2023

While tracking down rendering errors, I found that color rendering is broken with cpu rendering (cpu_fix).
Here's a code snippet to render ColorTest.

use egui_skia::rasterize;
use skia_safe::{EncodedImageFormat, Paint, Point};
use std::fs::File;
use std::io::Write;

pub fn main() {
    let mut demo = egui_demo_lib::ColorTest::default();

    let mut surface = rasterize(
        (800, 2000),
        |ctx| {
            egui::CentralPanel::default().show(ctx, |ui| {
                demo.ui(ui);
            });
        },
        None,
    );

    let data = surface
        .image_snapshot()
        .encode_to_data(EncodedImageFormat::PNG)
        .expect("Failed to encode image");

    File::create("output.png")
        .unwrap()
        .write_all(&data)
        .unwrap();

    println!("wrote output.png");
}

This is cpu-rendered image, generate from a code above, which shows errors.
output

Here's a side-by-side screenshot, comparing cpu-rendered with webgl one (from https://egui.rs)
image

@yjh0502
Copy link
Author

yjh0502 commented Jan 29, 2023

Some errors could be fixed by un-premultiplying colors from egui.

diff --git a/src/painter.rs b/src/painter.rs
index 5c07f5b..8696332 100644
--- a/src/painter.rs
+++ b/src/painter.rs
@@ -205,11 +205,19 @@ impl Painter {
 
                             pos.push(Point::new(fixed_pos.x, fixed_pos.y));
                             texs.push(Point::new(v.uv.x, v.uv.y));
+
+                            let c = v.color;
+                            let c = Color::from_argb(c.a(), c.r(), c.g(), c.b());
+                            // un-premultply color
+                            let mut cf = skia_safe::Color4f::from(c);
+                            cf.r /= cf.a;
+                            cf.g /= cf.a;
+                            cf.b /= cf.a;
                             colors.push(Color::from_argb(
-                                v.color.a(),
-                                v.color.r(),
-                                v.color.g(),
-                                v.color.b(),
+                                c.a(),
+                                (cf.r * 255.0) as u8,
+                                (cf.g * 255.0) as u8,
+                                (cf.b * 255.0) as u8,
                             ));
                         });

output

@lucasmerlin
Copy link
Owner

Hi! I applied your fix in #7, improving on the color test results. But as you already mentioned it's not perfect yet so I'll leave this issue open for now.
I also tested if I could get this to work by changing the type of the created skia texture but it didn't seem to make any difference.
Happy to accept a PR if someone figures out how to fix the additive blending and linear interpolation test cases!

@lucasmerlin lucasmerlin added the help wanted Extra attention is needed label Feb 15, 2023
@lucasmerlin lucasmerlin added the bug Something isn't working label Aug 11, 2023
@jb55
Copy link

jb55 commented Dec 19, 2023

The colors on rendered images are all messed up (weird pink tinge), I wonder if this is related?

@jb55
Copy link

jb55 commented Dec 21, 2023

I tried rendering a gradient texture and when I sample the color with a color picker, the red and the blue components appear to be swapped. I fixed it with this:

let scol = [0x1E, 0x55, 0xFF];
let ecol = [0xFA, 0x0D, 0xD4];

 // TODO: skia has r/b colors swapped for some reason, fix this
let start_color = Color32::from_rgb(scol[2], scol[1], scol[0]);
let end_color = Color32::from_rgb(ecol[2], ecol[1], ecol[0]);

let gradient = Gradient::linear(start_color, end_color);

before: https://cdn.jb55.com/s/0cdefad30a081797.png
after swapping r/b: https://cdn.jb55.com/s/2da42af5f9f69756.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants