Don't convert web text colors to linear
This commit is contained in:
parent
7f9afac93e
commit
bfb07147cd
4 changed files with 46 additions and 16 deletions
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue