git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

scenefx/render/fx_renderer/shaders/tex.frag (3.4K)

  1 #define SOURCE %d
  2 #define EFFECTS %d
  3 
  4 #define SOURCE_TEXTURE_RGBA 1
  5 #define SOURCE_TEXTURE_RGBX 2
  6 #define SOURCE_TEXTURE_EXTERNAL 3
  7 
  8 #if !defined(SOURCE) || !defined(EFFECTS)
  9 #error "Missing shader preamble"
 10 #endif
 11 
 12 #if SOURCE == SOURCE_TEXTURE_EXTERNAL
 13 #extension GL_OES_EGL_image_external : require
 14 #endif
 15 
 16 #ifdef GL_FRAGMENT_PRECISION_HIGH
 17 precision highp float;
 18 #else
 19 precision mediump float;
 20 #endif
 21 
 22 varying vec2 v_texcoord;
 23 
 24 #if SOURCE == SOURCE_TEXTURE_EXTERNAL
 25 uniform samplerExternalOES tex;
 26 #elif SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_RGBX
 27 uniform sampler2D tex;
 28 #endif
 29 
 30 uniform float alpha;
 31 
 32 #if EFFECTS
 33 uniform vec2 size;
 34 uniform vec2 position;
 35 uniform float radius_top_left;
 36 uniform float radius_top_right;
 37 uniform float radius_bottom_left;
 38 uniform float radius_bottom_right;
 39 
 40 uniform vec2 clip_size;
 41 uniform vec2 clip_position;
 42 uniform float clip_radius_top_left;
 43 uniform float clip_radius_top_right;
 44 uniform float clip_radius_bottom_left;
 45 uniform float clip_radius_bottom_right;
 46 #endif
 47 
 48 uniform bool discard_transparent;
 49 
 50 // Backdrop compression (see compress_backdrop below). Ceiling and knee are
 51 // linear luminances; a ceiling of 0 turns it off, which is every texture
 52 // draw but a status segment's blurred backdrop.
 53 uniform float compress_ceil;
 54 uniform float compress_knee;
 55 uniform bool compress_invert;
 56 
 57 vec4 sample_texture() {
 58 #if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
 59 	return texture2D(tex, v_texcoord);
 60 #elif SOURCE == SOURCE_TEXTURE_RGBX
 61 	return vec4(texture2D(tex, v_texcoord).rgb, 1.0);
 62 #endif
 63 }
 64 
 65 // Pull the backdrop's luminance under a ceiling, so text of a known color
 66 // keeps its contrast over every pixel of it. Below the knee nothing moves;
 67 // above it the luminance approaches the ceiling asymptotically (slope 1 at
 68 // the knee, so there is no visible seam), and the color is scaled rather
 69 // than desaturated, so a bright backdrop keeps its hue and only loses
 70 // brightness. Dark text compresses the INVERTED image, which lifts the
 71 // shadows toward white instead. Keep in step with droplet.frag.
 72 vec3 compress_backdrop(vec3 c) {
 73 	vec3 lin = pow(max(c, vec3(0.0)), vec3(2.2));
 74 	if (compress_invert) {
 75 		lin = vec3(1.0) - lin;
 76 	}
 77 	float y = dot(lin, vec3(0.2126, 0.7152, 0.0722));
 78 	if (y > compress_knee) {
 79 		float span = max(compress_ceil - compress_knee, 1e-4);
 80 		float y2 = compress_knee + span * (1.0 - exp(-(y - compress_knee) / span));
 81 		lin *= y2 / y;
 82 	}
 83 	if (compress_invert) {
 84 		lin = vec3(1.0) - lin;
 85 	}
 86 	return pow(clamp(lin, 0.0, 1.0), vec3(1.0 / 2.2));
 87 }
 88 
 89 vec4 sample_compressed() {
 90 	vec4 c = sample_texture();
 91 	if (compress_ceil > 0.0 && c.a > 0.0) {
 92 		c.rgb = compress_backdrop(c.rgb / c.a) * c.a;
 93 	}
 94 	return c;
 95 }
 96 
 97 #if EFFECTS
 98 float corner_alpha(vec2 size, vec2 position, bool is_cutout,
 99 		float radius_tl, float radius_tr, float radius_bl, float radius_br);
100 #endif
101 
102 void main() {
103 #if EFFECTS
104 	float quad_corner_alpha = corner_alpha(
105 		size - 0.5,
106 		position + 0.25,
107 		false,
108 		radius_top_left,
109 		radius_top_right,
110 		radius_bottom_left,
111 		radius_bottom_right
112 	);
113 
114 	// Clipping
115 	float clip_corner_alpha = corner_alpha(
116 		clip_size - 1.0,
117 		clip_position + 0.5,
118 		true,
119 		clip_radius_top_left,
120 		clip_radius_top_right,
121 		clip_radius_bottom_left,
122 		clip_radius_bottom_right
123 	);
124 
125 	gl_FragColor = sample_compressed() * alpha * quad_corner_alpha * clip_corner_alpha;
126 #else
127 	gl_FragColor = sample_compressed() * alpha;
128 #endif
129 
130 	if (discard_transparent && gl_FragColor.a == 0.0) {
131 		discard;
132 	}
133 }