Don't convert web text colors to linear

This commit is contained in:
grovesNL 2024-01-15 21:13:50 -03:30 committed by Josh Groves
parent 7f9afac93e
commit bfb07147cd
4 changed files with 46 additions and 16 deletions

View file

@ -51,7 +51,7 @@ pub(crate) struct GlyphToRender {
dim: [u16; 2], dim: [u16; 2],
uv: [u16; 2], uv: [u16; 2],
color: u32, color: u32,
content_type: u32, content_type_with_srgb: [u16; 2],
depth: f32, depth: f32,
} }

View file

@ -4,7 +4,7 @@ struct VertexInput {
@location(1) dim: u32, @location(1) dim: u32,
@location(2) uv: u32, @location(2) uv: u32,
@location(3) color: u32, @location(3) color: u32,
@location(4) content_type: u32, @location(4) content_type_with_srgb: u32,
@location(5) depth: f32, @location(5) depth: f32,
} }
@ -32,8 +32,7 @@ var mask_atlas_texture: texture_2d<f32>;
@group(0) @binding(3) @group(0) @binding(3)
var atlas_sampler: sampler; var atlas_sampler: sampler;
fn srgb_to_linear(srgb: u32) -> f32 { fn srgb_to_linear(c: f32) -> f32 {
let c = f32(srgb) / 255.0;
if c <= 0.04045 { if c <= 0.04045 {
return c / 12.92; return c / 12.92;
} else { } else {
@ -78,15 +77,31 @@ fn vs_main(in_vert: VertexInput) -> VertexOutput {
vert_output.position.y *= -1.0; vert_output.position.y *= -1.0;
vert_output.color = vec4<f32>( let content_type = in_vert.content_type_with_srgb & 0xffffu;
srgb_to_linear((color & 0x00ff0000u) >> 16u), let srgb = (in_vert.content_type_with_srgb & 0xffff0000u) >> 16u;
srgb_to_linear((color & 0x0000ff00u) >> 8u),
srgb_to_linear(color & 0x000000ffu), switch srgb {
f32((color & 0xff000000u) >> 24u) / 255.0, case 0u: {
); vert_output.color = vec4<f32>(
f32((color & 0x00ff0000u) >> 16u) / 255.0,
f32((color & 0x0000ff00u) >> 8u) / 255.0,
f32(color & 0x000000ffu) / 255.0,
f32((color & 0xff000000u) >> 24u) / 255.0,
);
}
case 1u: {
vert_output.color = vec4<f32>(
srgb_to_linear(f32((color & 0x00ff0000u) >> 16u) / 255.0),
srgb_to_linear(f32((color & 0x0000ff00u) >> 8u) / 255.0),
srgb_to_linear(f32(color & 0x000000ffu) / 255.0),
f32((color & 0xff000000u) >> 24u) / 255.0,
);
}
default: {}
}
var dim: vec2<u32> = vec2(0u); var dim: vec2<u32> = vec2(0u);
switch in_vert.content_type { switch content_type {
case 0u: { case 0u: {
dim = textureDimensions(color_atlas_texture); dim = textureDimensions(color_atlas_texture);
break; break;
@ -98,7 +113,7 @@ fn vs_main(in_vert: VertexInput) -> VertexOutput {
default: {} default: {}
} }
vert_output.content_type = in_vert.content_type; vert_output.content_type = content_type;
vert_output.uv = vec2<f32>(uv) / vec2<f32>(dim); vert_output.uv = vec2<f32>(uv) / vec2<f32>(dim);

View file

@ -271,6 +271,7 @@ pub struct TextAtlas {
pub(crate) shader: ShaderModule, pub(crate) shader: ShaderModule,
pub(crate) vertex_buffers: [wgpu::VertexBufferLayout<'static>; 1], pub(crate) vertex_buffers: [wgpu::VertexBufferLayout<'static>; 1],
pub(crate) format: TextureFormat, pub(crate) format: TextureFormat,
pub(crate) color_mode: ColorMode,
} }
impl TextAtlas { impl TextAtlas {
@ -450,6 +451,7 @@ impl TextAtlas {
shader, shader,
vertex_buffers, vertex_buffers,
format, format,
color_mode,
} }
} }

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError, RenderError, ColorMode, FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError,
Resolution, SwashCache, SwashContent, TextArea, TextAtlas, RenderError, Resolution, SwashCache, SwashContent, TextArea, TextAtlas,
}; };
use std::{iter, mem::size_of, slice, sync::Arc}; use std::{iter, mem::size_of, slice, sync::Arc};
use wgpu::{ use wgpu::{
@ -276,7 +276,13 @@ impl TextRenderer {
dim: [width as u16, height as u16], dim: [width as u16, height as u16],
uv: [atlas_x, atlas_y], uv: [atlas_x, atlas_y],
color: color.0, color: color.0,
content_type: content_type as u32, content_type_with_srgb: [
content_type as u16,
match atlas.color_mode {
ColorMode::Accurate => TextColorConversion::ConvertToLinear,
ColorMode::Web => TextColorConversion::None,
} as u16,
],
depth, depth,
}) })
.take(4), .take(4),
@ -405,13 +411,20 @@ impl TextRenderer {
} }
} }
#[repr(u32)] #[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ContentType { pub enum ContentType {
Color = 0, Color = 0,
Mask = 1, Mask = 1,
} }
#[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum TextColorConversion {
None = 0,
ConvertToLinear = 1,
}
fn next_copy_buffer_size(size: u64) -> u64 { fn next_copy_buffer_size(size: u64) -> u64 {
let align_mask = COPY_BUFFER_ALIGNMENT - 1; let align_mask = COPY_BUFFER_ALIGNMENT - 1;
((size.next_power_of_two() + align_mask) & !align_mask).max(COPY_BUFFER_ALIGNMENT) ((size.next_power_of_two() + align_mask) & !align_mask).max(COPY_BUFFER_ALIGNMENT)