Skip to content

sahaj-b/ghostty-cursor-shaders

Repository files navigation

Cursor shaders for ghostty

WARNING: These are extremely customizable

Demos

Effect Demo
Cursor Warp
(Neovide-like)
cursor_warp
Cursor Sweep cursor_sweep
Cursor Tail
(Kitty-like)
cursor_tail
Ripple Cursor ripple_cursor
Sonic Boom sonic_boom
Ripple Rectangle ripple_rectangle
Customized
(faded warp + ripple)
customized_warp

Trails

Pulse/Boom effects

Note

If you have the line cursor (default), these effects will trigger and freeze on unfocus(as cursor changes to hollow block). The solution is to add custom-shader-animation = always to your ghostty config

Usage

  1. Clone the repo into your ghostty shaders directory:
git clone https://github.com/sahaj-b/ghostty-cursor-shaders ~/.config/ghostty/shaders
  1. In your ~/.config/ghostty/config, add:
custom-shader = shaders/yourshader1.glsl
custom-shader = shaders/yourshader2.glsl
# ...

Replace yourshader with the name of any shader file (e.g., cursor_sweep, ripple_cursor, etc.)

Customization

  • All shaders has customizable parameters (like color, duration, size, thickness, etc) etc at the top of each file. You can adjust
  • Also, all files has various Easing Functions to choose from.
    • these function control the animation curve of the effects, you can make them elasitcy, springy, smooth, linear, etc by changing the easing function
    • in trail shaders, you can comment/uncomment the easing functions in the code
    • in pulse/boom shaders, you can comment/uncomment the lines in the ANIMATION section
    • you can also add your own easing functions if you want

Example (faded warp + ripple)

// in cursor_warp.glsl
const float DURATION = 0.15;
const float TRAIL_SIZE = 0.8;
const float THRESHOLD_MIN_DISTANCE = 1.0;
const float BLUR = 1.0;
const float TRAIL_THICKNESS = 1.0;
const float TRAIL_THICKNESS_X = 0.9;

const float FADE_ENABLED = 1.0;
const float FADE_EXPONENT = 5.0;
// in ripple_cursor.glsl
const float DURATION = 0.15;
const float MAX_RADIUS = 0.026;
const float RING_THICKNESS = 0.02;
const float CURSOR_WIDTH_CHANGE_THRESHOLD = 0.5;
vec4 COLOR = vec4(0.35, 0.36, 0.44, 0.8);
const float BLUR = 3.5;
const float ANIMATION_START_OFFSET = 0.01;

Acknowledgements

Inspired by Neovide cursor animations and KroneCorylus/ghostty-shader-playground

License

MIT

Why use branching(if/else) instead of branchless math

  • coz we are dealing with uniform branching here, which has NO DIVERGENCE.
  • ie, all fragments will take the same branch path, so no performance penalty on modern GPUs
  • Branchless math would force GPU to calculate animations every single frame, even when there is no need

About

My custom cursor shaders for ghostty (trails and ripple/pulse effects)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages