diff options
author | 2023-06-06 17:06:40 -0700 | |
---|---|---|
committer | 2023-06-06 17:24:26 -0700 | |
commit | 9554c78f3adc9846b76e9d3b96af06e98fb69aa0 (patch) | |
tree | cb51e072386014989aa42d259b9e17a70ae2d821 | |
parent | 226ce3d6c96e1ee091980c3d1ba869c01920b316 (diff) | |
download | iced-9554c78f3adc9846b76e9d3b96af06e98fb69aa0.tar.gz iced-9554c78f3adc9846b76e9d3b96af06e98fb69aa0.tar.bz2 iced-9554c78f3adc9846b76e9d3b96af06e98fb69aa0.zip |
Updated color packing into u32 to consider incorrect web-colors.
-rw-r--r-- | core/src/color.rs | 19 | ||||
-rw-r--r-- | graphics/src/gradient.rs | 33 | ||||
-rw-r--r-- | wgpu/src/shader/quad.wgsl | 29 | ||||
-rw-r--r-- | wgpu/src/shader/triangle.wgsl | 29 |
4 files changed, 61 insertions, 49 deletions
diff --git a/core/src/color.rs b/core/src/color.rs index 9ea6ccbf..9ef66b28 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -132,6 +132,25 @@ impl Color { r | g | b | a } + /// Converts the [`Color`] into a `u32` value containing its linear RGBA8 components. + pub fn into_linear_u32(self) -> u32 { + let [r, g, b, a] = self.into_linear(); + + let [r, g, b, a] = [ + (r * 255.0).round() as u8, + (g * 255.0).round() as u8, + (b * 255.0).round() as u8, + (a * 255.0).round() as u8, + ]; + + let r = (r as u32) << 24; + let g = (g as u32) << 16; + let b = (b as u32) << 8; + let a = a as u32; + + r | g | b | a + } + /// Inverts the [`Color`] in-place. pub fn invert(&mut self) { self.r = 1.0f32 - self.r; diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 57cc007f..97b0a6d7 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -103,11 +103,17 @@ impl Linear { let mut offsets = [0.0f32; 8]; for (index, stop) in self.stops.iter().enumerate() { - let (color, offset) = stop - .map_or((Color::default().into_u32(), 2.0), |s| { - (s.color.into_u32(), s.offset) - }); - colors[index] = color; + let (color, offset) = + stop.map_or((Color::default(), 2.0), |s| (s.color, s.offset)); + + if color::GAMMA_CORRECTION { + //correct colors, convert to linear before uploading to GPU + colors[index] = color.into_linear_u32(); + } else { + //web colors, don't convert to linear before uploading to GPU + colors[index] = color.into_u32(); + } + offsets[index] = offset; } @@ -139,16 +145,17 @@ pub fn pack(gradient: &core::Gradient, bounds: Rectangle) -> Packed { let mut offsets = [0.0f32; 8]; for (index, stop) in linear.stops.iter().enumerate() { - // let [r, g, b, a] = - // color::pack(stop.map_or(Color::default(), |s| s.color)) - // .components(); - let (color, offset) = stop - .map_or((Color::default().into_u32(), 2.0), |s| { - (s.color.into_u32(), s.offset) - }); + .map_or((Color::default(), 2.0), |s| (s.color, s.offset)); + + if color::GAMMA_CORRECTION { + //correct colors, convert to linear before uploading to GPU + colors[index] = color.into_linear_u32(); + } else { + //web colors, don't convert to linear before uploading to GPU + colors[index] = color.into_u32(); + } - colors[index] = color; offsets[index] = offset; } diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index fdcc6743..5a1237e6 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -38,17 +38,10 @@ fn select_border_radius(radi: vec4<f32>, position: vec2<f32>, center: vec2<f32>) return rx; } -fn l(c: f32) -> f32 { - if (c < 0.04045) { - return c / 12.92; - } else { - return pow(((c + 0.055) / 1.055), 2.4); - }; -} +fn unpack_u32(color: u32) -> vec4<f32> { + let u = unpack4x8unorm(color); -fn to_linear(color: u32) -> vec4<f32> { - let c = unpack4x8unorm(color); //unpacks as a b g r - return vec4<f32>(l(c.w), l(c.z), l(c.y), c.x); + return vec4<f32>(u.w, u.z, u.y, u.x); } struct SolidVertexInput { @@ -269,14 +262,14 @@ fn gradient( @fragment fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> { let colors = array<vec4<f32>, 8>( - to_linear(input.colors_1.x), - to_linear(input.colors_1.y), - to_linear(input.colors_1.z), - to_linear(input.colors_1.w), - to_linear(input.colors_2.x), - to_linear(input.colors_2.y), - to_linear(input.colors_2.z), - to_linear(input.colors_2.w), + unpack_u32(input.colors_1.x), + unpack_u32(input.colors_1.y), + unpack_u32(input.colors_1.z), + unpack_u32(input.colors_1.w), + unpack_u32(input.colors_2.x), + unpack_u32(input.colors_2.y), + unpack_u32(input.colors_2.z), + unpack_u32(input.colors_2.w), ); var offsets = array<f32, 8>( diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl index 5a73a77f..f1bb2733 100644 --- a/wgpu/src/shader/triangle.wgsl +++ b/wgpu/src/shader/triangle.wgsl @@ -4,17 +4,10 @@ struct Globals { @group(0) @binding(0) var<uniform> globals: Globals; -fn l(c: f32) -> f32 { - if (c < 0.04045) { - return c / 12.92; - } else { - return pow(((c + 0.055) / 1.055), 2.4); - }; -} +fn unpack_u32(color: u32) -> vec4<f32> { + let u = unpack4x8unorm(color); -fn to_linear(color: u32) -> vec4<f32> { - let c = unpack4x8unorm(color); //unpacks as a b g r - return vec4<f32>(l(c.w), l(c.z), l(c.y), c.x); + return vec4<f32>(u.w, u.z, u.y, u.x); } struct SolidVertexInput { @@ -130,14 +123,14 @@ fn gradient( @fragment fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> { let colors = array<vec4<f32>, 8>( - to_linear(input.colors_1.x), - to_linear(input.colors_1.y), - to_linear(input.colors_1.z), - to_linear(input.colors_1.w), - to_linear(input.colors_2.x), - to_linear(input.colors_2.y), - to_linear(input.colors_2.z), - to_linear(input.colors_2.w), + unpack_u32(input.colors_1.x), + unpack_u32(input.colors_1.y), + unpack_u32(input.colors_1.z), + unpack_u32(input.colors_1.w), + unpack_u32(input.colors_2.x), + unpack_u32(input.colors_2.y), + unpack_u32(input.colors_2.z), + unpack_u32(input.colors_2.w), ); var offsets = array<f32, 8>( |