mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 23:21:08 +03:00
Consolidate shader logic
Now that we have a single pass, we don't need to "include" snippets, and that makes the shaders a lot easier to follow. refs: #986
This commit is contained in:
parent
725572de9c
commit
e165cdf210
@ -1,113 +0,0 @@
|
||||
// This file is automatically prepended to the various -frag shaders.
|
||||
|
||||
precision highp float;
|
||||
|
||||
in float o_has_color;
|
||||
in vec2 o_tex;
|
||||
in vec3 o_hsv;
|
||||
in vec4 o_fg_color;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform vec3 foreground_text_hsb;
|
||||
|
||||
float multiply_one(float src, float dst, float inv_dst_alpha, float inv_src_alpha) {
|
||||
return (src * dst) + (src * (inv_dst_alpha)) + (dst * (inv_src_alpha));
|
||||
}
|
||||
|
||||
// Alpha-regulated multiply to colorize the glyph bitmap.
|
||||
vec4 multiply(vec4 src, vec4 dst) {
|
||||
float inv_src_alpha = 1.0 - src.a;
|
||||
float inv_dst_alpha = 1.0 - dst.a;
|
||||
|
||||
return vec4(
|
||||
multiply_one(src.r, dst.r, inv_dst_alpha, inv_src_alpha),
|
||||
multiply_one(src.g, dst.g, inv_dst_alpha, inv_src_alpha),
|
||||
multiply_one(src.b, dst.b, inv_dst_alpha, inv_src_alpha),
|
||||
dst.a);
|
||||
}
|
||||
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
const vec3 unit3 = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec4 apply_hsv(vec4 c, vec3 transform)
|
||||
{
|
||||
if (transform == unit3) {
|
||||
return c;
|
||||
}
|
||||
vec3 hsv = rgb2hsv(c.rgb) * transform;
|
||||
return vec4(hsv2rgb(hsv).rgb, c.a);
|
||||
}
|
||||
|
||||
// Given glyph, the greyscale rgba value computed by freetype,
|
||||
// and color, the desired color, compute the resultant pixel
|
||||
// value for rendering over the top of the given background
|
||||
// color.
|
||||
//
|
||||
// The freetype glyph is greyscale (R=G=B=A) when font_antialias=Greyscale,
|
||||
// where each channel holds the brightness of the pixel.
|
||||
// It holds separate intensity values for the R, G and B channels when
|
||||
// subpixel anti-aliasing is in use, with an approximated A value
|
||||
// derived from the R, G, B values.
|
||||
//
|
||||
// In sub-pixel mode we don't want to look at glyph.a as we effective
|
||||
// have per-channel alpha. In greyscale mode, glyph.a is the same
|
||||
// as the other channels, so this routine ignores glyph.a when
|
||||
// computing the blend, but does include that value for the returned
|
||||
// alpha value.
|
||||
//
|
||||
// See also: https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-gamma-correct-font-rendering/
|
||||
vec4 colorize(vec4 glyph, vec4 color, vec4 background) {
|
||||
float r = glyph.r * color.r + (1.0 - glyph.r) * background.r;
|
||||
float g = glyph.g * color.g + (1.0 - glyph.g) * background.g;
|
||||
float b = glyph.b * color.b + (1.0 - glyph.b) * background.b;
|
||||
|
||||
return vec4(r, g, b, glyph.a);
|
||||
// return vec4(glyph.rgb * color.rgb, glyph.a);
|
||||
}
|
||||
|
||||
vec4 colorize2(vec4 glyph, vec4 color) {
|
||||
float r = glyph.r * color.r;// + (1.0 - glyph.r) * background.r;
|
||||
float g = glyph.g * color.g;// + (1.0 - glyph.g) * background.g;
|
||||
float b = glyph.b * color.b;// + (1.0 - glyph.b) * background.b;
|
||||
|
||||
return vec4(r, g, b, glyph.a);
|
||||
// return vec4(glyph.rgb * color.rgb, glyph.a);
|
||||
}
|
||||
|
||||
vec4 from_linear(vec4 v) {
|
||||
return pow(v, vec4(2.2));
|
||||
}
|
||||
|
||||
vec4 to_gamma(vec4 v) {
|
||||
return pow(v, vec4(1.0/2.2));
|
||||
}
|
||||
|
||||
// For reasons that I haven't been able to figure out, we need
|
||||
// to gamma correct the data that we read from the textures that
|
||||
// are supplied to OpenGL, otherwise they appear too dark.
|
||||
// AFAICT, I've done what I thought were all of the right things
|
||||
// (but are perhaps only some of the right things) to tell OpenGL/EGL
|
||||
// that everything is already SRGB, so this function should really
|
||||
// just be a call to `texture` and not do the gamma conversion.
|
||||
vec4 sample_texture(sampler2D s, vec2 coords) {
|
||||
vec4 color = texture(s, coords);
|
||||
return to_gamma(color);
|
||||
}
|
@ -1,11 +1,115 @@
|
||||
// This is the Glyph fragment shader.
|
||||
// It is responsible for laying down the glyph graphics on top of the other layers.
|
||||
|
||||
// Note: fragment-common.glsl is automatically prepended!
|
||||
precision highp float;
|
||||
|
||||
in float o_has_color;
|
||||
in vec2 o_tex;
|
||||
in vec3 o_hsv;
|
||||
in vec4 o_fg_color;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform vec3 foreground_text_hsb;
|
||||
uniform sampler2D atlas_nearest_sampler;
|
||||
uniform sampler2D atlas_linear_sampler;
|
||||
|
||||
|
||||
float multiply_one(float src, float dst, float inv_dst_alpha, float inv_src_alpha) {
|
||||
return (src * dst) + (src * (inv_dst_alpha)) + (dst * (inv_src_alpha));
|
||||
}
|
||||
|
||||
// Alpha-regulated multiply to colorize the glyph bitmap.
|
||||
vec4 multiply(vec4 src, vec4 dst) {
|
||||
float inv_src_alpha = 1.0 - src.a;
|
||||
float inv_dst_alpha = 1.0 - dst.a;
|
||||
|
||||
return vec4(
|
||||
multiply_one(src.r, dst.r, inv_dst_alpha, inv_src_alpha),
|
||||
multiply_one(src.g, dst.g, inv_dst_alpha, inv_src_alpha),
|
||||
multiply_one(src.b, dst.b, inv_dst_alpha, inv_src_alpha),
|
||||
dst.a);
|
||||
}
|
||||
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
const vec3 unit3 = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec4 apply_hsv(vec4 c, vec3 transform)
|
||||
{
|
||||
if (transform == unit3) {
|
||||
return c;
|
||||
}
|
||||
vec3 hsv = rgb2hsv(c.rgb) * transform;
|
||||
return vec4(hsv2rgb(hsv).rgb, c.a);
|
||||
}
|
||||
|
||||
// Given glyph, the greyscale rgba value computed by freetype,
|
||||
// and color, the desired color, compute the resultant pixel
|
||||
// value for rendering over the top of the given background
|
||||
// color.
|
||||
//
|
||||
// The freetype glyph is greyscale (R=G=B=A) when font_antialias=Greyscale,
|
||||
// where each channel holds the brightness of the pixel.
|
||||
// It holds separate intensity values for the R, G and B channels when
|
||||
// subpixel anti-aliasing is in use, with an approximated A value
|
||||
// derived from the R, G, B values.
|
||||
//
|
||||
// In sub-pixel mode we don't want to look at glyph.a as we effective
|
||||
// have per-channel alpha. In greyscale mode, glyph.a is the same
|
||||
// as the other channels, so this routine ignores glyph.a when
|
||||
// computing the blend, but does include that value for the returned
|
||||
// alpha value.
|
||||
//
|
||||
// See also: https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-gamma-correct-font-rendering/
|
||||
vec4 colorize(vec4 glyph, vec4 color, vec4 background) {
|
||||
float r = glyph.r * color.r + (1.0 - glyph.r) * background.r;
|
||||
float g = glyph.g * color.g + (1.0 - glyph.g) * background.g;
|
||||
float b = glyph.b * color.b + (1.0 - glyph.b) * background.b;
|
||||
|
||||
return vec4(r, g, b, glyph.a);
|
||||
}
|
||||
|
||||
vec4 colorize2(vec4 glyph, vec4 color) {
|
||||
return vec4(glyph.rgb * color.rgb, glyph.a);
|
||||
}
|
||||
|
||||
vec4 from_linear(vec4 v) {
|
||||
return pow(v, vec4(2.2));
|
||||
}
|
||||
|
||||
vec4 to_gamma(vec4 v) {
|
||||
return pow(v, vec4(1.0/2.2));
|
||||
}
|
||||
|
||||
// For reasons that I haven't been able to figure out, we need
|
||||
// to gamma correct the data that we read from the textures that
|
||||
// are supplied to OpenGL, otherwise they appear too dark.
|
||||
// AFAICT, I've done what I thought were all of the right things
|
||||
// (but are perhaps only some of the right things) to tell OpenGL/EGL
|
||||
// that everything is already SRGB, so this function should really
|
||||
// just be a call to `texture` and not do the gamma conversion.
|
||||
vec4 sample_texture(sampler2D s, vec2 coords) {
|
||||
vec4 color = texture(s, coords);
|
||||
return to_gamma(color);
|
||||
}
|
||||
|
||||
void main() {
|
||||
if (o_has_color == 2.0) {
|
||||
// The window background attachment
|
||||
|
@ -2,11 +2,32 @@
|
||||
// It is responsible for placing the glyph images in the
|
||||
// correct place on screen.
|
||||
|
||||
// Note: vertex-common.glsl is automatically prepended!
|
||||
precision highp float;
|
||||
|
||||
in vec2 position;
|
||||
in vec2 adjust;
|
||||
in vec2 tex;
|
||||
in vec4 fg_color;
|
||||
in float has_color;
|
||||
in vec3 hsv;
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
out float o_has_color;
|
||||
out vec2 o_tex;
|
||||
out vec3 o_hsv;
|
||||
out vec4 o_fg_color;
|
||||
|
||||
void pass_through_vertex() {
|
||||
o_tex = tex;
|
||||
o_has_color = has_color;
|
||||
o_fg_color = fg_color;
|
||||
o_hsv = hsv;
|
||||
}
|
||||
|
||||
void main() {
|
||||
pass_through_vertex();
|
||||
|
||||
// Use only the adjusted cell position to render the glyph
|
||||
// Use the adjusted cell position to render the quad
|
||||
gl_Position = projection * vec4(position + adjust, 0.0, 1.0);
|
||||
}
|
||||
|
@ -188,17 +188,11 @@ impl RenderState {
|
||||
fn glyph_shader(version: &str) -> (String, String) {
|
||||
(
|
||||
format!(
|
||||
"#version {}\n{}\n{}",
|
||||
"#version {}\n{}",
|
||||
version,
|
||||
include_str!("vertex-common.glsl"),
|
||||
include_str!("glyph-vertex.glsl")
|
||||
),
|
||||
format!(
|
||||
"#version {}\n{}\n{}",
|
||||
version,
|
||||
include_str!("fragment-common.glsl"),
|
||||
include_str!("glyph-frag.glsl")
|
||||
),
|
||||
format!("#version {}\n{}", version, include_str!("glyph-frag.glsl")),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
// This file is automatically prepended to the various
|
||||
// vertex.glsl files.
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec2 position;
|
||||
in vec2 adjust;
|
||||
in vec2 tex;
|
||||
in vec4 fg_color;
|
||||
in float has_color;
|
||||
in vec3 hsv;
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
out float o_has_color;
|
||||
out vec2 o_tex;
|
||||
out vec3 o_hsv;
|
||||
out vec4 o_fg_color;
|
||||
|
||||
void pass_through_vertex() {
|
||||
o_tex = tex;
|
||||
o_has_color = has_color;
|
||||
o_fg_color = fg_color;
|
||||
o_hsv = hsv;
|
||||
}
|
||||
|
||||
// Returns a position that is outside of the viewport,
|
||||
// such that this vertex effectively won't contribute
|
||||
// the scene being rendered.
|
||||
// There may be a better way to do this.
|
||||
vec4 off_screen() {
|
||||
return vec4(100.0, 100.0, 100.0, 100.0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user