summaryrefslogtreecommitdiff
path: root/config/picom/shaders/OldCRT.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'config/picom/shaders/OldCRT.glsl')
-rw-r--r--config/picom/shaders/OldCRT.glsl190
1 files changed, 190 insertions, 0 deletions
diff --git a/config/picom/shaders/OldCRT.glsl b/config/picom/shaders/OldCRT.glsl
new file mode 100644
index 0000000..6e02812
--- /dev/null
+++ b/config/picom/shaders/OldCRT.glsl
@@ -0,0 +1,190 @@
+#version 430
+#define PI 3.1415926538
+uniform float opacity;
+uniform float time;
+
+// Works best with fullscreen windows
+// Made this to play retro games the way god intended
+
+uniform float sc_freq = 0.2; // Frequency for the scanlines
+
+uniform float sc_intensity = 0.6; // Intensity of the scanline effect
+
+uniform bool grid = false; // Whether to also apply scanlines to x axis or not
+
+uniform int distortion_offset = 2; // Pixel offset for red/blue distortion
+
+uniform int downscale_factor = 2; // How many pixels of the window
+ // make an actual "pixel" (or block)
+
+uniform float sph_distance = 500; // Distance from the theoretical sphere
+ // we use for our curvature transform
+
+uniform float curvature = 1.5; // How much the window should "curve"
+
+uniform float shadow_cutoff = 1; // How "early" the shadow starts affecting
+ // pixels close to the edges
+ // I'd keep this value very close to 1
+
+uniform int shadow_intensity = 1; // Intensity level of the shadow effect (from 1 to 5)
+
+vec4 outside_color = vec4(0 ,0 ,0, opacity); // Color for the outside of the window
+
+float flash_speed = 0; // Speed of flashing effect, set to 0 to deactivate
+
+float flash_intensity = 0.8; // Intensity of flashing effect
+
+
+// You can play with different values for all the variables above
+
+in vec2 texcoord; // texture coordinate of the fragment
+
+uniform sampler2D tex; // texture of the window
+
+ivec2 window_size = textureSize(tex, 0);
+ivec2 window_center = ivec2(window_size.x/2, window_size.y/2);
+float radius = (window_size.x/curvature);
+int flash = int(round(flash_speed*time/(10000/window_size.y))) % window_size.y;
+
+// Default window post-processing:
+// 1) invert color
+// 2) opacity / transparency
+// 3) max-brightness clamping
+// 4) rounded corners
+vec4 default_post_processing(vec4 c);
+
+// Darkens a pixels near the edges
+vec4 darken_color(vec4 color, vec2 coords)
+{
+ // If shadow intensity is 0, change nothing
+ if (shadow_intensity == 0)
+ {
+ return color;
+ }
+
+ // Get how far the coords are from the center
+ vec2 distances_from_center = abs(window_center - coords);
+
+ // Darken pixels close to the edges of the screen in a polynomial fashion
+ float brightness = 1;
+ brightness *= -pow((distances_from_center.y/window_center.y)*shadow_cutoff,
+ (5/shadow_intensity)*2)+1;
+ brightness *= -pow((distances_from_center.x/window_center.x)*shadow_cutoff,
+ (5/shadow_intensity)*2)+1;
+ color.xyz *= brightness;
+
+ return color;
+}
+
+// Applies a transformation to our window pixels to simulate
+// a curved screen
+ivec2 curve_coords_spheric(vec2 coords)
+{
+ // Offset coords
+ coords -= window_center;
+ vec2 curved_coords;
+
+ // For this transform imagine a sphere in a 3d space with the
+ // window as a 2d plane tangent to that sphere
+ // For simplicity, we center the sphere at 0,0,0
+ // The coordinates of the projection share x and y with our window pixel
+ // We find Z using the formula for a sphere
+ vec3 projection_coords3d = vec3(coords.x, coords.y,
+ sqrt(pow(radius+sph_distance,2)-
+ pow(coords.x,2)-
+ pow(coords.y,2)));
+
+ // That vector goes from the center of the sphere to the projection of a pixel
+ // of our window onto the sphere's surface
+ // Let's scale it until it hits our window plane
+ projection_coords3d *= ((radius+sph_distance)/projection_coords3d.z);
+ curved_coords = projection_coords3d.xy;
+
+ // Compensate for starting coords offset
+ curved_coords += window_center;
+
+ return ivec2(curved_coords);
+}
+
+
+// Gets a color for a pixel with all the coordinate and
+// downscale changes
+vec4 get_pixel(vec2 coords)
+{
+ // If pixel is at the edge of the window, return a completely black color
+ if (coords.x >=window_size.x-1 || coords.y >=window_size.y-1 ||
+ coords.x <=0 || coords.y <=0)
+ {
+ return outside_color;
+ }
+ vec4 color = texelFetch(tex, ivec2(coords), 0);
+ return default_post_processing(color);
+}
+
+// Gets the color from a downscaled block
+vec4 get_block_color(vec2 coords)
+{
+ // If downscale is set to 1, just return a pixel
+ if (downscale_factor < 2)
+ {
+ return get_pixel(coords);
+ }
+
+ // Relative position of pixel inside the block
+ ivec2 relative_position;
+ relative_position.xy = ivec2(coords).xy % downscale_factor;
+
+ // Average all colors from pixels inside the block
+ vec4 average = vec4(0, 0 , 0, 0);
+ for (int i = 0; i < downscale_factor; i++)
+ {
+ for (int j = 0; j < downscale_factor; j++)
+ {
+ average.xyzw += get_pixel(vec2(coords.x + i - relative_position.x,
+ coords.y + j - relative_position.y));
+ }
+ }
+ average /= pow(downscale_factor, 2);
+
+ return average;
+}
+
+
+// Main shader function
+vec4 window_shader() {
+
+ // Apply curvature transform to coords
+ vec2 curved_coords = curve_coords_spheric(texcoord);
+
+ // Fetch the color
+ vec4 c = get_block_color(curved_coords);
+
+ // Fetch colors from close pixels to apply color distortion
+ vec4 c_right = get_block_color(vec2(curved_coords.x+2, curved_coords.y));
+ vec4 c_left = get_block_color(vec2(curved_coords.x-2, curved_coords.y));
+
+ // Mix red and blue colors
+ c = vec4(c_left.x, c.y, c_right.z, c.w);
+
+ // Apply scanlines
+ c.xyz *= sin(2*PI*sc_freq*(texcoord).y)/(2/sc_intensity) +
+ 1 - sc_intensity/2;
+
+ // Also apply scanlines to x axis if grid is enabled
+ if (grid == true)
+ {
+ c.xyz *= sin(2*PI*sc_freq*(texcoord).x)/(2/sc_intensity) +
+ 1 - sc_intensity/2;
+ }
+
+ // Apply flash
+ if (curved_coords.y >=flash-(window_size.y/10) && curved_coords.y <=flash)
+ {
+ c.xyz *= flash_intensity*(pow(((flash-curved_coords.y)/(window_size.y/10))-1,2)
+ + 1/flash_intensity);
+ }
+
+ // Darken pixel
+ c = darken_color(c, curved_coords);
+ return (c);
+}