Skip to content

[RFC] Custom shaders for fun and profit! #10344

Description

@kovidgoyal

What is it?

Custom shaders let you attach GPU post-processing effects to your kitty terminal. They run after kitty finishes drawing everything else, so they can transform the final image any way you like — animated backgrounds, mouse effects, cursor trails, retro screen filters, window-focus highlights, you name it.

# kitty.conf
custom_shaders northern-lights

That's it. One line and your terminal is glowing with the Aurora Borealis. Several shaders ship with kitty out of the box; you can also write your own.

Custom shaders are zero overhead unless loaded. When they are enabled kitty takes a more resource intensive rendering path, rendering in layers, so you do pay a small resource cost for using them. Complexity of the actual custom shaders used also matters, of course. But even the most demanding of them, such as northern-lights only consumes ~ 3-5% of CPU and automatically turns off when the window is idle.


Demo videos

Animated backgrounds

Shader
inside-the-matrixSee the bones of reality. ▶ watch
northern-lightsThe ethereal Aurora Borealis. ▶ watch
fireworksCelebrate the sheer awesomeness of your terminal. ▶ watch
waterPretend you are cool enough to code underwater. ▶ watch

Cursor trails

Shader
cursor-trail-blazeSet your cursor on fire as it moves around. ▶ watch
cursor-trail-lightningMake your cursor shoot lightning as it moves around. ▶ watch

Mouse effects

Shader
pond-rippleClicking is like throwing stones in a pond. ▶ watch
spotlightSpotlight your mouse pointer as it moves around. ▶ watch

Navigation

Shader
dim-inactive-windowsMake the active window stand out more. ▶ watch
tab-changeHighlight the active window on focus change. ▶ watch
focus-highlightBriefly highlight the active window on focus change. ▶ watch

Retro terminals

Shader
crtYour terminal deserves to have curves. ▶ watch
crt-blueDo you have the blues? ▶ watch
tftYou are too modern for CRT. ▶ watch

Standout features

Animation events

Shaders don't just run blindly on every frame — they respond to events. You tell a shader when to wake up and when to rest:

# in a .pipeline file
startgroup
    animation_start pointer-left-button-press
    animation_stop  1500
    animation_curve ease-out
    shaders pond-ripple
endgroup

Available events include pointer-left-button-press, os-window-focus-in/out, window-focus-in/out, tab-change, bell-in-window, user-activity, user-idle, and cursor-trail-move/stop. Combine multiple events with |. Shaders that aren't animating cost nothing — kitty skips them entirely.

Named textures

Pipelines get three named off-screen buffers for multi-pass effects: a and b for scratch work within a frame, and persist for state that survives between frames (trails, simulations, accumulation effects).

# .pipeline file — glow effect example
textures a

startgroup
    shaders bloom-prepass
    output_texture a        # render glow mask into texture a
endgroup

startgroup
    shaders bloom-composite # read t.backbuffer + t.a to composite
endgroup

Composing and tuning shaders

Stack multiple shaders in a single pipeline and tweak their parameters without touching the shader source — just set var overrides in the pipeline file:

startgroup
    var float4 TINT = float4(0, 0.8, 0.6, 1)
    shaders crt
endgroup

startgroup
    animation_start os-window-focus-in | user-activity
    animation_stop  os-window-focus-out | user-idle
    shaders spotlight
endgroup

CRT with a teal tint, plus a spotlight that follows your mouse while you're active. Two shaders, one pipeline, zero fuss.


Quick start

Install kitty nightly or build from master.

Run:

kitty -o 'custom_shaders northern-lights cursor-trail-blaze' -o 'cursor_trail 1'

Or put them in kitty.conf

# Animated background — pick one you like
custom_shaders northern-lights cursor-trail-blaze
# Cursor trails need this enabled too
cursor_trail 1

# Or stack a retro filter with an animated background:
# (create ~/.config/kitty/shaders/my-setup.pipeline)
# custom_shaders my-setup

Shaders are searched first in ~/.config/kitty/shaders/, then among the shaders bundled with kitty, so dropping your own .slang or .pipeline file there is all you need to get started.


Writing your own

Shaders are written in Slang, a modern shading language that compiles to whatever the platform needs (Metal, Vulkan, OpenGL). The entry point is a single function:

public float4
fragment_main(float4 color, KittyTextures t, KittyCustomShaderData d) {
    // color is the pixel from the previous pass (or the terminal frame)
    // d holds time, mouse position, window geometry, animation_progress, …
    return color;  // passthrough — not very exciting, but it works
}

static const variables at the top of a shader become tunable parameters that pipeline files can override with var directives — no recompilation needed.


Full documentation

The complete reference — all pipeline directives, the full event list, named textures, shader anatomy, and more — lives here:

docs/custom-shaders.rst


Feedback

Feel free to comment if you find something missing or broken or have ideas for further improvements.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions