From d688ed76f5bcef5ee94a58a0f5510a2ec8216df5 Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Mon, 20 Feb 2023 21:21:38 -0500 Subject: [PATCH] Add support for outlined text. --- examples/hello.rs | 2 ++ src/pipeline.rs | 3 +++ src/shader/glyph.wgsl | 23 ++++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/examples/hello.rs b/examples/hello.rs index e656692..03e8efa 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -134,6 +134,7 @@ fn main() -> Result<(), Box> { bounds: (size.width as f32, size.height as f32), text: vec![Text::new("Hello wgpu_glyph!") .with_color([0.0, 0.0, 0.0, 1.0]) + .with_outline_color([1.0, 1.0, 1.0, 1.0]) .with_scale(40.0)], ..Section::default() }); @@ -143,6 +144,7 @@ fn main() -> Result<(), Box> { bounds: (size.width as f32, size.height as f32), text: vec![Text::new("Hello wgpu_glyph!") .with_color([1.0, 1.0, 1.0, 1.0]) + .with_outline_color([0.0, 0.0, 0.0, 1.0]) .with_scale(40.0)], ..Section::default() }); diff --git a/src/pipeline.rs b/src/pipeline.rs index e2d3daf..b15b7ef 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -306,6 +306,7 @@ fn build( 2 => Float32x2, 3 => Float32x2, 4 => Float32x4, + 5 => Float32x4, ], }], }, @@ -448,6 +449,7 @@ pub struct Instance { tex_left_top: [f32; 2], tex_right_bottom: [f32; 2], color: [f32; 4], + outline_color: [f32; 4], } impl Instance { @@ -503,6 +505,7 @@ impl Instance { tex_left_top: [tex_coords.min.x, tex_coords.max.y], tex_right_bottom: [tex_coords.max.x, tex_coords.min.y], color: extra.color, + outline_color: extra.outline_color, } } } diff --git a/src/shader/glyph.wgsl b/src/shader/glyph.wgsl index c8a5910..253ec1c 100644 --- a/src/shader/glyph.wgsl +++ b/src/shader/glyph.wgsl @@ -13,12 +13,14 @@ struct VertexInput { @location(2) tex_left_top: vec2, @location(3) tex_right_bottom: vec2, @location(4) color: vec4, + @location(5) outline_color: vec4, } struct VertexOutput { @builtin(position) position: vec4, @location(0) f_tex_pos: vec2, @location(1) f_color: vec4, + @location(2) f_outline_color: vec4, } @vertex @@ -52,6 +54,7 @@ fn vs_main(input: VertexInput) -> VertexOutput { } out.f_color = input.color; + out.f_outline_color = input.outline_color; out.position = globals.transform * vec4(pos, input.left_top.z, 1.0); return out; @@ -61,9 +64,27 @@ fn vs_main(input: VertexInput) -> VertexOutput { fn fs_main(input: VertexOutput) -> @location(0) vec4 { var alpha: f32 = textureSample(font_tex, font_sampler, input.f_tex_pos).r; + var pixel_size: vec2 = (1.0 / vec2(textureDimensions(font_tex))); + + var border = false; + for(var i = -1; i <= 1 && !border; i += 1) { + for(var j = -1; j <= 1 && !border; j += 1) { + if i == 0 && j == 0 { + continue; + } + if textureSample(font_tex, font_sampler, input.f_tex_pos + pixel_size*vec2(f32(i), f32(j))).r <= 0.0 { + border = true; + } + } + } + if (alpha <= 0.0) { discard; } - return input.f_color * vec4(1.0, 1.0, 1.0, alpha); + if border { + return input.f_outline_color * vec4(1.0, 1.0, 1.0, alpha); + } else { + return input.f_color * vec4(1.0, 1.0, 1.0, alpha); + } }