first commit

This commit is contained in:
2025-06-14 20:26:14 +02:00
commit 1edfd60dbd
351 changed files with 34592 additions and 0 deletions

64
.clang-format Executable file
View File

@@ -0,0 +1,64 @@
BasedOnStyle: Google
AccessModifierOffset: -2
AlignConsecutiveAssignments: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
BreakAfterReturnType: Automatic
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
EmptyLineBeforeAccessModifier: LogicalBlock
FixNamespaceComments: true
IncludeBlocks: Regroup
SortIncludes: true
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentWidth: 4
KeepEmptyLines:
AtEndOfFile: true
AtStartOfBlock: true
AtStartOfFile: false
MaxEmptyLinesToKeep: 1
TabWidth: 4
UseTab: Never
SeparateDefinitionBlocks: Always
QualifierAlignment: Left

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
sync_cachy.sh

14
.memo/fish-keybindings Normal file
View File

@@ -0,0 +1,14 @@
C a 移动行首
C e 移动行末
C f 字符前移
C b 字符后移
A f 单词前移
A b 单词后移
C u 从光标位置到行首删除
C k 从光标位置到行末删除
A c 大小写切换
A s sudo

17
.memo/git-msg Normal file
View File

@@ -0,0 +1,17 @@
✨ feat: ✨ 新功能
🐛 fix: 🐛 修复 bug
📝 docs: 📝 文档更新
🎨 style: 🎨 代码格式(不影响功能)
♻️ refactor: ♻️ 代码重构
🚀 perf: 🚀 性能优化
✅ test: ✅ 添加测试
🔧 chore: 🔧 杂务(构建过程或辅助工具的变动)
🔒 security: 🔒 安全性改进
⬆️ upgrade: ⬆️ 升级依赖
⬇️ downgrade: ⬇️ 降级依赖
🚨 lint: 🚨 修复 linter 警告
💄 ui: 💄 更新 UI 和样式文件
🚧 wip: 🚧 工作进行中
🔥 remove: 🔥 删除代码或文件
🔀 merge: 🔀 合并分支
🔖 release: 🔖 发布/版本标签

40
.memo/hyprland-ricing Normal file
View File

@@ -0,0 +1,40 @@
安装的东西:
hyprland
hyprpaper
hypridle
hyprlock
hyprshot
hyprland-plugin-hyprexpo # 类似监控室老大爷视角 :/
xdg-desktop-portal-hyprland
xdg-desktop-portal-gnome
xdg-desktop-portal-gtk
mako # notification daemon
gnome-keyring
wl-clipboard
network-manager-applet # nm-applet
slurp # region selector
wf-recorder # screen recorder
brightnessctl
waybar
wlogout
fuzzel
hyprpicker
cliphist
blueman # bluetooth GUI & applet
pavucontrol
easyeffects
nautilus # dolphin doesn't look nice in Hyprland
gnome-text-editor # neither does kwrite, even with Kvantum
btop # system monitor
ttf-font-awesome
nwg-look # theme of GTK apps
catppuccin-gtk-theme-mocha # theme of GTK apps
polkit-gnome
kitty # normal terminal
ghostty # floating terminal, for btop for example

View File

@@ -0,0 +1,3 @@
__NV_PRIME_RENDER_OFFLOAD=1
__GLX_VENDOR_LIBRARY_NAME=nvidia
__VK_LAYER_NV_optimus=NVIDIA_only

32
.memo/shell.md Normal file
View File

@@ -0,0 +1,32 @@
## 登陆 shell
登陆 shell 是指用户通过终端登录系统时启动的 shell通常是用户登录时执行的第一个 shell可以通过`grep "^$(whoami):" /etc/passwd`查看。
登陆 shell 为 bash 时,在登陆时会检索
- `/etc/profile`
并加载,并会加载以下第一个存在的用户配置文件:
- `~/.bash_profile`
- `~/.bash_login`
- `~/.profile`
所有全局环境变量以及其他非交互配置(如 ssh-agent都可以写进这些文件。
## 非登陆 shell
非登陆 shell 是指用户在已经登录的情况下启动的 shell通常是通过终端仿真器或其他方式打开的 shell。
非登陆 shell 为 bash 时,会先加载`/etc/bash.bashrc`,然后加载用户的`~/.bashrc`文件。
对于非登陆 shell 为 fish 的情况,则会先加载`/etc/fish/conf.d`以及`/etc/fish/config.fish`
然后加载用户的`~/.config/fish/conf.d`以及`~/.config/fish/config.fish`
非登陆 shell 会继承登陆 shell 的环境变量,但不会加载登陆 shell 的配置文件。
## 当前做法
桌面端将登陆 shell 设置为 bash对于终端模拟器显式指定 shell 为 fish并禁用 conf.d 目录下的配置文件。
服务器端同样将登陆 shell 设置为 bash并在.bashrc 中启动 fish同样不使用 conf.d 目录下的配置文件。

52
.memo/swapfile-btrfs.md Normal file
View File

@@ -0,0 +1,52 @@
在 btrfs 分区下使用 swapfile 创建虚拟内存:
1. 创建 swap 子卷 (假定已经挂载到 /mnt)
```bash
btrfs subvolume create /mnt/@swap
```
2. 创建 swap 文件:
```bash
touch /mnt/@swap/swapfile
```
3. 设置 COW 禁用属性:
```bash
chattr +C /mnt/@swap/swapfile
```
4. 设置 swap 文件大小(例如 16GB
```bash
dd if=/dev/zero of=/mnt/@swap/swapfile bs=1M count=16384 oflag=direct
# 可检查属性,确保有 C
lsattr /mnt/@swap/swapfile
```
5. 设置 swap 文件权限:
```bash
chmod 600 /mnt/@swap/swapfile
```
6. 启用 swap 文件:
```bash
mkswap /mnt/@swap/swapfile
swapon /mnt/@swap/swapfile
# 可检查 swap 状态
swapon --show
```
7. 修改 `/etc/fstab` 以自动挂载 swap 文件:
```conf
# Btrfs @swap subvolume
UUID={btrfs-uuid} /swap btrfs subvol=@swap,defaults,noatime 0 0
# Swap file
/swap/swapfile none swap sw 0 0
```

33
.memo/tailscale-nfs Normal file
View File

@@ -0,0 +1,33 @@
1. tailscale
Tailscale 基于 WireGuard 实现 NAT 穿透。
安装:
1) General: curl -fsSL https://tailscale.com/install.sh | sh
2) Archlinux: yay -S tailscale
安装后:
1) systemctl 启动 tailscaled 服务;
2) sudo tailscale up 启动 tailscale
3) sudo tailscale status 查看状态 / 网站 https://login.tailscale.com/admin/machines。
2. nfs
NFS 允许将文件系统挂载到远程主机上。
安装:
1) 服务端: nfs-utils (Archlinux)
2) 客户端: nfs-common (ubuntu)
安装后:
1) 服务端:
aecho "/path/to/share *(rw,no_subtree_check,async)" | sudo tee -a /etc/exports
b) systemctl 启动 nfs-server 服务
2) 客户端
a) sudo mount -t nfs -o vers=4,noatime,async 100.x.y.z:/path/to/share /path/to/mount
3. 解除
1) umount即可
2) sudo tailscale down 关闭 tailscale。

26
.scripts/change_wallpaper.fish Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/fish
# if the path is given as an argument, use that
if test (count $argv) -eq 1
set image $argv[1]
else
set image (zenity --file-selection --title="Open File" --file-filter="*.jpg *.jpeg *.png")
end
if test -z "$image"
exit 1
end
if not test -f "$image"
notify-send "Error" "Selected file does not exist."
exit 1
end
if string match -q "* *" "$image"
notify-send "Error" "Selected file path contains white spaces, please select a file without white spaces."
exit 1
end
hyprctl hyprpaper reload ,"$image"
echo "preload = $image" > ~/.config/hypr/hyprpaper.conf
echo "wallpaper = , $image" >> ~/.config/hypr/hyprpaper.conf
notify-send "Wallpaper Changed" "Wallpaper changed to \"$image\" successfully."

1874
.scripts/fuzzel-emoji Executable file
View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# https://github.com/end-4/dots-hyprland/blob/main/.config/ags/scripts/hyprland/workspace_action.sh
hyprctl dispatch "$1" $(((($(hyprctl activeworkspace -j | jq -r .id) - 1) / 10) * 10 + $2))

30
.scripts/record-script.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
# https://github.com/end-4/dots-hyprland/blob/main/.config/ags/scripts/record-script.sh
getdate() {
date '+%Y-%m-%d_%H.%M.%S'
}
getaudiooutput() {
pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2
}
getactivemonitor() {
hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name'
}
mkdir -p "$(xdg-user-dir VIDEOS)"
cd "$(xdg-user-dir VIDEOS)" || exit
if pgrep wf-recorder > /dev/null; then
notify-send "Recording Stopped" "Stopped" -a 'record-script.sh' &
pkill wf-recorder &
else
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'record-script.sh'
if [[ "$1" == "--sound" ]]; then
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)" --audio="$(getaudiooutput)" & disown
elif [[ "$1" == "--fullscreen-sound" ]]; then
wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" & disown
elif [[ "$1" == "--fullscreen" ]]; then
wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t & disown
else
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)" & disown
fi
fi

5
.scripts/set_nv_env.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
export __NV_PRIME_RENDER_OFFLOAD=1
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export __VK_LAYER_NV_optimus=NVIDIA_only

6
.scripts/unset_nv_env.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
# __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia __VK_LAYER_NV_optimus=NVIDIA_only
unset __NV_PRIME_RENDER_OFFLOAD
unset __GLX_VENDOR_LIBRARY_NAME
unset __VK_LAYER_NV_optimus

18
.utils/live_mount.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
device="/dev/nvme0n1"
efi_part="${device}p3"
boot_part="${device}p4"
btrfs_part="${device}p5"
umount /mnt -R
mount $btrfs_part -o subvol=@ /mnt
mount $btrfs_part -o subvol=@home /mnt/home
mount $btrfs_part -o subvol=@log /mnt/var/log
mount $btrfs_part -o subvol=@cache /mnt/var/cache
mount $btrfs_part -o subvol=@tmp /mnt/tmp
mount $btrfs_part -o subvol=@swap /mnt/swap
mount $boot_part /mnt/boot
mount $efi_part /mnt/boot/efi
swapon /mnt/swap/swapfile

16
.utils/truecolor-test.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
# Based on: https://gist.github.com/XVilka/8346728
awk -v term_cols="${width:-$(tput cols || echo 80)}" 'BEGIN{
s="/\\";
for (colnum = 0; colnum<term_cols; colnum++) {
r = 255-(colnum*255/term_cols);
g = (colnum*510/term_cols);
b = (colnum*255/term_cols);
if (g>255) g = 510-g;
printf "\033[48;2;%d;%d;%dm", r,g,b;
printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
printf "%s\033[0m", substr(s,colnum%2+1,1);
}
printf "\n";
}'

167
alacritty/alacritty.toml Normal file
View File

@@ -0,0 +1,167 @@
[env]
TERM = "xterm-256color"
WINIT_X11_SCALE_FACTOR = "1"
[window]
dynamic_padding = true
decorations = "full"
title = "Alacritty@CachyOS"
opacity = 0.75
decorations_theme_variant = "Dark"
blur = true
[window.dimensions]
columns = 100
lines = 30
[window.class]
instance = "Alacritty"
general = "Alacritty"
[scrolling]
history = 10000
multiplier = 3
[colors]
draw_bold_text_with_bright_colors = true
# [colors.primary]
# background = "0x2E3440"
# foreground = "0xD8DEE9"
# [colors.normal]
# black = "0x3B4252"
# red = "0xBF616A"
# green = "0xA3BE8C"
# yellow = "0xEBCB8B"
# blue = "0x81A1C1"
# magenta = "0xB48EAD"
# cyan = "0x88C0D0"
# white = "0xE5E9F0"
# [colors.bright]
# black = "0x4C566A"
# red = "0xBF616A"
# green = "0xA3BE8C"
# yellow = "0xEBCB8B"
# blue = "0x81A1C1"
# magenta = "0xB48EAD"
# cyan = "0x8FBCBB"
# white = "0xECEFF4"
[font]
size = 12
[font.normal]
family = "Meslo LGM Nerd Font"
style = "Regular"
[font.bold]
family = "Meslo LGM Nerd Font"
style = "Bold"
[font.italic]
family = "Meslo LGM Nerd Font"
style = "Italic"
[font.bold_italic]
family = "Meslo LGM Nerd Font"
style = "Bold Italic"
[selection]
semantic_escape_chars = ",│`|:\"' ()[]{}<>\t"
save_to_clipboard = true
[cursor]
style = "Underline"
vi_mode_style = "None"
unfocused_hollow = true
thickness = 0.15
[mouse]
hide_when_typing = true
[[mouse.bindings]]
mouse = "Middle"
action = "PasteSelection"
[keyboard]
[[keyboard.bindings]]
key = "Paste"
action = "Paste"
[[keyboard.bindings]]
key = "Copy"
action = "Copy"
[[keyboard.bindings]]
key = "L"
mods = "Control"
action = "ClearLogNotice"
[[keyboard.bindings]]
key = "L"
mods = "Control"
mode = "~Vi"
chars = "\f"
[[keyboard.bindings]]
key = "PageUp"
mods = "Shift"
mode = "~Alt"
action = "ScrollPageUp"
[[keyboard.bindings]]
key = "PageDown"
mods = "Shift"
mode = "~Alt"
action = "ScrollPageDown"
[[keyboard.bindings]]
key = "Home"
mods = "Shift"
mode = "~Alt"
action = "ScrollToTop"
[[keyboard.bindings]]
key = "End"
mods = "Shift"
mode = "~Alt"
action = "ScrollToBottom"
[[keyboard.bindings]]
key = "V"
mods = "Control|Shift"
action = "Paste"
[[keyboard.bindings]]
key = "C"
mods = "Control|Shift"
action = "Copy"
[[keyboard.bindings]]
key = "F"
mods = "Control|Shift"
action = "SearchForward"
[[keyboard.bindings]]
key = "B"
mods = "Control|Shift"
action = "SearchBackward"
[[keyboard.bindings]]
key = "C"
mods = "Control|Shift"
mode = "Vi"
action = "ClearSelection"
[[keyboard.bindings]]
key = "Key0"
mods = "Control"
action = "ResetFontSize"
[general]
live_config_reload = true
working_directory = "None"
import = ["~/.config/alacritty/catppuccin-mocha.toml"]

View File

@@ -0,0 +1,65 @@
[colors.primary]
background = "#24273a"
foreground = "#cad3f5"
dim_foreground = "#8087a2"
bright_foreground = "#cad3f5"
[colors.cursor]
text = "#24273a"
cursor = "#f4dbd6"
[colors.vi_mode_cursor]
text = "#24273a"
cursor = "#b7bdf8"
[colors.search.matches]
foreground = "#24273a"
background = "#a5adcb"
[colors.search.focused_match]
foreground = "#24273a"
background = "#a6da95"
[colors.footer_bar]
foreground = "#24273a"
background = "#a5adcb"
[colors.hints.start]
foreground = "#24273a"
background = "#eed49f"
[colors.hints.end]
foreground = "#24273a"
background = "#a5adcb"
[colors.selection]
text = "#24273a"
background = "#f4dbd6"
[colors.normal]
black = "#494d64"
red = "#ed8796"
green = "#a6da95"
yellow = "#eed49f"
blue = "#8aadf4"
magenta = "#f5bde6"
cyan = "#8bd5ca"
white = "#b8c0e0"
[colors.bright]
black = "#5b6078"
red = "#ed8796"
green = "#a6da95"
yellow = "#eed49f"
blue = "#8aadf4"
magenta = "#f5bde6"
cyan = "#8bd5ca"
white = "#a5adcb"
[[colors.indexed_colors]]
index = 16
color = "#f5a97f"
[[colors.indexed_colors]]
index = 17
color = "#f4dbd6"

View File

@@ -0,0 +1,65 @@
[colors.primary]
background = "#1e1e2e"
foreground = "#cdd6f4"
dim_foreground = "#7f849c"
bright_foreground = "#cdd6f4"
[colors.cursor]
text = "#1e1e2e"
cursor = "#f5e0dc"
[colors.vi_mode_cursor]
text = "#1e1e2e"
cursor = "#b4befe"
[colors.search.matches]
foreground = "#1e1e2e"
background = "#a6adc8"
[colors.search.focused_match]
foreground = "#1e1e2e"
background = "#a6e3a1"
[colors.footer_bar]
foreground = "#1e1e2e"
background = "#a6adc8"
[colors.hints.start]
foreground = "#1e1e2e"
background = "#f9e2af"
[colors.hints.end]
foreground = "#1e1e2e"
background = "#a6adc8"
[colors.selection]
text = "#1e1e2e"
background = "#f5e0dc"
[colors.normal]
black = "#45475a"
red = "#f38ba8"
green = "#a6e3a1"
yellow = "#f9e2af"
blue = "#89b4fa"
magenta = "#f5c2e7"
cyan = "#94e2d5"
white = "#bac2de"
[colors.bright]
black = "#585b70"
red = "#f38ba8"
green = "#a6e3a1"
yellow = "#f9e2af"
blue = "#89b4fa"
magenta = "#f5c2e7"
cyan = "#94e2d5"
white = "#a6adc8"
[[colors.indexed_colors]]
index = 16
color = "#fab387"
[[colors.indexed_colors]]
index = 17
color = "#f5e0dc"

280
cava/config Normal file
View File

@@ -0,0 +1,280 @@
## Configuration file for CAVA.
# Remove the ; to change parameters.
[general]
# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. DEPRECATED as of 0.6.0
; mode = normal
# Accepts only non-negative values.
; framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
# new as of 0.6.0 autosens of low values (dynamic range)
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0
; autosens = 1
; overshoot = 20
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
# The number of bars (0-512). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
; bars = 0
; bar_width = 2
; bar_spacing = 1
# bar_height is only used for output in "noritake" format
; bar_height = 32
# For SDL width and space between bars is in pixels, defaults are:
; bar_width = 20
; bar_spacing = 5
# sdl_glsl have these default values, they are only used to calculate max number of bars.
; bar_width = 1
; bar_spacing = 0
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff if a too low band is specified.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
; sleep_timer = 0
[input]
# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem'
# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.
# On Mac it defaults to 'portaudio' or 'fifo'
# On windows this is automatic and no input settings are needed.
#
# All input methods uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For pipewire 'source' will be the object name or object.serial of the device to capture from.
# Both input and output devices are supported.
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
#
# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.
# README.md contains further information on how to setup CAVA for sndio.
#
# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.
# README.md contains further information on how to setup CAVA for OSS on FreeBSD.
#
# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.
# README.md contains further information on how to setup CAVA for JACK.
#
; method = pulse
; source = auto
method = pipewire
source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
; method = shmem
; source = /squeezelite-AA:BB:CC:DD:EE:FF
; method = portaudio
; source = auto
; method = sndio
; source = default
; method = oss
; source = /dev/dsp
; method = jack
; source = default
# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods:
# sample_rate: fifo, pipewire, sndio, oss
# sample_bits: fifo, pipewire, sndio, oss
# channels: sndio, oss, jack
# autoconnect: jack
# Other methods ignore these settings.
#
# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported
# by the chosen audio device, the device will use other supported values instead.
# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it
# will use 44100, 16 and 1.
#
; sample_rate = 44100
; sample_bits = 16
; channels = 2
; autoconnect = 2
[output]
# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl'
# or 'sdl_glsl'.
# 'noncurses' (default) uses a buffer and cursor movements to only print
# changes from frame to frame in the terminal. Uses less resources and is less
# prone to tearing (vsync issues) than 'ncurses'.
#
# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
# stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above.
#
# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display
# in graphic mode. It only support the 3000 series graphical VFDs for now.
#
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or
# use one of the predefined ones.
; method = noncurses
# Orientation of the visualization. Can be 'bottom', 'top', 'left', 'right' or
# 'horizontal'. Default is 'bottom'. 'left and 'right' are only supported on sdl
# and ncruses output. 'horizontal' (bars go up and down from center) is only supported
# on noncurses output.
# Note: many fonts have weird or missing glyphs for characters used in orientations
# other than 'bottom', which can make output not look right.
; orientation = bottom
# Visual channels. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' outputs left to right lowest to highest frequencies.
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
# set 'reverse' to 1 to display frequencies the other way around.
channels = mono
mono_option = average
; reverse = 0
# Raw output target. A fifo will be created if target does not exist.
; raw_target = /dev/stdout
# Raw data format. Can be 'binary' or 'ascii'.
; data_format = binary
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
; ascii_max_range = 1000
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
# sdl window size and position. -1,-1 is centered.
; sdl_width = 1000
; sdl_height = 500
; sdl_x = -1
; sdl_y= -1
; sdl_full_screen = 0
# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none'
# 'frequency' displays the lower cut off frequency of the bar above.
# Only supported on ncurses and noncurses output.
; xaxis = none
# enable synchronized sync. 1 = on, 0 = off
# removes flickering in alacritty terminal emulator.
# defaults to off since the behaviour in other terminal emulators is unknown
; synchronized_sync = 0
# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders
; vertex_shader = pass_through.vert
; fragment_shader = bar_spectrum.frag
; for glsl output mode, keep rendering even if no audio
; continuous_rendering = 0
# disable console blank (screen saver) in tty
# (Not supported on FreeBSD)
; disable_blanking = 0
# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off
; show_idle_bar_heads = 1
# show waveform instead of frequency spectrum, 1 = on, 0 = off
; waveform = 0
[color]
# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires
# a terminal that can change color definitions such as Gnome-terminal or rxvt.
# default is to keep current terminal color
; background = default
foreground = '#b4befe'
# SDL and sdl_glsl only support hex code colors, these are the default:
; background = '#111111'
; foreground = '#33ffff'
# Gradient mode, only hex defined colors are supported,
# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
# You can define as many as 8 different colors. They range from bottom to top of screen
; gradient = 0
; gradient_color_1 = '#59cc33'
; gradient_color_2 = '#80cc33'
; gradient_color_3 = '#a6cc33'
; gradient_color_4 = '#cccc33'
; gradient_color_5 = '#cca633'
; gradient_color_6 = '#cc8033'
; gradient_color_7 = '#cc5933'
; gradient_color_8 = '#cc3333'
[smoothing]
# Percentage value for integral smoothing. Takes values from 0 - 100.
# Higher values means smoother, but less precise. 0 to disable.
# DEPRECATED as of 0.8.0, use noise_reduction instead
; integral = 77
# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
; monstercat = 0
; waves = 0
# Set gravity percentage for "drop off". Higher values means bars will drop faster.
# Accepts only non-negative values. 50 means half gravity, 200 means double. Set to 0 to disable "drop off".
# DEPRECATED as of 0.8.0, use noise_reduction instead
; gravity = 100
# In bar height, bars that would have been lower that this will not be drawn.
# DEPRECATED as of 0.8.0
; ignore = 0
# Noise reduction, int 0 - 100. default 77
# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth
# 100 will be very slow and smooth, 0 will be fast but noisy.
; noise_reduction = 77
[eq]
# This one is tricky. You can have as much keys as you want.
# Remember to uncomment more than one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
1 = 2 # bass
2 = 1.5
3 = 1 # midtone
4 = 1
5 = 0.5 # treble

View File

@@ -0,0 +1,79 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space bewteen bars (configurable)
uniform vec3 u_resolution; // window resolution
//colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
{
//create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main()
{
// find which bar to use based on where we are on the x axis
float x = u_resolution.x * fragCoord.x;
int bar = int(bars_count * fragCoord.x);
//calculate a bar size
float bar_size = u_resolution.x / bars_count;
//the y coordinate and bar values are the same
float y = bars[bar];
// make sure there is a thin line at bottom
if (y * u_resolution.y < 1.0)
{
y = 1.0 / u_resolution.y;
}
//draw the bar up to current height
if (y > fragCoord.y)
{
//make some space between bars basen on settings
if (x > (bar + 1) * (bar_size) - bar_spacing)
{
fragColor = vec4(bg_color,1.0);
}
else
{
if (gradient_count == 0)
{
fragColor = vec4(fg_color,1.0);
}
else
{
//find which color in the configured gradient we are at
int color = int((gradient_count - 1) * fragCoord.y);
//find where on y this and next color is supposed to be
float y_min = color / (gradient_count - 1.0);
float y_max = (color + 1.0) / (gradient_count - 1.0);
//make color
fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0);
}
}
}
else
{
fragColor = vec4(bg_color,1.0);
}
}

View File

@@ -0,0 +1,34 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform vec3 u_resolution; // window resolution, not used here
//colors, configurable in cava config file
uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here
uniform vec3 fg_color; // foreground color, not used here
void main()
{
// find which bar to use based on where we are on the x axis
int bar = int(bars_count * fragCoord.x);
float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0;
float y = (bars[bar]) * bar_y;
float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count;
float bar_r = 1.0 - abs((bar_x - 0.5)) * 2;
bar_r = bar_r * bar_r * 2;
// set color
fragColor.r = fg_color.x * y * bar_r;
fragColor.g = fg_color.y * y * bar_r;
fragColor.b = fg_color.z * y * bar_r;
}

View File

@@ -0,0 +1,14 @@
#version 330
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
// Output data ; will be interpolated for each fragment.
out vec2 fragCoord;
void main()
{
gl_Position = vec4(vertexPosition_modelspace,1);
fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
}

View File

@@ -0,0 +1,53 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high
// to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space bewteen bars (configurable)
uniform vec3 u_resolution; // window resolution
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
uniform sampler2D inputTexture; // Texture from the first render pass
vec3 normalize_C(float y, vec3 col_1, vec3 col_2, float y_min, float y_max) {
// create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main() {
// find which bar to use based on where we are on the y axis
int bar = int(bars_count * fragCoord.y);
float y = bars[bar];
float band_size = 1.0 / float(bars_count);
float current_band_min = bar * band_size;
float current_band_max = (bar + 1) * band_size;
int hist_length = 512;
float win_size = 1.0 / hist_length;
if (fragCoord.x > 1.0 - win_size) {
if (fragCoord.y > current_band_min && fragCoord.y < current_band_max) {
fragColor = vec4(fg_color * y, 1.0);
}
} else {
vec2 offsetCoord = fragCoord;
offsetCoord.x += float(win_size);
fragColor = texture(inputTexture, offsetCoord);
}
}

View File

@@ -0,0 +1,112 @@
#version 330
// Emulate the "line style" spectrum analyzer from Winamp 2.
// Try this config for a demonstration:
/*
[general]
bar_width = 2
bar_spacing = 0
higher_cutoff_freq = 22000
[output]
method = sdl_glsl
channels = mono
fragment_shader = winamp_line_style_spectrum.frag
[color]
background = '#000000'
gradient = 1
gradient_color_1 = '#319C08'
gradient_color_2 = '#29CE10'
gradient_color_3 = '#BDDE29'
gradient_color_4 = '#DEA518'
gradient_color_5 = '#D66600'
gradient_color_6 = '#CE2910'
[smoothing]
noise_reduction = 10
*/
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space bewteen bars (configurable)
uniform vec3 u_resolution; // window resolution
//colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
{
//create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main()
{
// find which bar to use based on where we are on the x axis
float x = u_resolution.x * fragCoord.x;
int bar = int(bars_count * fragCoord.x);
//calculate a bar size
float bar_size = u_resolution.x / bars_count;
//the y coordinate is stretched by 4X to resemble Winamp
float y = min(bars[bar] * 4.0, 1.0);
// make sure there is a thin line at bottom
if (y * u_resolution.y < 1.0)
{
y = 1.0 / u_resolution.y;
}
vec4 bar_color;
if (gradient_count == 0)
{
bar_color = vec4(fg_color,1.0);
}
else
{
//find color in the configured gradient for the top of the bar
int color = int((gradient_count - 1) * y);
//find where on y this and next color is supposed to be
float y_min = float(color) / (gradient_count - 1.0);
float y_max = float(color + 1) / (gradient_count - 1.0);
//make a solid color for the entire bar
bar_color = vec4(normalize_C(y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0);
}
//draw the bar up to current height
if (y > fragCoord.y)
{
//make some space between bars based on settings
if (x > (bar + 1) * (bar_size) - bar_spacing)
{
fragColor = vec4(bg_color,1.0);
}
else
{
fragColor = bar_color;
}
}
else
{
fragColor = vec4(bg_color,1.0);
}
}

24
fastfetch/brief.jsonc Normal file
View File

@@ -0,0 +1,24 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"key": {
// "width": 14
}
},
"modules": [
{ "type": "title" },
{ "type": "separator" },
{ "key": " os", "type": "os" },
{ "key": "┠ host", "type": "host" },
{ "key": "┠ cpu", "type": "cpu" },
{ "key": "┠ gpu", "type": "gpu" },
{ "key": "┖ uptime", "type": "uptime" },
{ "type": "break" },
{ "key": " display", "type": "display" },
{ "key": "┠ wm", "type": "wm" },
{ "key": "┠ de", "type": "de" },
{ "key": "┠ shell", "type": "shell" },
{ "key": "┖ terminal", "type": "terminal" },
{ "type": "break" }
]
}

31
fastfetch/config.jsonc Executable file
View File

@@ -0,0 +1,31 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"key": {
// "width": 14
}
},
"modules": [
{ "type": "title" },
{ "type": "separator" },
{ "key": " os", "type": "os" },
{ "key": "┠ host", "type": "host" },
{ "key": "┠ kernel", "type": "kernel" },
{ "key": "┠ uptime", "type": "uptime" },
{ "key": "┖ packages", "type": "packages" },
{ "type": "break" },
{ "key": " display", "type": "display" },
{ "key": "┠ de", "type": "de" },
{ "key": "┠ wm", "type": "wm" },
{ "key": "┠ font", "type": "terminalfont" },
{ "key": "┠ shell", "type": "shell" },
{ "key": "┖ terminal", "type": "terminal" },
{ "type": "break" },
{ "key": " cpu", "type": "cpu" },
{ "key": "┠ gpu", "type": "gpu" },
{ "key": "┠ memory", "type": "memory" },
{ "key": "┠ disk", "type": "disk" },
{ "key": "┠ localip", "type": "localip" },
{ "key": "┖ publicip", "type": "publicip" }
]
}

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
[?25l ▂▃▅▆▅▃▃▃▃▃▂▁ 
▆▇┈▁┎┊▁▁▁▁▁▁▁▇▅▃ ▁▁  
▃▄▄▗▎▌┈▝▗╴▇▇▉▆▗▄▂▁┈▇▄  
▁▁╷▁▚▏╶▍▋▏ ▆▏▝▗▊▂▂┊▝▂ 
▇▗▁▋▄▉▄▅▅▉▅▄▄▃▁▊▁▆▂▅▄▃┈▎
┊╴┈▇▘╵▗╹╷ ┊ ▇▇▅▂▍▂▂▁▄ 
╻┊╹▅─┌╹┊╴▄▄┈▁▉▏ ▇╿╷▇┊▍ 
╴┌▏▁╴▂▂╸▇╶┊╵╻▌▃╴│└▏╵▌ 
▝▊▃▄▅▉━▏▁┗┈╷╌▁▁╸╶▏┃▊▝▅▉▖
╴▏▌▇▝▉▇▇▇▆╵▝▖▃▗┻▖▁╸╴▆▇▅▇
╶╴▝▃▃▘▇▁▂▁▘▎╺▆▌▇╏┈▘▝┌▉▅
▝╻▂▂▏╷┌───┊┋▁▅▅┌╴╸╴▝▊╹▉ 
╴┎╸╍▇ ┈┈╶┹╲▁▁┊┊▅▍ 
╼╴╷▄┈ ┈╶▁▂▉╶▖▍ 
▍▗▏ ╷┎━━▂╷╷▃╺━╾╷ ▝▆▂▃▄  
▍▌▎╌╺╴ ┍▉▍▊┃▉▏ ╵┈╵┕╴▅▃▂ 
▝▋▝┈▁┊ ┊▅▅▄▄▆ ▉▎▂╶╸▝
╺┊┙▇╷▇╶╴ ▁╷┈▂▎▅▂▃▄
[?25h

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
[?25l ▂▄▆▆▆▅▆▆▅▄▃▁ 
▄▆▖╼┌┊┊▇┊▆▅▖▃┈▅▖ 
▄┏▘╴▎┫┊╈╴▘┈▇▘▇▄┈▝  
▌▘╵▏╶▃▆▏┈╻┎┊▝┊▋▝┈▝  
┈╻┊▂▄▄▄▏▎▅▋╹╵╹╴╻▌╴▋ 
┖┊╴▂▂▁▇▏▖▖╴▊┊▝▂▌▊▏▊ 
▄▚▗▅▇╹┈╹╴▎▘▅▏▏▍▋▌▏▋ 
▏▋▇╾▄ ▃▇▉▁▇▆▊╴┊▗▘▊▍ 
┊▎ ┈ ┈ ╶▅╴▘▏▎╶╷┊▗  
╽┊▉ ┈ ╴╴┊▅▇┉╻╴┈▘ 
▋╴╴┈ ┈ ┊▗▘╴┈▗╽╴▘ 
▋┊╶▁▂╺┈╴▆▃╷▅┏▘▉▗  
▗▆▆▖▉╴╵▅▅▆┃▉▍┇▗  
[?25h

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,22 @@
[?25l  ▁▃▄▅▅▅▄▃▄▅▄▄▃▁  
▃▆▂▃▄▅▅▅▃▄▄▃▁╾▁┈▇▅▃  
▄▇▄▚▆▄╺▇┈▚ ╶▎▆┊┈▄┓▄▁▋▆▄  
▗▘▅▘┌╴▎▁ ┊┈┊▃▅━┈╴▝▎▝▅▖▏▝▖ 
▏▘▘╶▘▗┳┓▁▃▌▇╴▖╶▆╷▇▇▋▝┓▝┈┈▖  
▊▘╶╴▇╴▗┈╴▇▎╴╴▝━━╶▏▖┗▋▝▖▖▖▆▝ 
┊▁╹▎╷▁▄▄▄▄▎▉▏▆┵▋┍┈╻▄▇╴▚▝▏╴┊▎
▍▉▏▉▘ ┈▇▆▅╿┧╻▆╺╸╹▖╵▏╸▘▋▏▍▏┊▌
▆▊▗▁╼▄▇▆▖ ▋▍▝┈▘╻▄╿╷━╺▆▊▎▌▎▍▍
▗▉▚▘▘▆▇▋▇ ▋┈ ┖╻▏┈▌┨▃▋╼▊▏▚┈▌▏
┲┉╹▉▂━▂▏▅▁▇▄ ▝╺▆▅╽┕▏▏╴▝▝┊╴▊ 
┈╴▏╿╴╻┈▆ ▖▝▗▆▆▋▋▉▏▃╴╸╺▋▘ 
▗┚ ▗▗▇ ┈┈  ╺▃▂▘▘▃▎┈╴┈┊▗  
╶▏ ▌▍ ┊╵▇▇▗▘┊╴╴╶┊▖▉▘ 
╹╸╶┊▝ ┈ ▋▋╴▘┊╵▉┈╵▘▋▘ 
▎▝┐╵╸▁▂ ▁┈▁▂▘┄╴▅╴▚▎▏▁▌ 
▊┊┊╺┒▁▂╷╸▆┌▇╴▝▋╽▆╴┏▊╺▉▗▍ 
╴▃▅▄▂▇▇▎┊╴┊▅▃▄▊▁▃▊▘╶▋▗  
▖▍▉╴╷▖▗┈▆▄▅▁▁╶▘▗▌▏│▊▍   
▝▋▗▌▏┊▖╴┈▃▂▌▁▇╶┕┈▊▌└┊▌   
┉▝▉▌▎▖▋▝╺┊╷╸▇▅▄┊▊▊▊▏╴▖   
[?25h

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

BIN
fastfetch/logo_rm/1024.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
fastfetch/logo_rm/2400.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 MiB

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
[?25l ▗▃▂▂▁▁▁▂▂▃▖▁  
▖▏▆▇▇▇┇╷▗┈▗  
 ▌╶▁▁▂╻▃╴▖╶╾  
 ▆▖▇▇╵▆▆▁╶▃▇▄▂▅▆▅▄▃▂ 
 ▗▆▆┵╺┉▄▖▆▗▂▄▁┻╸╶▘▝▏▌ 
╶▎▁▁▗╸▅┳▁▖▆╶▄▃▏▁▁▁▃╴▉  
▊▝▁▊▝▎╶▉▏▆▚┊▎▅▁▅▚┊━▇  
▋▍▉▄▖╷┊╼┻╸▁▊▃▃┏▂▆╴▘▝▝▃╸
▍▘▁▍▇╵╴┉╴▃▃┛┈▍▇▅▝▃▅─▗▆ 
▖┊▆╴▊▝┈╴▆▁▃▂▅▘▆▄▂▂╴▇▄▘
 ▎▂▁▃▘▝▇▅▇╴▖▗▆╺╶▝▁╷ ▇  
 ▌▎▉▖╴▁▉╴╴┈▗▅▘▂▅▇▅▄━┻ 
▆▅╹╴▇▊▇▃▊▇▗▅▆ 
 ▝▁▝▏▂▃▘▋▍ 
 ▇▇▆ ▇▇  
[?25h

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
[?25l  ▂▁     ▁  
 ▖▗▇▇▆▅▆▆▅▇▇┓▗▅▅▌ 
  ▖╸╴┈╴▂╷┈┒▋▗▘▌▗  
 ▍┈╷─▊▁╌╷└╷┗╺▗╸▂ 
  ▂┈╹▄▏▆╺━╴╸▂▝▂▝▆╻  ▂▁▁  
 ▊ ▖╵▂▁╴╴▁▁▃▏╲▅▄▂▅▄━▇╹╺┊▆━▃  
 ▗▆▖╾▂▄━▃▃▄▏▅▂▂▝▖▆▁╸╼┑▆━╹▅▋ 
  ▘▆╿▖▂▂▁▁▃▘▂▝╾▖▆▇▇▃▆━┊▃┙▝▁▝▖ 
 ▌▗▂▃▖▖▘▃▆▇▄╴▂┑▇▖▇▇▂▃▗▃▃▄▝▇▂▘ 
 ▍▝▃▁▍▋▍╴╸▊▏▝▆▚╌▊▊▅▖▆▄▝╴▄▇  
 ▎▖▆▍▃▗▍╹▁▁▝▃▆▆┈▏▘╴▍▇▅┖┊▚▇▖╻  
▏▏▅▎▉╲╻╺╵▆▆▅╾╷▂▇▇▇▘▅▆▁▃▇▇▃▆▆▚ 
▊┊▘▇▉▗└▂▏▍┓╴╷▂▂▃╹╵▎▚╶▅▆▃▆▅▄▗▅  
 ▝▖▇▗▘▉╴▝╴┊▁━╵▇▗▏┈▂▂▍▄▁╾▉▃▅▝▆▂ 
 ▍▂▁▂▊╹▎▝▂▇▁▂▄▇▅▉▆▁▘▌▗▆▅▄▂━━▅ 
 ▉▃▁╵▁▃┙▆┈▄▆▇╼╴▖▇▃▊╴╾╾▃ ▗▁▁ 
 ▊▎╺▇▌ ▁▗▃┊╸┈ ▋▁▘▌▗▅▅▃━▁▂▇  
 ▊┊╴▁▂┈▇┌─┈┊ ▗▂▃▅┊▂▄  ▇▇  
 ▝▇▖▇▁┊▎▍▗▃▖▘▌▉▆▇ 
 ▝▘▎▇▍▝╴▆▗▏▋▋ 
 ▆▅▃▂▂▁▆▝▂▂▘ 
 
[?25h

BIN
fastfetch/logo_rm/512.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

2
fish/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
fish_variables
fish_plugins

4
fish/conf.d.disabled/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*
!.gitignore
!path.fish
!ssh-agent.fish

View File

@@ -0,0 +1,11 @@
fish_add_path $HOME/.local/bin
fish_add_path $HOME/bin
# cargo
if test -f $HOME/.cargo/env.fish
source $HOME/.cargo/env.fish
end
if test -d $HOME/.scripts
fish_add_path $HOME/.scripts
end

View File

@@ -0,0 +1,8 @@
if test -z "$SSH_AUTH_SOCK"
eval (command ssh-agent -c) >/dev/null 2>&1
for key in $HOME/.ssh/keys/*
if test -f $key
command ssh-add $key >/dev/null 2>&1
end
end
end

31
fish/config.fish Executable file
View File

@@ -0,0 +1,31 @@
if not status is-interactive
return
end
# no greeting
set fish_greeting
# ls alias
alias ls="ls --hyperlink=auto --color=auto"
# nvim
if type -q nvim
set -x EDITOR nvim
set -x VISUAL nvim
end
if test -d $HOME/.config/fish/prev.d
for file in $HOME/.config/fish/prev.d/*.fish
if test -f $file
source $file
end
end
end
if test -d $HOME/.config/fish/post.d
for file in $HOME/.config/fish/post.d/*.fish
if test -f $file
source $file
end
end
end

140
fish/functions/__bass.py Executable file
View File

@@ -0,0 +1,140 @@
"""
To be used with a companion fish function like this:
function refish
set -l _x (python /tmp/bass.py source ~/.nvm/nvim.sh ';' nvm use iojs); source $_x; and rm -f $_x
end
"""
from __future__ import print_function
import json
import os
import signal
import subprocess
import sys
import traceback
BASH = 'bash'
FISH_READONLY = [
'PWD', 'SHLVL', 'history', 'pipestatus', 'status', 'version',
'FISH_VERSION', 'fish_pid', 'hostname', '_', 'fish_private_mode'
]
IGNORED = [
'PS1', 'XPC_SERVICE_NAME'
]
def ignored(name):
if name == 'PWD': # this is read only, but has special handling
return False
# ignore other read only variables
if name in FISH_READONLY:
return True
if name in IGNORED or name.startswith("BASH_FUNC"):
return True
if name.startswith('%'):
return True
return False
def escape(string):
# use json.dumps to reliably escape quotes and backslashes
return json.dumps(string).replace(r'$', r'\$')
def escape_identifier(word):
return escape(word.replace('?', '\\?'))
def comment(string):
return '\n'.join(['# ' + line for line in string.split('\n')])
def gen_script():
# Use the following instead of /usr/bin/env to read environment so we can
# deal with multi-line environment variables (and other odd cases).
env_reader = "%s -c 'import os,json; print(json.dumps({k:v for k,v in os.environ.items()}))'" % (sys.executable)
args = [BASH, '-c', env_reader]
output = subprocess.check_output(args, universal_newlines=True)
old_env = output.strip()
pipe_r, pipe_w = os.pipe()
if sys.version_info >= (3, 4):
os.set_inheritable(pipe_w, True)
command = 'eval $1 && ({}; alias) >&{}'.format(
env_reader,
pipe_w
)
args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])]
p = subprocess.Popen(args, universal_newlines=True, close_fds=False)
os.close(pipe_w)
with os.fdopen(pipe_r) as f:
new_env = f.readline()
alias_str = f.read()
if p.wait() != 0:
raise subprocess.CalledProcessError(
returncode=p.returncode,
cmd=' '.join(sys.argv[1:]),
output=new_env + alias_str
)
new_env = new_env.strip()
old_env = json.loads(old_env)
new_env = json.loads(new_env)
script_lines = []
for k, v in new_env.items():
if ignored(k):
continue
v1 = old_env.get(k)
if not v1:
script_lines.append(comment('adding %s=%s' % (k, v)))
elif v1 != v:
script_lines.append(comment('updating %s=%s -> %s' % (k, v1, v)))
# process special variables
if k == 'PWD':
script_lines.append('cd %s' % escape(v))
continue
else:
continue
if k == 'PATH':
value = ' '.join([escape(directory)
for directory in v.split(':')])
else:
value = escape(v)
script_lines.append('set -g -x %s %s' % (k, value))
for var in set(old_env.keys()) - set(new_env.keys()):
script_lines.append(comment('removing %s' % var))
script_lines.append('set -e %s' % var)
script = '\n'.join(script_lines)
alias_lines = []
for line in alias_str.splitlines():
_, rest = line.split(None, 1)
k, v = rest.split("=", 1)
alias_lines.append("alias " + escape_identifier(k) + "=" + v)
alias = '\n'.join(alias_lines)
return script + '\n' + alias
script_file = os.fdopen(3, 'w')
if not sys.argv[1:]:
print('__bass_usage', file=script_file, end='')
sys.exit(0)
try:
script = gen_script()
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
except Exception:
print('Bass internal error!', file=sys.stderr)
raise # traceback will output to stderr
except KeyboardInterrupt:
signal.signal(signal.SIGINT, signal.SIG_DFL)
os.kill(os.getpid(), signal.SIGINT)
else:
script_file.write(script)

29
fish/functions/bass.fish Executable file
View File

@@ -0,0 +1,29 @@
function bass
set -l bash_args $argv
set -l bass_debug
if test "$bash_args[1]_" = '-d_'
set bass_debug true
set -e bash_args[1]
end
set -l script_file (mktemp)
if command -v python3 >/dev/null 2>&1
command python3 -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
else
command python -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
end
set -l bass_status $status
if test $bass_status -ne 0
return $bass_status
end
if test -n "$bass_debug"
cat $script_file
end
source $script_file
command rm $script_file
end
function __bass_usage
echo "Usage: bass [-d] <bash-command>"
end

34
fish/post.d/fetch.fish Normal file
View File

@@ -0,0 +1,34 @@
if not set -q fetch_logo_type
set -g fetch_logo_type "auto"
end
if test "$fetch_logo_type" = "symbols"
set -g fetch_args "--logo-type raw --logo-width 32 --logo \"$HOME/.config/fastfetch/logo_mugi/32x.symbols\""
set -g fetch_args_brief "--logo-type raw --logo-width 24 --logo \"$HOME/.config/fastfetch/logo_mugi/24x.symbols\""
else if test "$fetch_logo_type" = "logo"
set -g fetch_args "--logo-type builtin"
set -g fetch_args_brief "--logo-type small"
else if test "$fetch_logo_type" = "sixel"
set -g fetch_args "--logo-type raw --logo-width 32 --logo \"$HOME/.config/fastfetch/logo_mugi/32x.sixel\""
set -g fetch_args_brief "--logo-type raw --logo-width 24 --logo \"$HOME/.config/fastfetch/logo_mugi/24x.sixel\""
else # "kitty" or "auto" and others
set -g fetch_args "--logo-type $fetch_logo_type --logo-height 21 --logo \"$HOME/.config/fastfetch/logo_mugi/mugi_3.png\""
set -g fetch_args_brief "--logo-type $fetch_logo_type --logo-height 13 --logo \"$HOME/.config/fastfetch/logo_mugi/mugi_1.png\""
end
if type -q fastfetch
alias ff="fastfetch -c $HOME/.config/fastfetch/config.jsonc $fetch_args"
if test -f "$HOME/.config/fastfetch/brief.jsonc"
alias ff-brief="fastfetch -c $HOME/.config/fastfetch/brief.jsonc $fetch_args_brief"
else
alias ff-brief=ff
end
end
# add 'set -g no_fetch' somewhere other than post.d to disable fetching
if not set -q no_fetch
if type -q ff-brief
ff-brief
end
end

6
fish/prev.d/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*
!.gitignore
!zoxide.fish
!prompt.fish
!ssh-agent.fish
!theme.fish

12
fish/prev.d/prompt.fish Normal file
View File

@@ -0,0 +1,12 @@
function fish_prompt -d "Write out the prompt"
# This shows up as USER@HOST /home/user/ >, with the directory colored
# $USER and $hostname are set by fish, so you can just use them
# instead of using `whoami` and `hostname`
printf '%s@%s %s%s%s > ' $USER $hostname \
(set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
end
# oh-my-posh
if test -f $HOME/.config/posh_theme.omp.json; and type -q oh-my-posh
oh-my-posh init fish --config $HOME/.config/posh_theme.omp.json | source
end

6
fish/prev.d/theme.fish Normal file
View File

@@ -0,0 +1,6 @@
set -l theme 'Catpuccin Mocha'
if not set -q fish_current_theme; or not string match -q "$theme" "$fish_current_theme"
set -U fish_current_theme "$theme"
fish_config theme save "$theme"
end

4
fish/prev.d/zoxide.fish Normal file
View File

@@ -0,0 +1,4 @@
if type -q zoxide
zoxide init fish | source
alias cd=z
end

View File

@@ -0,0 +1,30 @@
# name: 'Catppuccin Frappé'
# url: 'https://github.com/catppuccin/fish'
# preferred_background: 303446
fish_color_normal c6d0f5
fish_color_command 8caaee
fish_color_param eebebe
fish_color_keyword e78284
fish_color_quote a6d189
fish_color_redirection f4b8e4
fish_color_end ef9f76
fish_color_comment 838ba7
fish_color_error e78284
fish_color_gray 737994
fish_color_selection --background=414559
fish_color_search_match --background=414559
fish_color_option a6d189
fish_color_operator f4b8e4
fish_color_escape ea999c
fish_color_autosuggestion 737994
fish_color_cancel e78284
fish_color_cwd e5c890
fish_color_user 81c8be
fish_color_host 8caaee
fish_color_host_remote a6d189
fish_color_status e78284
fish_pager_color_progress 737994
fish_pager_color_prefix f4b8e4
fish_pager_color_completion c6d0f5
fish_pager_color_description 737994

View File

@@ -0,0 +1,30 @@
# name: 'Catppuccin Latte'
# url: 'https://github.com/catppuccin/fish'
# preferred_background: eff1f5
fish_color_normal 4c4f69
fish_color_command 1e66f5
fish_color_param dd7878
fish_color_keyword d20f39
fish_color_quote 40a02b
fish_color_redirection ea76cb
fish_color_end fe640b
fish_color_comment 8c8fa1
fish_color_error d20f39
fish_color_gray 9ca0b0
fish_color_selection --background=ccd0da
fish_color_search_match --background=ccd0da
fish_color_option 40a02b
fish_color_operator ea76cb
fish_color_escape e64553
fish_color_autosuggestion 9ca0b0
fish_color_cancel d20f39
fish_color_cwd df8e1d
fish_color_user 179299
fish_color_host 1e66f5
fish_color_host_remote 40a02b
fish_color_status d20f39
fish_pager_color_progress 9ca0b0
fish_pager_color_prefix ea76cb
fish_pager_color_completion 4c4f69
fish_pager_color_description 9ca0b0

View File

@@ -0,0 +1,30 @@
# name: 'Catppuccin Macchiato'
# url: 'https://github.com/catppuccin/fish'
# preferred_background: 24273a
fish_color_normal cad3f5
fish_color_command 8aadf4
fish_color_param f0c6c6
fish_color_keyword ed8796
fish_color_quote a6da95
fish_color_redirection f5bde6
fish_color_end f5a97f
fish_color_comment 8087a2
fish_color_error ed8796
fish_color_gray 6e738d
fish_color_selection --background=363a4f
fish_color_search_match --background=363a4f
fish_color_option a6da95
fish_color_operator f5bde6
fish_color_escape ee99a0
fish_color_autosuggestion 6e738d
fish_color_cancel ed8796
fish_color_cwd eed49f
fish_color_user 8bd5ca
fish_color_host 8aadf4
fish_color_host_remote a6da95
fish_color_status ed8796
fish_pager_color_progress 6e738d
fish_pager_color_prefix f5bde6
fish_pager_color_completion cad3f5
fish_pager_color_description 6e738d

View File

@@ -0,0 +1,30 @@
# name: 'Catppuccin Mocha'
# url: 'https://github.com/catppuccin/fish'
# preferred_background: 1e1e2e
fish_color_normal cdd6f4
fish_color_command 89b4fa
fish_color_param f2cdcd
fish_color_keyword f38ba8
fish_color_quote a6e3a1
fish_color_redirection f5c2e7
fish_color_end fab387
fish_color_comment 7f849c
fish_color_error f38ba8
fish_color_gray 6c7086
fish_color_selection --background=313244
fish_color_search_match --background=313244
fish_color_option a6e3a1
fish_color_operator f5c2e7
fish_color_escape eba0ac
fish_color_autosuggestion 6c7086
fish_color_cancel f38ba8
fish_color_cwd f9e2af
fish_color_user 94e2d5
fish_color_host 89b4fa
fish_color_host_remote a6e3a1
fish_color_status f38ba8
fish_pager_color_progress 6c7086
fish_pager_color_prefix f5c2e7
fish_pager_color_completion cdd6f4
fish_pager_color_description 6c7086

24
fuzzel/fuzzel.ini Executable file
View File

@@ -0,0 +1,24 @@
terminal=kitty -e
prompt=">> "
layer=overlay
[colors]
background=1e1e2edd
text=cdd6f4ff
prompt=bac2deff
placeholder=7f849cff
input=cdd6f4ff
match=89b4faff
selection=585b70ff
selection-text=cdd6f4ff
selection-match=89b4faff
counter=7f849cff
border=89b4faff
[border]
radius=17
width=2
[dmenu]
exit-immediately-if-empty=yes

19
ghostty/config Normal file
View File

@@ -0,0 +1,19 @@
theme = catppuccin-mocha
background-opacity = 0.75
background-blur = true
window-padding-x = 10
window-padding-y = 10
keybind = ctrl+shift+r=reload_config
command = exec fish
confirm-close-surface = false
font-family = MeloLGM Nerd Font
font-size = 12
# just for fun
# custom-shader = ~/.config/ghostty/shaders/glitchy.glsl

View File

@@ -0,0 +1,40 @@
// credits: https://github.com/unkn0wncode
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord.xy / iResolution.xy;
// Create seamless gradient animation
float speed = 0.2;
float gradientFactor = (uv.x + uv.y) / 2.0;
// Use smoothstep and multiple sin waves for smoother transition
float t = sin(iTime * speed) * 0.5 + 0.5;
gradientFactor = smoothstep(0.0, 1.0, gradientFactor);
// Create smooth circular animation
float angle = iTime * speed;
vec3 color1 = vec3(0.1, 0.1, 0.5);
vec3 color2 = vec3(0.5, 0.1, 0.1);
vec3 color3 = vec3(0.1, 0.5, 0.1);
// Smooth interpolation between colors using multiple mix operations
vec3 gradientStartColor = mix(
mix(color1, color2, smoothstep(0.0, 1.0, sin(angle) * 0.5 + 0.5)),
color3,
smoothstep(0.0, 1.0, sin(angle + 2.0) * 0.5 + 0.5)
);
vec3 gradientEndColor = mix(
mix(color2, color3, smoothstep(0.0, 1.0, sin(angle + 1.0) * 0.5 + 0.5)),
color1,
smoothstep(0.0, 1.0, sin(angle + 3.0) * 0.5 + 0.5)
);
vec3 gradientColor = mix(gradientStartColor, gradientEndColor, gradientFactor);
vec4 terminalColor = texture(iChannel0, uv);
float mask = 1.0 - step(0.5, dot(terminalColor.rgb, vec3(1.0)));
vec3 blendedColor = mix(terminalColor.rgb, gradientColor, mask);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,33 @@
// Original shader collected from: https://www.shadertoy.com/view/WsVSzV
// Licensed under Shadertoy's default since the original creator didn't provide any license. (CC BY NC SA 3.0)
// Slight modifications were made to give a green-ish effect.
// This shader was modified by April Hall (arithefirst)
// Sourced from https://github.com/m-ahdal/ghostty-shaders/blob/main/retro-terminal.glsl
// Changes made:
// - Removed tint
// - Made the boundaries match ghostty's background color
float warp = 0.25; // simulate curvature of CRT monitor
float scan = 0.50; // simulate darkness between scanlines
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// squared distance from center
vec2 uv = fragCoord / iResolution.xy;
vec2 dc = abs(0.5 - uv);
dc *= dc;
// warp the fragment coordinates
uv.x -= 0.5; uv.x *= 1.0 + (dc.y * (0.3 * warp)); uv.x += 0.5;
uv.y -= 0.5; uv.y *= 1.0 + (dc.x * (0.4 * warp)); uv.y += 0.5;
// determine if we are drawing in a scanline
float apply = abs(sin(fragCoord.y) * 0.25 * scan);
// sample the texture
vec3 color = texture(iChannel0, uv).rgb;
// mix the sampled color with the scanline intensity
fragColor = vec4(mix(color, vec3(0.0), apply), 1.0);
}

View File

@@ -0,0 +1,52 @@
// source: https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f
// credits: https://github.com/qwerasd205
// Golden spiral samples, [x, y, weight] weight is inverse of distance.
const vec3[24] samples = {
vec3(0.1693761725038636, 0.9855514761735895, 1),
vec3(-1.333070830962943, 0.4721463328627773, 0.7071067811865475),
vec3(-0.8464394909806497, -1.51113870578065, 0.5773502691896258),
vec3(1.554155680728463, -1.2588090085709776, 0.5),
vec3(1.681364377589461, 1.4741145918052656, 0.4472135954999579),
vec3(-1.2795157692199817, 2.088741103228784, 0.4082482904638631),
vec3(-2.4575847530631187, -0.9799373355024756, 0.3779644730092272),
vec3(0.5874641440200847, -2.7667464429345077, 0.35355339059327373),
vec3(2.997715703369726, 0.11704939884745152, 0.3333333333333333),
vec3(0.41360842451688395, 3.1351121305574803, 0.31622776601683794),
vec3(-3.167149933769243, 0.9844599011770256, 0.30151134457776363),
vec3(-1.5736713846521535, -3.0860263079123245, 0.2886751345948129),
vec3(2.888202648340422, -2.1583061557896213, 0.2773500981126146),
vec3(2.7150778983300325, 2.5745586041105715, 0.2672612419124244),
vec3(-2.1504069972377464, 3.2211410627650165, 0.2581988897471611),
vec3(-3.6548858794907493, -1.6253643308191343, 0.25),
vec3(1.0130775986052671, -3.9967078676335834, 0.24253562503633297),
vec3(4.229723673607257, 0.33081361055181563, 0.23570226039551587),
vec3(0.40107790291173834, 4.340407413572593, 0.22941573387056174),
vec3(-4.319124570236028, 1.159811599693438, 0.22360679774997896),
vec3(-1.9209044802827355, -4.160543952132907, 0.2182178902359924),
vec3(3.8639122286635708, -2.6589814382925123, 0.21320071635561041),
vec3(3.3486228404946234, 3.4331800232609, 0.20851441405707477),
vec3(-2.8769733643574344, 3.9652268864187157, 0.20412414523193154)
};
float lum(vec4 c) {
return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec4 color = texture(iChannel0, uv);
vec2 step = vec2(1.414) / iResolution.xy;
for (int i = 0; i < 24; i++) {
vec3 s = samples[i];
vec4 c = texture(iChannel0, uv + s.xy * step);
float l = lum(c);
if (l > 0.2) {
color += l * s.z * c * 0.2;
}
}
fragColor = color;
}

View File

@@ -0,0 +1,79 @@
// INFO: This shader is a port of https://www.shadertoy.com/view/3sySRK
// INFO: Change these variables to create some variation in the animation
#define BLACK_BLEND_THRESHOLD .4 // This is controls the dim of the screen
#define COLOR_SPEED 0.1 // This controls the speed at which the colors change
#define MOVEMENT_SPEED 0.1 // This controls the speed at which the balls move
float opSmoothUnion( float d1, float d2, float k )
{
float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
return mix( d2, d1, h ) - k*h*(1.0-h);
}
float sdSphere( vec3 p, float s )
{
return length(p)-s;
}
float map(vec3 p)
{
float d = 2.0;
for (int i = 0; i < 16; i++) {
float fi = float(i);
float time = iTime * (fract(fi * 412.531 + 0.513) - 0.5) * 2.0;
d = opSmoothUnion(
sdSphere(p + sin(time*MOVEMENT_SPEED + fi * vec3(52.5126, 64.62744, 632.25)) * vec3(2.0, 2.0, 0.8), mix(0.5, 1.0, fract(fi * 412.531 + 0.5124))),
d,
0.4
);
}
return d;
}
vec3 calcNormal( in vec3 p )
{
const float h = 1e-5; // or some other value
const vec2 k = vec2(1,-1);
return normalize( k.xyy*map( p + k.xyy*h ) +
k.yyx*map( p + k.yyx*h ) +
k.yxy*map( p + k.yxy*h ) +
k.xxx*map( p + k.xxx*h ) );
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
vec3 rayOri = vec3((uv - 0.5) * vec2(iResolution.x/iResolution.y, 1.0) * 6.0, 3.0);
vec3 rayDir = vec3(0.0, 0.0, -1.0);
float depth = 0.0;
vec3 p;
for(int i = 0; i < 64; i++) {
p = rayOri + rayDir * depth;
float dist = map(p);
depth += dist;
if (dist < 1e-6) {
break;
}
}
depth = min(6.0, depth);
vec3 n = calcNormal(p);
float b = max(0.0, dot(n, vec3(0.577)));
vec3 col = (0.5 + 0.5 * cos((b + iTime*COLOR_SPEED * 3.0) + uv.xyx * 2.0 + vec3(0,2,4))) * (0.85 + b * 0.35);
col *= exp( -depth * 0.15 );
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb * 1.0, col.rgb * 0.3, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

310
ghostty/shaders/crt.glsl Normal file
View File

@@ -0,0 +1,310 @@
// source: https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f
// credits: https://github.com/qwerasd205
//==============================================================
//
// [CRTS] PUBLIC DOMAIN CRT-STYLED SCALAR by Timothy Lottes
//
// [+] Adapted with alterations for use in Ghostty by Qwerasd.
// For more information on changes, see comment below license.
//
//==============================================================
//
// LICENSE = UNLICENSE (aka PUBLIC DOMAIN)
//
//--------------------------------------------------------------
// This is free and unencumbered software released into the
// public domain.
//--------------------------------------------------------------
// Anyone is free to copy, modify, publish, use, compile, sell,
// or distribute this software, either in source code form or as
// a compiled binary, for any purpose, commercial or
// non-commercial, and by any means.
//--------------------------------------------------------------
// In jurisdictions that recognize copyright laws, the author or
// authors of this software dedicate any and all copyright
// interest in the software to the public domain. We make this
// dedication for the benefit of the public at large and to the
// detriment of our heirs and successors. We intend this
// dedication to be an overt act of relinquishment in perpetuity
// of all present and future rights to this software under
// copyright law.
//--------------------------------------------------------------
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//--------------------------------------------------------------
// For more information, please refer to
// <http://unlicense.org/>
//==============================================================
// This shader is a modified version of the excellent
// FixingPixelArtFast by Timothy Lottes on Shadertoy.
//
// The original shader can be found at:
// https://www.shadertoy.com/view/MtSfRK
//
// Modifications have been made to reduce the verbosity,
// and many of the comments have been removed / reworded.
// Additionally, the license has been moved to the top of
// the file, and can be read above. I (Qwerasd) choose to
// release the modified version under the same license.
// The appearance of this shader can be altered
// by adjusting the parameters defined below.
// "Scanlines" per real screen pixel.
// e.g. SCALE 0.5 means each scanline is 2 pixels.
// Recommended values:
// o High DPI displays: 0.33333333
// - Low DPI displays: 0.66666666
#define SCALE 0.33333333
// "Tube" warp
#define CRTS_WARP 1
// Darkness of vignette in corners after warping
// 0.0 = completely black
// 1.0 = no vignetting
#define MIN_VIN 0.5
// Try different masks
// #define CRTS_MASK_GRILLE 1
// #define CRTS_MASK_GRILLE_LITE 1
// #define CRTS_MASK_NONE 1
#define CRTS_MASK_SHADOW 1
// Scanline thinness
// 0.50 = fused scanlines
// 0.70 = recommended default
// 1.00 = thinner scanlines (too thin)
#define INPUT_THIN 0.75
// Horizonal scan blur
// -3.0 = pixely
// -2.5 = default
// -2.0 = smooth
// -1.0 = too blurry
#define INPUT_BLUR -2.75
// Shadow mask effect, ranges from,
// 0.25 = large amount of mask (not recommended, too dark)
// 0.50 = recommended default
// 1.00 = no shadow mask
#define INPUT_MASK 0.65
float FromSrgb1(float c) {
return (c <= 0.04045) ? c * (1.0 / 12.92) :
pow(c * (1.0 / 1.055) + (0.055 / 1.055), 2.4);
}
vec3 FromSrgb(vec3 c) {
return vec3(
FromSrgb1(c.r), FromSrgb1(c.g), FromSrgb1(c.b));
}
vec3 CrtsFetch(vec2 uv) {
return FromSrgb(texture(iChannel0, uv.xy).rgb);
}
#define CrtsRcpF1(x) (1.0/(x))
#define CrtsSatF1(x) clamp((x),0.0,1.0)
float CrtsMax3F1(float a, float b, float c) {
return max(a, max(b, c));
}
vec2 CrtsTone(
float thin,
float mask) {
#ifdef CRTS_MASK_NONE
mask = 1.0;
#endif
#ifdef CRTS_MASK_GRILLE_LITE
// Normal R mask is {1.0,mask,mask}
// LITE R mask is {mask,1.0,1.0}
mask = 0.5 + mask * 0.5;
#endif
vec2 ret;
float midOut = 0.18 / ((1.5 - thin) * (0.5 * mask + 0.5));
float pMidIn = 0.18;
ret.x = ((-pMidIn) + midOut) / ((1.0 - pMidIn) * midOut);
ret.y = ((-pMidIn) * midOut + pMidIn) / (midOut * (-pMidIn) + midOut);
return ret;
}
vec3 CrtsMask(vec2 pos, float dark) {
#ifdef CRTS_MASK_GRILLE
vec3 m = vec3(dark, dark, dark);
float x = fract(pos.x * (1.0 / 3.0));
if (x < (1.0 / 3.0)) m.r = 1.0;
else if (x < (2.0 / 3.0)) m.g = 1.0;
else m.b = 1.0;
return m;
#endif
#ifdef CRTS_MASK_GRILLE_LITE
vec3 m = vec3(1.0, 1.0, 1.0);
float x = fract(pos.x * (1.0 / 3.0));
if (x < (1.0 / 3.0)) m.r = dark;
else if (x < (2.0 / 3.0)) m.g = dark;
else m.b = dark;
return m;
#endif
#ifdef CRTS_MASK_NONE
return vec3(1.0, 1.0, 1.0);
#endif
#ifdef CRTS_MASK_SHADOW
pos.x += pos.y * 3.0;
vec3 m = vec3(dark, dark, dark);
float x = fract(pos.x * (1.0 / 6.0));
if (x < (1.0 / 3.0)) m.r = 1.0;
else if (x < (2.0 / 3.0)) m.g = 1.0;
else m.b = 1.0;
return m;
#endif
}
vec3 CrtsFilter(
vec2 ipos,
vec2 inputSizeDivOutputSize,
vec2 halfInputSize,
vec2 rcpInputSize,
vec2 rcpOutputSize,
vec2 twoDivOutputSize,
float inputHeight,
vec2 warp,
float thin,
float blur,
float mask,
vec2 tone
) {
// Optional apply warp
vec2 pos;
#ifdef CRTS_WARP
// Convert to {-1 to 1} range
pos = ipos * twoDivOutputSize - vec2(1.0, 1.0);
// Distort pushes image outside {-1 to 1} range
pos *= vec2(
1.0 + (pos.y * pos.y) * warp.x,
1.0 + (pos.x * pos.x) * warp.y);
// TODO: Vignette needs optimization
float vin = 1.0 - (
(1.0 - CrtsSatF1(pos.x * pos.x)) * (1.0 - CrtsSatF1(pos.y * pos.y)));
vin = CrtsSatF1((-vin) * inputHeight + inputHeight);
// Leave in {0 to inputSize}
pos = pos * halfInputSize + halfInputSize;
#else
pos = ipos * inputSizeDivOutputSize;
#endif
// Snap to center of first scanline
float y0 = floor(pos.y - 0.5) + 0.5;
// Snap to center of one of four pixels
float x0 = floor(pos.x - 1.5) + 0.5;
// Inital UV position
vec2 p = vec2(x0 * rcpInputSize.x, y0 * rcpInputSize.y);
// Fetch 4 nearest texels from 2 nearest scanlines
vec3 colA0 = CrtsFetch(p);
p.x += rcpInputSize.x;
vec3 colA1 = CrtsFetch(p);
p.x += rcpInputSize.x;
vec3 colA2 = CrtsFetch(p);
p.x += rcpInputSize.x;
vec3 colA3 = CrtsFetch(p);
p.y += rcpInputSize.y;
vec3 colB3 = CrtsFetch(p);
p.x -= rcpInputSize.x;
vec3 colB2 = CrtsFetch(p);
p.x -= rcpInputSize.x;
vec3 colB1 = CrtsFetch(p);
p.x -= rcpInputSize.x;
vec3 colB0 = CrtsFetch(p);
// Vertical filter
// Scanline intensity is using sine wave
// Easy filter window and integral used later in exposure
float off = pos.y - y0;
float pi2 = 6.28318530717958;
float hlf = 0.5;
float scanA = cos(min(0.5, off * thin) * pi2) * hlf + hlf;
float scanB = cos(min(0.5, (-off) * thin + thin) * pi2) * hlf + hlf;
// Horizontal kernel is simple gaussian filter
float off0 = pos.x - x0;
float off1 = off0 - 1.0;
float off2 = off0 - 2.0;
float off3 = off0 - 3.0;
float pix0 = exp2(blur * off0 * off0);
float pix1 = exp2(blur * off1 * off1);
float pix2 = exp2(blur * off2 * off2);
float pix3 = exp2(blur * off3 * off3);
float pixT = CrtsRcpF1(pix0 + pix1 + pix2 + pix3);
#ifdef CRTS_WARP
// Get rid of wrong pixels on edge
pixT *= max(MIN_VIN, vin);
#endif
scanA *= pixT;
scanB *= pixT;
// Apply horizontal and vertical filters
vec3 color =
(colA0 * pix0 + colA1 * pix1 + colA2 * pix2 + colA3 * pix3) * scanA +
(colB0 * pix0 + colB1 * pix1 + colB2 * pix2 + colB3 * pix3) * scanB;
// Apply phosphor mask
color *= CrtsMask(ipos, mask);
// Tonal control, start by protecting from /0
float peak = max(1.0 / (256.0 * 65536.0),
CrtsMax3F1(color.r, color.g, color.b));
// Compute the ratios of {R,G,B}
vec3 ratio = color * CrtsRcpF1(peak);
// Apply tonal curve to peak value
peak = peak * CrtsRcpF1(peak * tone.x + tone.y);
// Reconstruct color
return ratio * peak;
}
float ToSrgb1(float c) {
return (c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 0.41666) - 0.055);
}
vec3 ToSrgb(vec3 c) {
return vec3(
ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
float aspect = iResolution.x / iResolution.y;
fragColor.rgb = CrtsFilter(
fragCoord.xy,
vec2(1.0),
iResolution.xy * SCALE * 0.5,
1.0 / (iResolution.xy * SCALE),
1.0 / iResolution.xy,
2.0 / iResolution.xy,
iResolution.y,
vec2(1.0 / (50.0 * aspect), 1.0 / 50.0),
INPUT_THIN,
INPUT_BLUR,
INPUT_MASK,
CrtsTone(INPUT_THIN, INPUT_MASK)
);
// Linear to SRGB for output.
fragColor.rgb = ToSrgb(fragColor.rgb);
}

114
ghostty/shaders/cubes.glsl Normal file
View File

@@ -0,0 +1,114 @@
// credits: https://github.com/rymdlego
const float speed = 0.2;
const float cube_size = 1.0;
const float cube_brightness = 1.0;
const float cube_rotation_speed = 2.8;
const float camera_rotation_speed = 0.1;
mat3 rotationMatrix(vec3 m,float a) {
m = normalize(m);
float c = cos(a),s=sin(a);
return mat3(c+(1.-c)*m.x*m.x,
(1.-c)*m.x*m.y-s*m.z,
(1.-c)*m.x*m.z+s*m.y,
(1.-c)*m.x*m.y+s*m.z,
c+(1.-c)*m.y*m.y,
(1.-c)*m.y*m.z-s*m.x,
(1.-c)*m.x*m.z-s*m.y,
(1.-c)*m.y*m.z+s*m.x,
c+(1.-c)*m.z*m.z);
}
float sphere(vec3 pos, float radius)
{
return length(pos) - radius;
}
float box(vec3 pos, vec3 size)
{
float t = iTime;
pos = pos * 0.9 * rotationMatrix(vec3(sin(t/4.0*speed)*10.,cos(t/4.0*speed)*12.,2.7), t*2.4/4.0*speed*cube_rotation_speed);
return length(max(abs(pos) - size, 0.0));
}
float distfunc(vec3 pos)
{
float t = iTime;
float size = 0.45 + 0.25*abs(16.0*sin(t*speed/4.0));
// float size = 2.3 + 1.8*tan((t-5.4)*6.549);
size = cube_size * 0.16 * clamp(size, 2.0, 4.0);
//pos = pos * rotationMatrix(vec3(0.,-3.,0.7), 3.3 * mod(t/30.0, 4.0));
vec3 q = mod(pos, 5.0) - 2.5;
float obj1 = box(q, vec3(size));
return obj1;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float t = iTime;
vec2 screenPos = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
screenPos.x *= iResolution.x / iResolution.y;
vec3 cameraOrigin = vec3(t*1.0*speed, 0.0, 0.0);
// vec3 cameraOrigin = vec3(t*1.8*speed, 3.0+t*0.02*speed, 0.0);
vec3 cameraTarget = vec3(t*100., 0.0, 0.0);
cameraTarget = vec3(t*20.0,0.0,0.0) * rotationMatrix(vec3(0.0,0.0,1.0), t*speed*camera_rotation_speed);
vec3 upDirection = vec3(0.5, 1.0, 0.6);
vec3 cameraDir = normalize(cameraTarget - cameraOrigin);
vec3 cameraRight = normalize(cross(upDirection, cameraOrigin));
vec3 cameraUp = cross(cameraDir, cameraRight);
vec3 rayDir = normalize(cameraRight * screenPos.x + cameraUp * screenPos.y + cameraDir);
const int MAX_ITER = 64;
const float MAX_DIST = 48.0;
const float EPSILON = 0.001;
float totalDist = 0.0;
vec3 pos = cameraOrigin;
float dist = EPSILON;
for (int i = 0; i < MAX_ITER; i++)
{
if (dist < EPSILON || totalDist > MAX_DIST)
break;
dist = distfunc(pos);
totalDist += dist;
pos += dist*rayDir;
}
vec4 cubes;
if (dist < EPSILON)
{
// Lighting Code
vec2 eps = vec2(0.0, EPSILON);
vec3 normal = normalize(vec3(
distfunc(pos + eps.yxx) - distfunc(pos - eps.yxx),
distfunc(pos + eps.xyx) - distfunc(pos - eps.xyx),
distfunc(pos + eps.xxy) - distfunc(pos - eps.xxy)));
float diffuse = max(0., dot(-rayDir, normal));
float specular = pow(diffuse, 32.0);
vec3 color = vec3(diffuse + specular);
vec3 cubeColor = vec3(abs(screenPos),0.5+0.5*sin(t*2.0))*0.8;
cubeColor = mix(cubeColor.rgb, vec3(0.0,0.0,0.0), 1.0);
color += cubeColor;
cubes = vec4(color, 1.0) * vec4(1.0 - (totalDist/MAX_DIST));
cubes = vec4(cubes.rgb*0.02*cube_brightness, 0.1);
}
else {
cubes = vec4(0.0);
}
vec2 uv = fragCoord/iResolution.xy;
vec4 terminalColor = texture(iChannel0, uv);
vec3 blendedColor = terminalColor.rgb + cubes.rgb;
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,30 @@
// Simple "dithering" effect
// (c) moni-dz (https://github.com/moni-dz)
// CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
// Packed bayer pattern using bit manipulation
const float bayerPattern[4] = float[4](
0x0514, // Encoding 0,8,2,10
0xC4E6, // Encoding 12,4,14,6
0x3B19, // Encoding 3,11,1,9
0xF7D5 // Encoding 15,7,13,5
);
float getBayerFromPacked(int x, int y) {
int idx = (x & 3) + ((y & 3) << 2);
return float((int(bayerPattern[y & 3]) >> ((x & 3) << 2)) & 0xF) * (1.0 / 16.0);
}
#define LEVELS 2.0 // Available color steps per channel
#define INV_LEVELS (1.0 / LEVELS)
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord * (1.0 / iResolution.xy);
vec3 color = texture(iChannel0, uv).rgb;
float threshold = getBayerFromPacked(int(fragCoord.x), int(fragCoord.y));
vec3 dithered = floor(color * LEVELS + threshold) * INV_LEVELS;
fragColor = vec4(dithered, 1.0);
}

View File

@@ -0,0 +1,68 @@
// Drunken stupor effect using fractal Brownian motion and Perlin noise
// (c) moni-dz (https://github.com/moni-dz)
// CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
vec2 hash2(vec2 p) {
uvec2 q = uvec2(floatBitsToUint(p.x), floatBitsToUint(p.y));
q = (q * uvec2(1597334673U, 3812015801U)) ^ (q.yx * uvec2(2798796415U, 1979697793U));
return vec2(q) * (1.0/float(0xffffffffU)) * 2.0 - 1.0;
}
float perlin2d(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f*f*(3.0-2.0*f);
return mix(mix(dot(hash2(i + vec2(0.0,0.0)), f - vec2(0.0,0.0)),
dot(hash2(i + vec2(1.0,0.0)), f - vec2(1.0,0.0)), u.x),
mix(dot(hash2(i + vec2(0.0,1.0)), f - vec2(0.0,1.0)),
dot(hash2(i + vec2(1.0,1.0)), f - vec2(1.0,1.0)), u.x), u.y);
}
#define OCTAVES 10 // How many passes of fractal Brownian motion to perform
#define GAIN 0.5 // How much should each pixel move
#define LACUNARITY 2.0 // How fast should each ripple be per pass
float fbm(vec2 p) {
float sum = 0.0;
float amp = 0.5;
float freq = 1.0;
for(int i = 0; i < OCTAVES; i++) {
sum += amp * perlin2d(p * freq);
freq *= LACUNARITY;
amp *= GAIN;
}
return sum;
}
#define NOISE_SCALE 1.0 // How distorted the image you want to be
#define NOISE_INTENSITY 0.05 // How strong the noise effect is
#define ABERRATION true // Chromatic aberration
#define ABERRATION_DELTA 0.1 // How strong the chromatic aberration effect is
#define ANIMATE true
#define SPEED 0.4 // Animation speed
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord/iResolution.xy;
float time = ANIMATE ? iTime * SPEED : 0.0;
vec2 noisePos = uv * NOISE_SCALE + vec2(time);
float noise = fbm(noisePos) * NOISE_INTENSITY;
vec3 col;
if (ABERRATION) {
col.r = texture(iChannel0, uv + vec2(noise * (1.0 + ABERRATION_DELTA))).r;
col.g = texture(iChannel0, uv + vec2(noise)).g;
col.b = texture(iChannel0, uv + vec2(noise * (1.0 - ABERRATION_DELTA))).b;
} else {
vec2 distortedUV = uv + vec2(noise);
col = texture(iChannel0, distortedUV).rgb;
}
fragColor = vec4(col, 1.0);
}

View File

@@ -0,0 +1,109 @@
// This Ghostty shader is a lightly modified port of https://www.shadertoy.com/view/4dBGRw
#define BLACK_BLEND_THRESHOLD .4
//Creates a diagonal red-and-white striped pattern.
vec3 barberpole(vec2 pos, vec2 rocketpos) {
float d = (pos.x - rocketpos.x) + (pos.y - rocketpos.y);
vec3 col = vec3(1.0);
d = mod(d * 20., 2.0);
if (d > 1.0) {
col = vec3(1.0, 0.0, 0.0);
}
return col;
}
vec3 rocket(vec2 pos, vec2 rocketpos) {
vec3 col = vec3(0.0);
float f = 0.;
float absx = abs(rocketpos.x - pos.x);
float absy = abs(rocketpos.y - pos.y);
// Wooden stick
if (absx < 0.01 && absy < 0.22) {
col = vec3(1.0, 0.5, 0.5);
}
// Barberpole
if (absx < 0.05 && absy < 0.15) {
col = barberpole(pos, rocketpos);
}
// Rocket Point
float pointw = (rocketpos.y - pos.y - 0.25) * -0.7;
if ((rocketpos.y - pos.y) > 0.1) {
f = smoothstep(pointw - 0.001, pointw + 0.001, absx);
col = mix(vec3(1.0, 0.0, 0.0), col, f);
}
// Shadow
f = -.5 + smoothstep(-0.05, 0.05, (rocketpos.x - pos.x));
col *= 0.7 + f;
return col;
}
float rand(float val, float seed) {
return cos(val * sin(val * seed) * seed);
}
float distance2(in vec2 a, in vec2 b) {
return dot(a - b, a - b);
}
mat2 rr = mat2(cos(1.0), -sin(1.0), sin(1.0), cos(1.0));
vec3 drawParticles(vec2 pos, vec3 particolor, float time, vec2 cpos, float gravity, float seed, float timelength) {
vec3 col = vec3(0.0);
vec2 pp = vec2(1.0, 0.0);
for (float i = 1.0; i <= 128.0; i++) {
float d = rand(i, seed);
float fade = (i / 128.0) * time;
vec2 particpos = cpos + time * pp * d;
pp = rr * pp;
col = mix(particolor / fade, col, smoothstep(0.0, 0.0001, distance2(particpos, pos)));
}
col *= smoothstep(0.0, 1.0, (timelength - time) / timelength);
return col;
}
vec3 drawFireworks(float time, vec2 uv, vec3 particolor, float seed) {
float timeoffset = 2.0;
vec3 col = vec3(0.0);
if (time <= 0.) {
return col;
}
if (mod(time, 6.0) > timeoffset) {
col = drawParticles(uv, particolor, mod(time, 6.0) - timeoffset, vec2(rand(ceil(time / 6.0), seed), -0.5), 0.5, ceil(time / 6.0), seed);
} else {
col = rocket(uv * 3., vec2(3. * rand(ceil(time / 6.0), seed), 3. * (-0.5 + (timeoffset - mod(time, 6.0)))));
}
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = 1.0 - 2.0 * fragCoord.xy / iResolution.xy;
uv.x *= iResolution.x / iResolution.y;
vec3 col = vec3(0.1, 0.1, 0.2);
// Flip the y-axis so that the rocket is drawn from the bottom of the screen
uv.y = -uv.y;
col += 0.1 * uv.y;
col += drawFireworks(iTime, uv, vec3(1.0, 0.1, 0.1), 1.);
col += drawFireworks(iTime - 2.0, uv, vec3(0.0, 1.0, 0.5), 2.);
col += drawFireworks(iTime - 4.0, uv, vec3(1.0, 1.0, 0.1), 3.);
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb * 1.0, col.rgb * 0.3, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,116 @@
// This Ghostty shader is a port of https://www.shadertoy.com/view/lscGRl
// "Fireworks" by Martijn Steinrucken aka BigWings - 2015
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// Email:countfrolic@gmail.com Twitter:@The_ArtOfCode
#define BLACK_BLEND_THRESHOLD .4
#define PI 3.141592653589793238
#define TWOPI 6.283185307179586
#define S(x,y,z) smoothstep(x,y,z)
#define B(x,y,z,w) S(x-z, x+z, w)*S(y+z, y-z, w)
#define saturate(x) clamp(x,0.,1.)
#define NUM_EXPLOSIONS 3.
#define NUM_PARTICLES 42.
// Noise functions by Dave Hoskins
#define MOD3 vec3(.1031,.11369,.13787)
vec3 hash31(float p) {
vec3 p3 = fract(vec3(p) * MOD3);
p3 += dot(p3, p3.yzx + 19.19);
return fract(vec3((p3.x + p3.y) * p3.z, (p3.x + p3.z) * p3.y, (p3.y + p3.z) * p3.x));
}
float hash12(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * MOD3);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.x + p3.y) * p3.z);
}
float circ(vec2 uv, vec2 pos, float size) {
uv -= pos;
size *= size;
return S(size * 1.1, size, dot(uv, uv));
}
float light(vec2 uv, vec2 pos, float size) {
uv -= pos;
size *= size;
return size / dot(uv, uv);
}
vec3 explosion(vec2 uv, vec2 p, float seed, float t) {
vec3 col = vec3(0.);
vec3 en = hash31(seed);
vec3 baseCol = en;
for (float i = 0.; i < NUM_PARTICLES; i++) {
vec3 n = hash31(i) - .5;
vec2 startP = p - vec2(0., t * t * .1);
vec2 endP = startP + normalize(n.xy) * n.z - vec2(0., t * .2);
float pt = 1. - pow(t - 1., 2.);
vec2 pos = mix(p, endP, pt);
float size = mix(.01, .005, S(0., .1, pt));
size *= S(1., .1, pt);
float sparkle = (sin((pt + n.z) * 21.) * .5 + .5);
sparkle = pow(sparkle, pow(en.x, 3.) * 50.) * mix(0.01, .01, en.y * n.y);
//size += sparkle*B(.6, 1., .1, t);
size += sparkle * B(en.x, en.y, en.z, t);
col += baseCol * light(uv, pos, size);
}
return col;
}
vec3 Rainbow(vec3 c) {
float t = iTime;
float avg = (c.r + c.g + c.b) / 3.;
c = avg + (c - avg) * sin(vec3(0., .333, .666) + t);
c += sin(vec3(.4, .3, .3) * t + vec3(1.1244, 3.43215, 6.435)) * vec3(.4, .1, .5);
return c;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord.xy / iResolution.xy;
uv.x -= .5;
uv.x *= iResolution.x / iResolution.y;
// Flip the y-axis so that the gravity is downwards
uv.y = -uv.y + 1.;
float n = hash12(uv + 10.);
float t = iTime * .5;
vec3 c = vec3(0.);
for (float i = 0.; i < NUM_EXPLOSIONS; i++) {
float et = t + i * 1234.45235;
float id = floor(et);
et -= id;
vec2 p = hash31(id).xy;
p.x -= .5;
p.x *= 1.6;
c += explosion(uv, p, id, et);
}
c = Rainbow(c);
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb * 1.0, c.rgb * 0.3, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

139
ghostty/shaders/galaxy.glsl Normal file
View File

@@ -0,0 +1,139 @@
float triangle(float x, float period) {
return 2.0 * abs(3.0* ((x / period) - floor((x / period) + 0.5))) - 1.0;
}
float field(in vec3 position) {
float strength = 7.0 + 0.03 * log(1.0e-6 + fract(sin(iTime) * 373.11));
float accumulated = 0.0;
float previousMagnitude = 0.0;
float totalWeight = 0.0;
for (int i = 0; i < 6; ++i) {
float magnitude = dot(position, position);
position = abs(position) / magnitude + vec3(-0.5, -0.8 + 0.1 * sin(-iTime * 0.1 + 2.0), -1.1 + 0.3 * cos(iTime * 0.3));
float weight = exp(-float(i) / 7.0);
accumulated += weight * exp(-strength * pow(abs(magnitude - previousMagnitude), 2.3));
totalWeight += weight;
previousMagnitude = magnitude;
}
return max(0.0, 5.0 * accumulated / totalWeight - 0.7);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
const float baseSpeed = 0.02;
const int maxIterations = 16;
const float formulaParameter = 0.79;
const float volumeSteps = 7.0;
const float stepSize = 0.24;
const float zoomFactor = 0.1;
const float tilingFactor = 0.85;
const float baseBrightness = 0.0008;
const float darkMatter = 0.2;
const float distanceFading = 0.56;
const float colorSaturation = 0.9;
const float transverseMotion = 0.2;
const float cloudOpacity = 0.48;
const float zoomSpeed = 0.0002;
vec2 normalizedCoordinates = 2.0 * fragCoord.xy / vec2(512) - 1.0;
vec2 scaledCoordinates = normalizedCoordinates * vec2(512) / 512.0;
float timeElapsed = iTime;
float speedAdjustment = -baseSpeed;
float formulaAdjustment = formulaParameter;
speedAdjustment = zoomSpeed * cos(iTime * 0.02 + 3.1415926 / 4.0);
vec2 uvCoordinates = scaledCoordinates;
float rotationXZ = 0.9;
float rotationYZ = -0.6;
float rotationXY = 0.9 + iTime * 0.08;
mat2 rotationMatrixXZ = mat2(vec2(cos(rotationXZ), sin(rotationXZ)), vec2(-sin(rotationXZ), cos(rotationXZ)));
mat2 rotationMatrixYZ = mat2(vec2(cos(rotationYZ), sin(rotationYZ)), vec2(-sin(rotationYZ), cos(rotationYZ)));
mat2 rotationMatrixXY = mat2(vec2(cos(rotationXY), sin(rotationXY)), vec2(-sin(rotationXY), cos(rotationXY)));
vec2 canvasCenter = vec2(0.5, 0.5);
vec3 rayDirection = vec3(uvCoordinates * zoomFactor, 1.0);
vec3 cameraPosition = vec3(0.0, 0.0, 0.0);
cameraPosition.x -= 2.0 * (canvasCenter.x - 0.5);
cameraPosition.y -= 2.0 * (canvasCenter.y - 0.5);
vec3 forwardVector = vec3(0.0, 0.0, 1.0);
cameraPosition.x += transverseMotion * cos(0.01 * iTime) + 0.001 * iTime;
cameraPosition.y += transverseMotion * sin(0.01 * iTime) + 0.001 * iTime;
cameraPosition.z += 0.003 * iTime;
rayDirection.xz *= rotationMatrixXZ;
forwardVector.xz *= rotationMatrixXZ;
rayDirection.yz *= rotationMatrixYZ;
forwardVector.yz *= rotationMatrixYZ;
cameraPosition.xy *= -1.0 * rotationMatrixXY;
cameraPosition.xz *= rotationMatrixXZ;
cameraPosition.yz *= rotationMatrixYZ;
float zoomOffset = (timeElapsed - 3311.0) * speedAdjustment;
cameraPosition += forwardVector * zoomOffset;
float sampleOffset = mod(zoomOffset, stepSize);
float normalizedSampleOffset = sampleOffset / stepSize;
float stepDistance = 0.24;
float secondaryStepDistance = stepDistance + stepSize / 2.0;
vec3 accumulatedColor = vec3(0.0);
float fieldContribution = 0.0;
vec3 backgroundColor = vec3(0.0);
for (float stepIndex = 0.0; stepIndex < volumeSteps; ++stepIndex) {
vec3 primaryPosition = cameraPosition + (stepDistance + sampleOffset) * rayDirection;
vec3 secondaryPosition = cameraPosition + (secondaryStepDistance + sampleOffset) * rayDirection;
primaryPosition = abs(vec3(tilingFactor) - mod(primaryPosition, vec3(tilingFactor * 2.0)));
secondaryPosition = abs(vec3(tilingFactor) - mod(secondaryPosition, vec3(tilingFactor * 2.0)));
fieldContribution = field(secondaryPosition);
float particleAccumulator = 0.0, particleDistance = 0.0;
for (int i = 0; i < maxIterations; ++i) {
primaryPosition = abs(primaryPosition) / dot(primaryPosition, primaryPosition) - formulaAdjustment;
float distanceChange = abs(length(primaryPosition) - particleDistance);
particleAccumulator += i > 2 ? min(12.0, distanceChange) : distanceChange;
particleDistance = length(primaryPosition);
}
particleAccumulator *= particleAccumulator * particleAccumulator;
float fadeFactor = pow(distanceFading, max(0.0, float(stepIndex) - normalizedSampleOffset));
accumulatedColor += vec3(stepDistance, stepDistance * stepDistance, stepDistance * stepDistance * stepDistance * stepDistance)
* particleAccumulator * baseBrightness * fadeFactor;
backgroundColor += mix(0.4, 1.0, cloudOpacity) * vec3(1.8 * fieldContribution * fieldContribution * fieldContribution,
1.4 * fieldContribution * fieldContribution, fieldContribution) * fadeFactor;
stepDistance += stepSize;
secondaryStepDistance += stepSize;
}
accumulatedColor = mix(vec3(length(accumulatedColor)), accumulatedColor, colorSaturation);
vec4 foregroundColor = vec4(accumulatedColor * 0.01, 1.0);
backgroundColor *= cloudOpacity;
backgroundColor.b *= 1.8;
backgroundColor.r *= 0.05;
backgroundColor.b = 0.5 * mix(backgroundColor.g, backgroundColor.b, 0.8);
backgroundColor.g = 0.0;
backgroundColor.bg = mix(backgroundColor.gb, backgroundColor.bg, 0.5 * (cos(iTime * 0.01) + 1.0));
vec2 terminalUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, terminalUV);
float brightnessThreshold = 0.1;
float terminalBrightness = dot(terminalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
if (terminalBrightness < brightnessThreshold) {
fragColor = mix(terminalColor, vec4(foregroundColor.rgb + backgroundColor, 1.0), 0.24);
} else {
fragColor = terminalColor;
}
}

View File

@@ -0,0 +1,377 @@
// sligltly modified version of https://www.shadertoy.com/view/DsVSDV
// The only changes are done in the mainImage function
// Ive added comments on what to modify
// works really well with most colorschemes
#define Rot(a) mat2(cos(a),-sin(a),sin(a),cos(a))
#define antialiasing(n) n/min(iResolution.y,iResolution.x)
#define S(d,b) smoothstep(antialiasing(3.0),b,d)
#define B(p,s) max(abs(p).x-s.x,abs(p).y-s.y)
#define deg45 .707
#define R45(p) (( p + vec2(p.y,-p.x) ) *deg45)
#define Tri(p,s) max(R45(p).x,max(R45(p).y,B(p,s)))
#define DF(a,b) length(a) * cos( mod( atan(a.y,a.x)+6.28/(b*8.0), 6.28/((b*8.0)*0.5))+(b-1.)*6.28/(b*8.0) + vec2(0,11) )
float random (vec2 p) {
return fract(sin(dot(p.xy, vec2(12.9898,78.233)))* 43758.5453123);
}
float innerGear(vec2 p, float dir){
p*=Rot(radians(-iTime*45.+45.)*dir);
vec2 prevP = p;
//p*=Rot(radians(iTime*45.+20.));
p = DF(p,7.);
p-=vec2(0.24);
p*=Rot(deg45);
float d = B(p,vec2(0.01,0.06));
p = prevP;
float d2 = abs(length(p)-0.42)-0.02;
d = min(d,d2);
d2 = abs(length(p)-0.578)-0.02;
d = min(d,d2);
d2 = abs(length(p)-0.499)-0.005;
d = min(d,d2);
p = DF(p,7.);
p-=vec2(0.43);
p*=Rot(deg45);
d2 = B(p,vec2(0.01,0.04));
d = min(d,d2);
return d;
}
vec3 pattern1(vec2 p, vec3 col, float dir){
vec2 prevP = p;
float size = 0.499;
float thick = 0.15;
p+=vec2(size);
float d = abs(length(p)-size)-thick;
d = max(d,innerGear(p,dir));
col = mix(col,vec3(1.),S(d,0.0));
p = prevP;
p-=vec2(size);
d = abs(length(p)-size)-thick;
d = max(d,innerGear(p,dir));
col = mix(col,vec3(1.),S(d,0.0));
return col;
}
vec3 pattern2(vec2 p, vec3 col, float dir){
vec2 prevP = p;
float size = 0.33;
float thick = 0.15;
float thift = 0.0;
float speed = 0.3;
p-=vec2(size,0.);
float d = B(p,vec2(size,thick));
p.x+=thift;
p.x-=iTime*speed*dir;
p.x=mod(p.x,0.08)-0.04;
d = max(d,B(p,vec2(0.011,thick)));
p = prevP;
d = max(-(abs(p.y)-0.1),d);
//d = min(B(p,vec2(1.,0.1)),d);
p.y=abs(p.y)-0.079;
d = min(B(p,vec2(1.,0.02)),d);
p = prevP;
p-=vec2(0.0,size);
float d2 = B(p,vec2(thick,size));
p.y+=thift;
p.y+=iTime*speed*dir;
p.y=mod(p.y,0.08)-0.04;
d2 = max(d2,B(p,vec2(thick,0.011)));
p = prevP;
d2 = max(-(abs(p.x)-0.1),d2);
d2 = min(B(p,vec2(0.005,1.)),d2);
p.x=abs(p.x)-0.079;
d2 = min(B(p,vec2(0.02,1.)),d2);
d = min(d,d2);
p = prevP;
p+=vec2(0.0,size);
d2 = B(p,vec2(thick,size));
p.y+=thift;
p.y-=iTime*speed*dir;
p.y=mod(p.y,0.08)-0.04;
d2 = max(d2,B(p,vec2(thick,0.011)));
p = prevP;
d2 = max(-(abs(p.x)-0.1),d2);
d2 = min(B(p,vec2(0.005,1.)),d2);
p.x=abs(p.x)-0.079;
d2 = min(B(p,vec2(0.02,1.)),d2);
d = min(d,d2);
p = prevP;
p+=vec2(size,0.0);
d2 = B(p,vec2(size,thick));
p.x+=thift;
p.x+=iTime*speed*dir;
p.x=mod(p.x,0.08)-0.04;
d2 = max(d2,B(p,vec2(0.011,thick)));
d = min(d,d2);
p = prevP;
d = max(-(abs(p.y)-0.1),d);
d = min(B(p,vec2(1.,0.005)),d);
p.y=abs(p.y)-0.079;
d = min(B(p,vec2(1.,0.02)),d);
p = prevP;
d2 = abs(B(p,vec2(size*0.3)))-0.05;
d = min(d,d2);
col = mix(col,vec3(1.),S(d,0.0));
d = B(p,vec2(0.08));
col = mix(col,vec3(0.),S(d,0.0));
p*=Rot(radians(60.*iTime*dir));
d = B(p,vec2(0.03));
col = mix(col,vec3(1.),S(d,0.0));
return col;
}
vec3 drawBelt(vec2 p, vec3 col, float size){
vec2 prevP = p;
p*=size;
vec2 id = floor(p);
vec2 gr = fract(p)-0.5;
float dir = mod(id.x+id.y,2.)*2.-1.;
float n = random(id);
if(n<0.5){
if(n<0.25){
gr.x*=-1.;
}
col = pattern1(gr,col,dir);
} else {
if(n>0.75){
gr.x*=-1.;
}
col = pattern2(gr,col,dir);
}
return col;
}
vec3 gear(vec2 p, vec3 col, float dir){
vec2 prevP = p;
p*=Rot(radians(iTime*45.+13.)*-dir);
p = DF(p,7.);
p-=vec2(0.23);
p*=Rot(deg45);
float d = B(p,vec2(0.01,0.04));
p = prevP;
float d2 = abs(length(p)-0.29)-0.02;
d = min(d,d2);
col = mix(col,vec3(1.),S(d,0.0));
p*=Rot(radians(iTime*30.-30.)*dir);
p = DF(p,6.);
p-=vec2(0.14);
p*=Rot(radians(45.));
d = B(p,vec2(0.01,0.03));
p = prevP;
d2 =abs( length(p)-0.1)-0.02;
p*=Rot(radians(iTime*25.+30.)*-dir);
d2 = max(-(abs(p.x)-0.05),d2);
d = min(d,d2);
col = mix(col,vec3(1.),S(d,0.0));
return col;
}
vec3 item0(vec2 p, vec3 col, float dir){
vec2 prevP = p;
p.x*=dir;
p*=Rot(radians(iTime*30.+30.));
float d = abs(length(p)-0.2)-0.05;
col = mix(col,vec3(0.3),S(d,0.0));
d = abs(length(p)-0.2)-0.05;
d = max(-p.x,d);
float a = clamp(atan(p.x,p.y)*0.5,0.3,1.);
col = mix(col,vec3(a),S(d,0.0));
return col;
}
vec3 item1(vec2 p, vec3 col, float dir){
p.x*=dir;
vec2 prevP = p;
p*=Rot(radians(iTime*30.+30.));
float d = abs(length(p)-0.25)-0.04;
d = abs(max((abs(p.y)-0.15),d))-0.005;
float d2 = abs(length(p)-0.25)-0.01;
d2 = max((abs(p.y)-0.12),d2);
d = min(d,d2);
d2 = abs(length(p)-0.27)-0.01;
d2 = max(-(abs(p.y)-0.22),d2);
d = min(d,d2);
d2 = B(p,vec2(0.01,0.32));
d2 = max(-(abs(p.y)-0.22),d2);
d = min(d,d2);
p = prevP;
p*=Rot(radians(iTime*-20.+30.));
p = DF(p,2.);
p-=vec2(0.105);
p*=Rot(radians(45.));
d2 = B(p,vec2(0.03,0.01));
d = min(d,d2);
p = prevP;
d2 = abs(length(p)-0.09)-0.005;
d2 = max(-(abs(p.x)-0.03),d2);
d2 = max(-(abs(p.y)-0.03),d2);
d = min(d,d2);
col = mix(col,vec3(0.6),S(d,0.0));
return col;
}
vec3 item2(vec2 p, vec3 col, float dir){
p.x*=dir;
p*=Rot(radians(iTime*50.-10.));
vec2 prevP = p;
float d = abs(length(p)-0.15)-0.005;
float d2 = abs(length(p)-0.2)-0.01;
d2 = max((abs(p.y)-0.15),d2);
d = min(d,d2);
p = DF(p,1.);
p-=vec2(0.13);
p*=Rot(radians(45.));
d2 = B(p,vec2(0.008,0.1));
d = min(d,d2);
p = prevP;
p = DF(p,4.);
p-=vec2(0.18);
p*=Rot(radians(45.));
d2 = B(p,vec2(0.005,0.02));
d = min(d,d2);
col = mix(col,vec3(0.6),S(d,0.0));
return col;
}
float needle(vec2 p){
p.y-=0.05;
p*=1.5;
vec2 prevP = p;
p.y-=0.3;
p.x*=6.;
float d = Tri(p,vec2(0.3));
p = prevP;
p.y+=0.1;
p.x*=2.;
p.y*=-1.;
float d2 = Tri(p,vec2(0.1));
d = min(d,d2);
return d;
}
vec3 item3(vec2 p, vec3 col, float dir){
p*=Rot(radians(sin(iTime*dir)*120.));
vec2 prevP = p;
p.y= abs(p.y)-0.05;
float d = needle(p);
p = prevP;
float d2 = abs(length(p)-0.1)-0.003;
d2 = max(-(abs(p.x)-0.05),d2);
d = min(d,d2);
d2 = abs(length(p)-0.2)-0.005;
d2 = max(-(abs(p.x)-0.08),d2);
d = min(d,d2);
p = DF(p,4.);
p-=vec2(0.18);
d2 = length(p)-0.01;
p = prevP;
d2 = max(-(abs(p.x)-0.03),d2);
d = min(d,d2);
col = mix(col,vec3(0.6),S(d,0.0));
return col;
}
vec3 drawGearsAndItems(vec2 p, vec3 col, float size){
vec2 prevP = p;
p*=size;
p+=vec2(0.5);
vec2 id = floor(p);
vec2 gr = fract(p)-0.5;
float n = random(id);
float dir = mod(id.x+id.y,2.)*2.-1.;
if(n<0.3){
col = gear(gr,col,dir);
} else if(n>=0.3 && n<0.5){
col = item0(gr,col,dir);
} else if(n>=0.5 && n<0.7){
col = item1(gr,col,dir);
} else if(n>=0.7 && n<0.8) {
col = item2(gr,col,dir);
} else if(n>=0.8){
col = item3(gr,col,dir);
}
return col;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (fragCoord-0.5*iResolution.xy)/iResolution.y;
// set speed of downwards motion
p.y+=iTime*0.02;
float size = 4.;
vec3 col = vec3(0.);
// Modify the colors to be darker by multiplying with a small factor
vec3 darkFactor = vec3(.5); // This makes everything 50% as bright
// Get the original colors but make them darker
col = drawBelt(p, col, size) * darkFactor;
col = drawGearsAndItems(p, col, size) * darkFactor;
// Additional option: you can add a color tint to make it less stark white
vec3 tint = vec3(0.1, 0.12, 0.15); // Slight blue-ish dark tint
col = col * tint;
vec2 uv = fragCoord/iResolution.xy;
vec4 terminalColor = texture(iChannel0, uv);
// Blend with reduced opacity for the shader elements
vec3 blendedColor = terminalColor.rgb + col.rgb * 0.7; // Reduced blend factor
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,117 @@
// modified version of https://www.shadertoy.com/view/wld3WN
// amount of seconds for which the glitch loop occurs
#define DURATION 10.
// percentage of the duration for which the glitch is triggered
#define AMT .1
#define SS(a, b, x) (smoothstep(a, b, x) * smoothstep(b, a, x))
#define UI0 1597334673U
#define UI1 3812015801U
#define UI2 uvec2(UI0, UI1)
#define UI3 uvec3(UI0, UI1, 2798796415U)
#define UIF (1. / float(0xffffffffU))
// Hash by David_Hoskins
vec3 hash33(vec3 p)
{
uvec3 q = uvec3(ivec3(p)) * UI3;
q = (q.x ^ q.y ^ q.z)*UI3;
return -1. + 2. * vec3(q) * UIF;
}
// Gradient noise by iq
float gnoise(vec3 x)
{
// grid
vec3 p = floor(x);
vec3 w = fract(x);
// quintic interpolant
vec3 u = w * w * w * (w * (w * 6. - 15.) + 10.);
// gradients
vec3 ga = hash33(p + vec3(0., 0., 0.));
vec3 gb = hash33(p + vec3(1., 0., 0.));
vec3 gc = hash33(p + vec3(0., 1., 0.));
vec3 gd = hash33(p + vec3(1., 1., 0.));
vec3 ge = hash33(p + vec3(0., 0., 1.));
vec3 gf = hash33(p + vec3(1., 0., 1.));
vec3 gg = hash33(p + vec3(0., 1., 1.));
vec3 gh = hash33(p + vec3(1., 1., 1.));
// projections
float va = dot(ga, w - vec3(0., 0., 0.));
float vb = dot(gb, w - vec3(1., 0., 0.));
float vc = dot(gc, w - vec3(0., 1., 0.));
float vd = dot(gd, w - vec3(1., 1., 0.));
float ve = dot(ge, w - vec3(0., 0., 1.));
float vf = dot(gf, w - vec3(1., 0., 1.));
float vg = dot(gg, w - vec3(0., 1., 1.));
float vh = dot(gh, w - vec3(1., 1., 1.));
// interpolation
float gNoise = va + u.x * (vb - va) +
u.y * (vc - va) +
u.z * (ve - va) +
u.x * u.y * (va - vb - vc + vd) +
u.y * u.z * (va - vc - ve + vg) +
u.z * u.x * (va - vb - ve + vf) +
u.x * u.y * u.z * (-va + vb + vc - vd + ve - vf - vg + vh);
return 2. * gNoise;
}
// gradient noise in range [0, 1]
float gnoise01(vec3 x)
{
return .5 + .5 * gnoise(x);
}
// warp uvs for the crt effect
vec2 crt(vec2 uv)
{
float tht = atan(uv.y, uv.x);
float r = length(uv);
// curve without distorting the center
r /= (1. - .1 * r * r);
uv.x = r * cos(tht);
uv.y = r * sin(tht);
return .5 * (uv + 1.);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
float t = iTime;
// smoothed interval for which the glitch gets triggered
float glitchAmount = SS(DURATION * .001, DURATION * AMT, mod(t, DURATION));
float displayNoise = 0.;
vec3 col = vec3(0.);
vec2 eps = vec2(5. / iResolution.x, 0.);
vec2 st = vec2(0.);
// analog distortion
float y = uv.y * iResolution.y;
float distortion = gnoise(vec3(0., y * .01, t * 500.)) * (glitchAmount * 4. + .1);
distortion *= gnoise(vec3(0., y * .02, t * 250.)) * (glitchAmount * 2. + .025);
++displayNoise;
distortion += smoothstep(.999, 1., sin((uv.y + t * 1.6) * 2.)) * .02;
distortion -= smoothstep(.999, 1., sin((uv.y + t) * 2.)) * .02;
st = uv + vec2(distortion, 0.);
// chromatic aberration
col.r += textureLod(iChannel0, st + eps + distortion, 0.).r;
col.g += textureLod(iChannel0, st, 0.).g;
col.b += textureLod(iChannel0, st - eps - distortion, 0.).b;
// white noise + scanlines
displayNoise = 0.2 * clamp(displayNoise, 0., 1.);
col += (.15 + .65 * glitchAmount) * (hash33(vec3(fragCoord, mod(float(iFrame),
1000.))).r) * displayNoise;
col -= (.25 + .75 * glitchAmount) * (sin(4. * t + uv.y * iResolution.y * 1.75))
* displayNoise;
fragColor = vec4(col, 1.0);
}

View File

@@ -0,0 +1,144 @@
// First it does a "chromatic aberration" by splitting the rgb signals by a product of sin functions
// over time, then it does a glow effect in a perceptual color space
// Based on kalgynirae's Ghostty passable glow shader and NickWest's Chromatic Aberration shader demo
// Passable glow: https://github.com/kalgynirae/dotfiles/blob/main/ghostty/glow.glsl
// "Chromatic Aberration": https://www.shadertoy.com/view/Mds3zn
// sRGB linear -> nonlinear transform from https://bottosson.github.io/posts/colorwrong/
float f(float x) {
if (x >= 0.0031308) {
return 1.055 * pow(x, 1.0 / 2.4) - 0.055;
} else {
return 12.92 * x;
}
}
float f_inv(float x) {
if (x >= 0.04045) {
return pow((x + 0.055) / 1.055, 2.4);
} else {
return x / 12.92;
}
}
// Oklab <-> linear sRGB conversions from https://bottosson.github.io/posts/oklab/
vec4 toOklab(vec4 rgb) {
vec3 c = vec3(f_inv(rgb.r), f_inv(rgb.g), f_inv(rgb.b));
float l = 0.4122214708 * c.r + 0.5363325363 * c.g + 0.0514459929 * c.b;
float m = 0.2119034982 * c.r + 0.6806995451 * c.g + 0.1073969566 * c.b;
float s = 0.0883024619 * c.r + 0.2817188376 * c.g + 0.6299787005 * c.b;
float l_ = pow(l, 1.0 / 3.0);
float m_ = pow(m, 1.0 / 3.0);
float s_ = pow(s, 1.0 / 3.0);
return vec4(
0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_,
rgb.a
);
}
vec4 toRgb(vec4 oklab) {
vec3 c = oklab.rgb;
float l_ = c.r + 0.3963377774 * c.g + 0.2158037573 * c.b;
float m_ = c.r - 0.1055613458 * c.g - 0.0638541728 * c.b;
float s_ = c.r - 0.0894841775 * c.g - 1.2914855480 * c.b;
float l = l_ * l_ * l_;
float m = m_ * m_ * m_;
float s = s_ * s_ * s_;
vec3 linear_srgb = vec3(
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
);
return vec4(
clamp(f(linear_srgb.r), 0.0, 1.0),
clamp(f(linear_srgb.g), 0.0, 1.0),
clamp(f(linear_srgb.b), 0.0, 1.0),
oklab.a
);
}
// Bloom samples from https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f
const vec3[24] samples = {
vec3(0.1693761725038636, 0.9855514761735895, 1),
vec3(-1.333070830962943, 0.4721463328627773, 0.7071067811865475),
vec3(-0.8464394909806497, -1.51113870578065, 0.5773502691896258),
vec3(1.554155680728463, -1.2588090085709776, 0.5),
vec3(1.681364377589461, 1.4741145918052656, 0.4472135954999579),
vec3(-1.2795157692199817, 2.088741103228784, 0.4082482904638631),
vec3(-2.4575847530631187, -0.9799373355024756, 0.3779644730092272),
vec3(0.5874641440200847, -2.7667464429345077, 0.35355339059327373),
vec3(2.997715703369726, 0.11704939884745152, 0.3333333333333333),
vec3(0.41360842451688395, 3.1351121305574803, 0.31622776601683794),
vec3(-3.167149933769243, 0.9844599011770256, 0.30151134457776363),
vec3(-1.5736713846521535, -3.0860263079123245, 0.2886751345948129),
vec3(2.888202648340422, -2.1583061557896213, 0.2773500981126146),
vec3(2.7150778983300325, 2.5745586041105715, 0.2672612419124244),
vec3(-2.1504069972377464, 3.2211410627650165, 0.2581988897471611),
vec3(-3.6548858794907493, -1.6253643308191343, 0.25),
vec3(1.0130775986052671, -3.9967078676335834, 0.24253562503633297),
vec3(4.229723673607257, 0.33081361055181563, 0.23570226039551587),
vec3(0.40107790291173834, 4.340407413572593, 0.22941573387056174),
vec3(-4.319124570236028, 1.159811599693438, 0.22360679774997896),
vec3(-1.9209044802827355, -4.160543952132907, 0.2182178902359924),
vec3(3.8639122286635708, -2.6589814382925123, 0.21320071635561041),
vec3(3.3486228404946234, 3.4331800232609, 0.20851441405707477),
vec3(-2.8769733643574344, 3.9652268864187157, 0.20412414523193154)
};
float offsetFunction(float iTime) {
float amount = 1.0;
const float periods[4] = {6.0, 16.0, 19.0, 27.0};
for (int i = 0; i < 4; i++) {
amount *= 1.0 + 0.5 * sin(iTime*periods[i]);
}
//return amount;
return amount * periods[3];
}
const float DIM_CUTOFF = 0.35;
const float BRIGHT_CUTOFF = 0.65;
const float ABBERATION_FACTOR = 0.05;
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
float amount = offsetFunction(iTime);
vec3 col;
col.r = texture( iChannel0, vec2(uv.x-ABBERATION_FACTOR*amount / iResolution.x, uv.y) ).r;
col.g = texture( iChannel0, uv ).g;
col.b = texture( iChannel0, vec2(uv.x+ABBERATION_FACTOR*amount / iResolution.x, uv.y) ).b;
vec4 splittedColor = vec4(col, 1.0);
vec4 source = toOklab(splittedColor);
vec4 dest = source;
if (source.x > DIM_CUTOFF) {
dest.x *= 1.2;
// dest.x = 1.2;
} else {
vec2 step = vec2(1.414) / iResolution.xy;
vec3 glow = vec3(0.0);
for (int i = 0; i < 24; i++) {
vec3 s = samples[i];
float weight = s.z;
vec4 c = toOklab(texture(iChannel0, uv + s.xy * step));
if (c.x > DIM_CUTOFF) {
glow.yz += c.yz * weight * 0.3;
if (c.x <= BRIGHT_CUTOFF) {
glow.x += c.x * weight * 0.05;
} else {
glow.x += c.x * weight * 0.10;
}
}
}
// float lightness_diff = clamp(glow.x - dest.x, 0.0, 1.0);
// dest.x = lightness_diff;
// dest.yz = dest.yz * (1.0 - lightness_diff) + glow.yz * lightness_diff;
dest.xyz += glow.xyz;
}
fragColor = toRgb(dest);
}

View File

@@ -0,0 +1,25 @@
// credits: https://github.com/unkn0wncode
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// Normalize pixel coordinates (range from 0 to 1)
vec2 uv = fragCoord.xy / iResolution.xy;
// Create a gradient from bottom right to top left as a function (x + y)/2
float gradientFactor = (uv.x + uv.y) / 2.0;
// Define gradient colors (adjust to your preference)
vec3 gradientStartColor = vec3(0.1, 0.1, 0.5); // Start color (e.g., dark blue)
vec3 gradientEndColor = vec3(0.5, 0.1, 0.1); // End color (e.g., dark red)
vec3 gradientColor = mix(gradientStartColor, gradientEndColor, gradientFactor);
// Sample the terminal screen texture including alpha channel
vec4 terminalColor = texture(iChannel0, uv);
// Make a mask that is 1.0 where the terminal content is not black
float mask = 1 - step(0.5, dot(terminalColor.rgb, vec3(1.0)));
vec3 blendedColor = mix(terminalColor.rgb, gradientColor, mask);
// Apply terminal's alpha to control overall opacity
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,304 @@
// In-game CRT shader
// Author: sarphiv
// License: CC BY-NC-SA 4.0
// Description:
// Shader for ghostty that is focussed on being usable while looking like a stylized CRT terminal in a modern video game.
// I know a tiny bit about shaders, and nothing about GLSL,
// so this is a Frakenstein's monster combination of other shaders together with a lot of surgery.
// On the bright side, i've cleaned up the body parts and surgery a lot.
// Based on:
// 1. https://gist.github.com/mitchellh/39d62186910dcc27cad097fed16eb882 (forces the choice of license)
// 2. https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f
// 3. https://gist.github.com/seanwcom/0fbe6b270aaa5f28823e053d3dbb14ca
// Settings:
// How straight the terminal is in each axis
// (x, y) \in R^2 : x, y > 0
#define CURVE 13.0, 11.0
// How far apart the different colors are from each other
// x \in R
#define COLOR_FRINGING_SPREAD 1.0
// How much the ghost images are spread out
// x \in R : x >= 0
#define GHOSTING_SPREAD 0.75
// How visible ghost images are
// x \in R : x >= 0
#define GHOSTING_STRENGTH 1.0
// How much of the non-linearly darkened colors are mixed in
// [0, 1]
#define DARKEN_MIX 0.4
// How far in the vignette spreads
// x \in R : x >= 0
#define VIGNETTE_SPREAD 0.3
// How bright the vignette is
// x \in R : x >= 0
#define VIGNETTE_BRIGHTNESS 6.4
// Tint all colors
// [0, 1]^3
#define TINT 0.93, 1.00, 0.96
// How visible the scan line effect is
// NOTE: Technically these are not scan lines, but rather the lack of them
// [0, 1]
#define SCAN_LINES_STRENGTH 0.15
// How bright the spaces between the lines are
// [0, 1]
#define SCAN_LINES_VARIANCE 0.35
// Pixels per scan line effect
// x \in R : x > 0
#define SCAN_LINES_PERIOD 4.0
// How visible the aperture grille is
// x \in R : x >= 0
#define APERTURE_GRILLE_STRENGTH 0.2
// Pixels per aperture grille
// x \in R : x > 0
#define APERTURE_GRILLE_PERIOD 2.0
// How much the screen flickers
// x \in R : x >= 0
#define FLICKER_STRENGTH 0.05
// How fast the screen flickers
// x \in R : x > 0
#define FLICKER_FREQUENCY 15.0
// How much noise is added to filled areas
// [0, 1]
#define NOISE_CONTENT_STRENGTH 0.15
// How much noise is added everywhere
// [0, 1]
#define NOISE_UNIFORM_STRENGTH 0.03
// How big the bloom is
// x \in R : x >= 0
#define BLOOM_SPREAD 8.0
// How visible the bloom is
// [0, 1]
#define BLOOM_STRENGTH 0.04
// How fast colors fade in and out
// [0, 1]
#define FADE_FACTOR 0.55
// Disabled values for when the settings are not defined
#ifndef COLOR_FRINGING_SPREAD
#define COLOR_FRINGING_SPREAD 0.0
#endif
#if !defined(GHOSTING_SPREAD) || !defined(GHOSTING_STRENGTH)
#undef GHOSTING_SPREAD
#undef GHOSTING_STRENGTH
#define GHOSTING_SPREAD 0.0
#define GHOSTING_STRENGTH 0.0
#endif
#ifndef DARKEN_MIX
#define DARKEN_MIX 0.0
#endif
#if !defined(VIGNETTE_SPREAD) || !defined(VIGNETTE_BRIGHTNESS)
#undef VIGNETTE_SPREAD
#undef VIGNETTE_BRIGHTNESS
#define VIGNETTE_SPREAD 0.0
#define VIGNETTE_BRIGHTNESS 1.0
#endif
#ifndef TINT
#define TINT 1.00, 1.00, 1.00
#endif
#if !defined(SCAN_LINES_STRENGTH) || !defined(SCAN_LINES_VARIANCE) || !defined(SCAN_LINES_PERIOD)
#undef SCAN_LINES_STRENGTH
#undef SCAN_LINES_VARIANCE
#undef SCAN_LINES_PERIOD
#define SCAN_LINES_STRENGTH 0.0
#define SCAN_LINES_VARIANCE 1.0
#define SCAN_LINES_PERIOD 1.0
#endif
#if !defined(APERTURE_GRILLE_STRENGTH) || !defined(APERTURE_GRILLE_PERIOD)
#undef APERTURE_GRILLE_STRENGTH
#undef APERTURE_GRILLE_PERIOD
#define APERTURE_GRILLE_STRENGTH 0.0
#define APERTURE_GRILLE_PERIOD 1.0
#endif
#if !defined(FLICKER_STRENGTH) || !defined(FLICKER_FREQUENCY)
#undef FLICKER_STRENGTH
#undef FLICKER_FREQUENCY
#define FLICKER_STRENGTH 0.0
#define FLICKER_FREQUENCY 1.0
#endif
#if !defined(NOISE_CONTENT_STRENGTH) || !defined(NOISE_UNIFORM_STRENGTH)
#undef NOISE_CONTENT_STRENGTH
#undef NOISE_UNIFORM_STRENGTH
#define NOISE_CONTENT_STRENGTH 0.0
#define NOISE_UNIFORM_STRENGTH 0.0
#endif
#if !defined(BLOOM_SPREAD) || !defined(BLOOM_STRENGTH)
#undef BLOOM_SPREAD
#undef BLOOM_STRENGTH
#define BLOOM_SPREAD 0.0
#define BLOOM_STRENGTH 0.0
#endif
#ifndef FADE_FACTOR
#define FADE_FACTOR 1.00
#endif
// Constants
#define PI 3.1415926535897932384626433832795
#ifdef BLOOM_SPREAD
// Golden spiral samples used for bloom.
// [x, y, weight] weight is inverse of distance.
const vec3[24] bloom_samples = {
vec3( 0.1693761725038636, 0.9855514761735895, 1),
vec3(-1.333070830962943, 0.4721463328627773, 0.7071067811865475),
vec3(-0.8464394909806497, -1.51113870578065, 0.5773502691896258),
vec3( 1.554155680728463, -1.2588090085709776, 0.5),
vec3( 1.681364377589461, 1.4741145918052656, 0.4472135954999579),
vec3(-1.2795157692199817, 2.088741103228784, 0.4082482904638631),
vec3(-2.4575847530631187, -0.9799373355024756, 0.3779644730092272),
vec3( 0.5874641440200847, -2.7667464429345077, 0.35355339059327373),
vec3( 2.997715703369726, 0.11704939884745152, 0.3333333333333333),
vec3( 0.41360842451688395, 3.1351121305574803, 0.31622776601683794),
vec3(-3.167149933769243, 0.9844599011770256, 0.30151134457776363),
vec3(-1.5736713846521535, -3.0860263079123245, 0.2886751345948129),
vec3( 2.888202648340422, -2.1583061557896213, 0.2773500981126146),
vec3( 2.7150778983300325, 2.5745586041105715, 0.2672612419124244),
vec3(-2.1504069972377464, 3.2211410627650165, 0.2581988897471611),
vec3(-3.6548858794907493, -1.6253643308191343, 0.25),
vec3( 1.0130775986052671, -3.9967078676335834, 0.24253562503633297),
vec3( 4.229723673607257, 0.33081361055181563, 0.23570226039551587),
vec3( 0.40107790291173834, 4.340407413572593, 0.22941573387056174),
vec3(-4.319124570236028, 1.159811599693438, 0.22360679774997896),
vec3(-1.9209044802827355, -4.160543952132907, 0.2182178902359924),
vec3( 3.8639122286635708, -2.6589814382925123, 0.21320071635561041),
vec3( 3.3486228404946234, 3.4331800232609, 0.20851441405707477),
vec3(-2.8769733643574344, 3.9652268864187157, 0.20412414523193154)
};
#endif
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// Get texture coordinates
vec2 uv = fragCoord.xy / iResolution.xy;
#ifdef CURVE
// Curve texture coordinates to mimic non-flat CRT monior
uv = (uv - 0.5) * 2.0;
uv.xy *= 1.0 + pow((abs(vec2(uv.y, uv.x)) / vec2(CURVE)), vec2(2.0));
uv = (uv / 2.0) + 0.5;
#endif
// Retrieve colors from appropriate locations
fragColor.r = texture(iChannel0, vec2(uv.x + 0.0003 * COLOR_FRINGING_SPREAD, uv.y + 0.0003 * COLOR_FRINGING_SPREAD)).x;
fragColor.g = texture(iChannel0, vec2(uv.x + 0.0000 * COLOR_FRINGING_SPREAD, uv.y - 0.0006 * COLOR_FRINGING_SPREAD)).y;
fragColor.b = texture(iChannel0, vec2(uv.x - 0.0006 * COLOR_FRINGING_SPREAD, uv.y + 0.0000 * COLOR_FRINGING_SPREAD)).z;
fragColor.a = texture(iChannel0, uv).a;
// Add faint ghost images
fragColor.r += 0.04 * GHOSTING_STRENGTH * texture(iChannel0, GHOSTING_SPREAD * vec2(+0.025, -0.027) + uv.xy).x;
fragColor.g += 0.02 * GHOSTING_STRENGTH * texture(iChannel0, GHOSTING_SPREAD * vec2(-0.022, -0.020) + uv.xy).y;
fragColor.b += 0.04 * GHOSTING_STRENGTH * texture(iChannel0, GHOSTING_SPREAD * vec2(-0.020, -0.018) + uv.xy).z;
// Quadratically darken everything
fragColor.rgb = mix(fragColor.rgb, fragColor.rgb*fragColor.rgb, DARKEN_MIX);
// Vignette effect
fragColor.rgb *= VIGNETTE_BRIGHTNESS * pow(uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y), VIGNETTE_SPREAD);
// Tint all colors
fragColor.rgb *= vec3(TINT);
// NOTE: At this point, RGB values may be above 1
// Add scan lines effect
fragColor.rgb *= mix(
1.0,
SCAN_LINES_VARIANCE/2.0*(1.0 + sin(2*PI* uv.y * iResolution.y/SCAN_LINES_PERIOD)),
SCAN_LINES_STRENGTH
);
// Add aperture grille
int aperture_grille_step = int(8 * mod(fragCoord.x, APERTURE_GRILLE_PERIOD) / APERTURE_GRILLE_PERIOD);
float aperture_grille_mask;
if (aperture_grille_step < 3)
aperture_grille_mask = 0.0;
else if (aperture_grille_step < 4)
aperture_grille_mask = mod(8*fragCoord.x, APERTURE_GRILLE_PERIOD) / APERTURE_GRILLE_PERIOD;
else if (aperture_grille_step < 7)
aperture_grille_mask = 1.0;
else if (aperture_grille_step < 8)
aperture_grille_mask = mod(-8*fragCoord.x, APERTURE_GRILLE_PERIOD) / APERTURE_GRILLE_PERIOD;
fragColor.rgb *= 1.0 - APERTURE_GRILLE_STRENGTH*aperture_grille_mask;
// Add flicker
fragColor *= 1.0 - FLICKER_STRENGTH/2.0*(1.0 + sin(2*PI*FLICKER_FREQUENCY*iTime));
// Add noise
// NOTE: Hard-coded noise distributions
float noiseContent = smoothstep(0.4, 0.6, fract(sin(uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y) * iTime * 4096.0) * 65536.0));
float noiseUniform = smoothstep(0.4, 0.6, fract(sin(uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y) * iTime * 8192.0) * 65536.0));
fragColor.rgb *= clamp(noiseContent + 1.0 - NOISE_CONTENT_STRENGTH, 0.0, 1.0);
fragColor.rgb = clamp(fragColor.rgb + noiseUniform * NOISE_UNIFORM_STRENGTH, 0.0, 1.0);
// NOTE: At this point, RGB values are again within [0, 1]
// Remove output outside of screen bounds
if (uv.x < 0.0 || uv.x > 1.0)
fragColor.rgb *= 0.0;
if (uv.y < 0.0 || uv.y > 1.0)
fragColor.rgb *= 0.0;
#ifdef BLOOM_SPREAD
// Add bloom
vec2 step = BLOOM_SPREAD * vec2(1.414) / iResolution.xy;
for (int i = 0; i < 24; i++) {
vec3 bloom_sample = bloom_samples[i];
vec4 neighbor = texture(iChannel0, uv + bloom_sample.xy * step);
float luminance = 0.299 * neighbor.r + 0.587 * neighbor.g + 0.114 * neighbor.b;
fragColor += luminance * bloom_sample.z * neighbor * BLOOM_STRENGTH;
}
fragColor = clamp(fragColor, 0.0, 1.0);
#endif
// Add fade effect to smoothen out color transitions
// NOTE: May need to be iTime/iTimeDelta dependent
fragColor = vec4(FADE_FACTOR*fragColor.rgb, FADE_FACTOR);
}

View File

@@ -0,0 +1,413 @@
/*
Feel free to do anything you want with this code.
This shader uses "runes" code by FabriceNeyret2 (https://www.shadertoy.com/view/4ltyDM)
which is based on "runes" by otaviogood (https://shadertoy.com/view/MsXSRn).
These random runes look good as matrix symbols and have acceptable performance.
@pkazmier modified this shader to work in Ghostty.
*/
const int ITERATIONS = 40; //use less value if you need more performance
const float SPEED = .5;
const float STRIP_CHARS_MIN = 7.;
const float STRIP_CHARS_MAX = 40.;
const float STRIP_CHAR_HEIGHT = 0.15;
const float STRIP_CHAR_WIDTH = 0.10;
const float ZCELL_SIZE = 1. * (STRIP_CHAR_HEIGHT * STRIP_CHARS_MAX); //the multiplier can't be less than 1.
const float XYCELL_SIZE = 12. * STRIP_CHAR_WIDTH; //the multiplier can't be less than 1.
const int BLOCK_SIZE = 10; //in cells
const int BLOCK_GAP = 2; //in cells
const float WALK_SPEED = 0.5 * XYCELL_SIZE;
const float BLOCKS_BEFORE_TURN = 3.;
const float PI = 3.14159265359;
// ---- random ----
float hash(float v) {
return fract(sin(v)*43758.5453123);
}
float hash(vec2 v) {
return hash(dot(v, vec2(5.3983, 5.4427)));
}
vec2 hash2(vec2 v)
{
v = vec2(v * mat2(127.1, 311.7, 269.5, 183.3));
return fract(sin(v)*43758.5453123);
}
vec4 hash4(vec2 v)
{
vec4 p = vec4(v * mat4x2( 127.1, 311.7,
269.5, 183.3,
113.5, 271.9,
246.1, 124.6 ));
return fract(sin(p)*43758.5453123);
}
vec4 hash4(vec3 v)
{
vec4 p = vec4(v * mat4x3( 127.1, 311.7, 74.7,
269.5, 183.3, 246.1,
113.5, 271.9, 124.6,
271.9, 269.5, 311.7 ) );
return fract(sin(p)*43758.5453123);
}
// ---- symbols ----
// Slightly modified version of "runes" by FabriceNeyret2 - https://www.shadertoy.com/view/4ltyDM
// Which is based on "runes" by otaviogood - https://shadertoy.com/view/MsXSRn
float rune_line(vec2 p, vec2 a, vec2 b) { // from https://www.shadertoy.com/view/4dcfW8
p -= a, b -= a;
float h = clamp(dot(p, b) / dot(b, b), 0., 1.); // proj coord on line
return length(p - b * h); // dist to segment
}
float rune(vec2 U, vec2 seed, float highlight)
{
float d = 1e5;
for (int i = 0; i < 4; i++) // number of strokes
{
vec4 pos = hash4(seed);
seed += 1.;
// each rune touches the edge of its box on all 4 sides
if (i == 0) pos.y = .0;
if (i == 1) pos.x = .999;
if (i == 2) pos.x = .0;
if (i == 3) pos.y = .999;
// snap the random line endpoints to a grid 2x3
vec4 snaps = vec4(2, 3, 2, 3);
pos = ( floor(pos * snaps) + .5) / snaps;
if (pos.xy != pos.zw) //filter out single points (when start and end are the same)
d = min(d, rune_line(U, pos.xy, pos.zw + .001) ); // closest line
}
return smoothstep(0.1, 0., d) + highlight*smoothstep(0.4, 0., d);
}
float random_char(vec2 outer, vec2 inner, float highlight) {
vec2 seed = vec2(dot(outer, vec2(269.5, 183.3)), dot(outer, vec2(113.5, 271.9)));
return rune(inner, seed, highlight);
}
// ---- digital rain ----
// xy - horizontal, z - vertical
vec3 rain(vec3 ro3, vec3 rd3, float time) {
vec4 result = vec4(0.);
// normalized 2d projection
vec2 ro2 = vec2(ro3);
vec2 rd2 = normalize(vec2(rd3));
// we use formulas `ro3 + rd3 * t3` and `ro2 + rd2 * t2`, `t3_to_t2` is a multiplier to convert t3 to t2
bool prefer_dx = abs(rd2.x) > abs(rd2.y);
float t3_to_t2 = prefer_dx ? rd3.x / rd2.x : rd3.y / rd2.y;
// at first, horizontal space (xy) is divided into cells (which are columns in 3D)
// then each xy-cell is divided into vertical cells (along z) - each of these cells contains one raindrop
ivec3 cell_side = ivec3(step(0., rd3)); //for positive rd.x use cell side with higher x (1) as the next side, for negative - with lower x (0), the same for y and z
ivec3 cell_shift = ivec3(sign(rd3)); //shift to move to the next cell
// move through xy-cells in the ray direction
float t2 = 0.; // the ray formula is: ro2 + rd2 * t2, where t2 is positive as the ray has a direction.
ivec2 next_cell = ivec2(floor(ro2/XYCELL_SIZE)); //first cell index where ray origin is located
for (int i=0; i<ITERATIONS; i++) {
ivec2 cell = next_cell; //save cell value before changing
float t2s = t2; //and t
// find the intersection with the nearest side of the current xy-cell (since we know the direction, we only need to check one vertical side and one horizontal side)
vec2 side = vec2(next_cell + cell_side.xy) * XYCELL_SIZE; //side.x is x coord of the y-axis side, side.y - y of the x-axis side
vec2 t2_side = (side - ro2) / rd2; // t2_side.x and t2_side.y are two candidates for the next value of t2, we need the nearest
if (t2_side.x < t2_side.y) {
t2 = t2_side.x;
next_cell.x += cell_shift.x; //cross through the y-axis side
} else {
t2 = t2_side.y;
next_cell.y += cell_shift.y; //cross through the x-axis side
}
//now t2 is the value of the end point in the current cell (and the same point is the start value in the next cell)
// gap cells
vec2 cell_in_block = fract(vec2(cell) / float(BLOCK_SIZE));
float gap = float(BLOCK_GAP) / float(BLOCK_SIZE);
if (cell_in_block.x < gap || cell_in_block.y < gap || (cell_in_block.x < (gap+0.1) && cell_in_block.y < (gap+0.1))) {
continue;
}
// return to 3d - we have start and end points of the ray segment inside the column (t3s and t3e)
float t3s = t2s / t3_to_t2;
// move through z-cells of the current column in the ray direction (don't need much to check, two nearest cells are enough)
float pos_z = ro3.z + rd3.z * t3s;
float xycell_hash = hash(vec2(cell));
float z_shift = xycell_hash*11. - time * (0.5 + xycell_hash * 1.0 + xycell_hash * xycell_hash * 1.0 + pow(xycell_hash, 16.) * 3.0); //a different z shift for each xy column
float char_z_shift = floor(z_shift / STRIP_CHAR_HEIGHT);
z_shift = char_z_shift * STRIP_CHAR_HEIGHT;
int zcell = int(floor((pos_z - z_shift)/ZCELL_SIZE)); //z-cell index
for (int j=0; j<2; j++) { //2 iterations is enough if camera doesn't look much up or down
// calcaulate coordinates of the target (raindrop)
vec4 cell_hash = hash4(vec3(ivec3(cell, zcell)));
vec4 cell_hash2 = fract(cell_hash * vec4(127.1, 311.7, 271.9, 124.6));
float chars_count = cell_hash.w * (STRIP_CHARS_MAX - STRIP_CHARS_MIN) + STRIP_CHARS_MIN;
float target_length = chars_count * STRIP_CHAR_HEIGHT;
float target_rad = STRIP_CHAR_WIDTH / 2.;
float target_z = (float(zcell)*ZCELL_SIZE + z_shift) + cell_hash.z * (ZCELL_SIZE - target_length);
vec2 target = vec2(cell) * XYCELL_SIZE + target_rad + cell_hash.xy * (XYCELL_SIZE - target_rad*2.);
// We have a line segment (t0,t). Now calculate the distance between line segment and cell target (it's easier in 2d)
vec2 s = target - ro2;
float tmin = dot(s, rd2); //tmin - point with minimal distance to target
if (tmin >= t2s && tmin <= t2) {
float u = s.x * rd2.y - s.y * rd2.x; //horizontal coord in the matrix strip
if (abs(u) < target_rad) {
u = (u/target_rad + 1.) / 2.;
float z = ro3.z + rd3.z * tmin/t3_to_t2;
float v = (z - target_z) / target_length; //vertical coord in the matrix strip
if (v >= 0.0 && v < 1.0) {
float c = floor(v * chars_count); //symbol index relative to the start of the strip, with addition of char_z_shift it becomes an index relative to the whole cell
float q = fract(v * chars_count);
vec2 char_hash = hash2(vec2(c+char_z_shift, cell_hash2.x));
if (char_hash.x >= 0.1 || c == 0.) { //10% of missed symbols
float time_factor = floor(c == 0. ? time*5.0 : //first symbol is changed fast
time*(1.0*cell_hash2.z + //strips are changed sometime with different speed
cell_hash2.w*cell_hash2.w*4.*pow(char_hash.y, 4.))); //some symbols in some strips are changed relatively often
float a = random_char(vec2(char_hash.x, time_factor), vec2(u,q), max(1., 3. - c/2.)*0.2); //alpha
a *= clamp((chars_count - 0.5 - c) / 2., 0., 1.); //tail fade
if (a > 0.) {
float attenuation = 1. + pow(0.06*tmin/t3_to_t2, 2.);
vec3 col = (c == 0. ? vec3(0.67, 1.0, 0.82) : vec3(0.25, 0.80, 0.40)) / attenuation;
float a1 = result.a;
result.a = a1 + (1. - a1) * a;
result.xyz = (result.xyz * a1 + col * (1. - a1) * a) / result.a;
if (result.a > 0.98) return result.xyz;
}
}
}
}
}
// not found in this cell - go to next vertical cell
zcell += cell_shift.z;
}
// go to next horizontal cell
}
return result.xyz * result.a;
}
// ---- main, camera ----
vec2 rotate(vec2 v, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return m * v;
}
vec3 rotateX(vec3 v, float a) {
float s = sin(a);
float c = cos(a);
return mat3(1.,0.,0.,0.,c,-s,0.,s,c) * v;
}
vec3 rotateY(vec3 v, float a) {
float s = sin(a);
float c = cos(a);
return mat3(c,0.,-s,0.,1.,0.,s,0.,c) * v;
}
vec3 rotateZ(vec3 v, float a) {
float s = sin(a);
float c = cos(a);
return mat3(c,-s,0.,s,c,0.,0.,0.,1.) * v;
}
float smoothstep1(float x) {
return smoothstep(0., 1., x);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
if (STRIP_CHAR_WIDTH > XYCELL_SIZE || STRIP_CHAR_HEIGHT * STRIP_CHARS_MAX > ZCELL_SIZE) {
// error
fragColor = vec4(1., 0., 0., 1.);
return;
}
vec2 uv = fragCoord.xy / iResolution.xy;
float time = iTime * SPEED;
const float turn_rad = 0.25 / BLOCKS_BEFORE_TURN; //0 .. 0.5
const float turn_abs_time = (PI/2.*turn_rad) * 1.5; //multiplier different than 1 means a slow down on turns
const float turn_time = turn_abs_time / (1. - 2.*turn_rad + turn_abs_time); //0..1, but should be <= 0.5
float level1_size = float(BLOCK_SIZE) * BLOCKS_BEFORE_TURN * XYCELL_SIZE;
float level2_size = 4. * level1_size;
float gap_size = float(BLOCK_GAP) * XYCELL_SIZE;
vec3 ro = vec3(gap_size/2., gap_size/2., 0.);
vec3 rd = vec3(uv.x, 2.0, uv.y);
float tq = fract(time / (level2_size*4.) * WALK_SPEED); //the whole cycle time counter
float t8 = fract(tq*4.); //time counter while walking on one of the four big sides
float t1 = fract(t8*8.); //time counter while walking on one of the eight sides of the big side
vec2 prev;
vec2 dir;
if (tq < 0.25) {
prev = vec2(0.,0.);
dir = vec2(0.,1.);
} else if (tq < 0.5) {
prev = vec2(0.,1.);
dir = vec2(1.,0.);
} else if (tq < 0.75) {
prev = vec2(1.,1.);
dir = vec2(0.,-1.);
} else {
prev = vec2(1.,0.);
dir = vec2(-1.,0.);
}
float angle = floor(tq * 4.); //0..4 wich means 0..2*PI
prev *= 4.;
const float first_turn_look_angle = 0.4;
const float second_turn_drift_angle = 0.5;
const float fifth_turn_drift_angle = 0.25;
vec2 turn;
float turn_sign = 0.;
vec2 dirL = rotate(dir, -PI/2.);
vec2 dirR = -dirL;
float up_down = 0.;
float rotate_on_turns = 1.;
float roll_on_turns = 1.;
float add_angel = 0.;
if (t8 < 0.125) {
turn = dirL;
//dir = dir;
turn_sign = -1.;
angle -= first_turn_look_angle * (max(0., t1 - (1. - turn_time*2.)) / turn_time - max(0., t1 - (1. - turn_time)) / turn_time * 2.5);
roll_on_turns = 0.;
} else if (t8 < 0.250) {
prev += dir;
turn = dir;
dir = dirL;
angle -= 1.;
turn_sign = 1.;
add_angel += first_turn_look_angle*0.5 + (-first_turn_look_angle*0.5+1.0+second_turn_drift_angle)*t1;
rotate_on_turns = 0.;
roll_on_turns = 0.;
} else if (t8 < 0.375) {
prev += dir + dirL;
turn = dirR;
//dir = dir;
turn_sign = 1.;
add_angel += second_turn_drift_angle*sqrt(1.-t1);
//roll_on_turns = 0.;
} else if (t8 < 0.5) {
prev += dir + dir + dirL;
turn = dirR;
dir = dirR;
angle += 1.;
turn_sign = 0.;
up_down = sin(t1*PI) * 0.37;
} else if (t8 < 0.625) {
prev += dir + dir;
turn = dir;
dir = dirR;
angle += 1.;
turn_sign = -1.;
up_down = sin(-min(1., t1/(1.-turn_time))*PI) * 0.37;
} else if (t8 < 0.750) {
prev += dir + dir + dirR;
turn = dirL;
//dir = dir;
turn_sign = -1.;
add_angel -= (fifth_turn_drift_angle + 1.) * smoothstep1(t1);
rotate_on_turns = 0.;
roll_on_turns = 0.;
} else if (t8 < 0.875) {
prev += dir + dir + dir + dirR;
turn = dir;
dir = dirL;
angle -= 1.;
turn_sign = 1.;
add_angel -= fifth_turn_drift_angle - smoothstep1(t1) * (fifth_turn_drift_angle * 2. + 1.);
rotate_on_turns = 0.;
roll_on_turns = 0.;
} else {
prev += dir + dir + dir;
turn = dirR;
//dir = dir;
turn_sign = 1.;
angle += fifth_turn_drift_angle * (1.5*min(1., (1.-t1)/turn_time) - 0.5*smoothstep1(1. - min(1.,t1/(1.-turn_time))));
}
if (iMouse.x > 10. || iMouse.y > 10.) {
vec2 mouse = iMouse.xy / iResolution.xy * 2. - 1.;
up_down = -0.7 * mouse.y;
angle += mouse.x;
rotate_on_turns = 1.;
roll_on_turns = 0.;
} else {
angle += add_angel;
}
rd = rotateX(rd, up_down);
vec2 p;
if (turn_sign == 0.) {
// move forward
p = prev + dir * (turn_rad + 1. * t1);
}
else if (t1 > (1. - turn_time)) {
// turn
float tr = (t1 - (1. - turn_time)) / turn_time;
vec2 c = prev + dir * (1. - turn_rad) + turn * turn_rad;
p = c + turn_rad * rotate(dir, (tr - 1.) * turn_sign * PI/2.);
angle += tr * turn_sign * rotate_on_turns;
rd = rotateY(rd, sin(tr*turn_sign*PI) * 0.2 * roll_on_turns); //roll
} else {
// move forward
t1 /= (1. - turn_time);
p = prev + dir * (turn_rad + (1. - turn_rad*2.) * t1);
}
rd = rotateZ(rd, angle * PI/2.);
ro.xy += level1_size * p;
ro += rd * 0.2;
rd = normalize(rd);
// vec3 col = rain(ro, rd, time);
vec3 col = rain(ro, rd, time) * 0.25;
// Sample the terminal screen texture including alpha channel
vec4 terminalColor = texture(iChannel0, uv);
// Combine the matrix effect with the terminal color
// vec3 blendedColor = terminalColor.rgb + col;
// Make a mask that is 1.0 where the terminal content is not black
float mask = 1.2 - step(0.5, dot(terminalColor.rgb, vec3(1.0)));
vec3 blendedColor = mix(terminalColor.rgb * 1.2, col, mask);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2013 Andrew Baldwin (twitter: baldand, www: http://thndl.com)
// License = Attribution-NonCommercial-ShareAlike (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US)
// "Just snow"
// Simple (but not cheap) snow made from multiple parallax layers with randomly positioned
// flakes and directions. Also includes a DoF effect. Pan around with mouse.
#define LIGHT_SNOW // Comment this out for a blizzard
#ifdef LIGHT_SNOW
#define LAYERS 50
#define DEPTH .5
#define WIDTH .3
#define SPEED .6
#else // BLIZZARD
#define LAYERS 200
#define DEPTH .1
#define WIDTH .8
#define SPEED 1.5
#endif
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
const mat3 p = mat3(13.323122,23.5112,21.71123,21.1212,28.7312,11.9312,21.8112,14.7212,61.3934);
vec2 uv = fragCoord.xy / iResolution.xy;
vec3 acc = vec3(0.0);
float dof = 5.0 * sin(iTime * 0.1);
for (int i = 0; i < LAYERS; i++) {
float fi = float(i);
vec2 q =-uv*(1.0 + fi * DEPTH);
q += vec2(q.y * (WIDTH * mod(fi * 7.238917, 1.0) - WIDTH * 0.5), -SPEED * iTime / (1.0 + fi * DEPTH * 0.03));
vec3 n = vec3(floor(q), 31.189 + fi);
vec3 m = floor(n) * 0.00001 + fract(n);
vec3 mp = (31415.9 + m) / fract(p * m);
vec3 r = fract(mp);
vec2 s = abs(mod(q, 1.0) - 0.5 + 0.9 * r.xy - 0.45);
s += 0.01 * abs(2.0 * fract(10.0 * q.yx) - 1.0);
float d = 0.6 * max(s.x - s.y, s.x + s.y) + max(s.x, s.y) - 0.01;
float edge = 0.005 + 0.05 * min(0.5 * abs(fi - 5.0 - dof), 1.0);
acc += vec3(smoothstep(edge, -edge, d) * (r.x / (1.0 + 0.02 * fi * DEPTH)));
}
// Sample the terminal screen texture including alpha channel
vec4 terminalColor = texture(iChannel0, uv);
// Combine the snow effect with the terminal color
vec3 blendedColor = terminalColor.rgb + acc;
// Use the terminal's original alpha
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,40 @@
// based on the following Shader Toy entry
//
// [SH17A] Matrix rain. Created by Reinder Nijhoff 2017
// Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
// @reindernijhoff
//
// https://www.shadertoy.com/view/ldjBW1
//
#define SPEED_MULTIPLIER 1.
#define GREEN_ALPHA .33
#define BLACK_BLEND_THRESHOLD .4
#define R fract(1e2 * sin(p.x * 8. + p.y))
void mainImage(out vec4 fragColor, vec2 fragCoord) {
vec3 v = vec3(fragCoord, 1) / iResolution - .5;
// vec3 s = .5 / abs(v);
// scale?
vec3 s = .9 / abs(v);
s.z = min(s.y, s.x);
vec3 i = ceil( 8e2 * s.z * ( s.y < s.x ? v.xzz : v.zyz ) ) * .1;
vec3 j = fract(i);
i -= j;
vec3 p = vec3(9, int(iTime * SPEED_MULTIPLIER * (9. + 8. * sin(i).x)), 0) + i;
vec3 col = fragColor.rgb;
col.g = R / s.z;
p *= j;
col *= (R >.5 && j.x < .6 && j.y < .8) ? GREEN_ALPHA : 0.;
// Sample the terminal screen texture including alpha channel
vec2 uv = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, uv);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb * 1.2, col, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

119
ghostty/shaders/mnoise.glsl Normal file
View File

@@ -0,0 +1,119 @@
vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec4 permute(vec4 x) { return mod289(((x * 34.0) + 10.0) * x); }
vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
float snoise(vec3 v) {
const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy));
vec3 x0 = v - i + dot(i, C.xxx);
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min(g.xyz, l.zxy);
vec3 i2 = max(g.xyz, l.zxy);
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y +
vec4(0.0, i1.y, i2.y, 1.0)) +
i.x + vec4(0.0, i1.x, i2.x, 1.0));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
vec4 x = x_ * ns.x + ns.yyyy;
vec4 y = y_ * ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4(x.xy, y.xy);
vec4 b1 = vec4(x.zw, y.zw);
// vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
// vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0) * 2.0 + 1.0;
vec4 s1 = floor(b1) * 2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
vec3 p0 = vec3(a0.xy, h.x);
vec3 p1 = vec3(a0.zw, h.y);
vec3 p2 = vec3(a1.xy, h.z);
vec3 p3 = vec3(a1.zw, h.w);
// Normalise gradients
vec4 norm =
taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m =
max(0.5 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
m = m * m;
return 105.0 *
dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}
float noise2D(vec2 uv) {
uvec2 pos = uvec2(floor(uv * 1000.));
return float((pos.x * 68657387u ^ pos.y * 361524851u + pos.x) % 890129u) *
(1.0 / 890128.0);
}
float roundRectSDF(vec2 center, vec2 size, float radius) {
return length(max(abs(center) - size + radius, 0.)) - radius;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord / iResolution.xy, sd = vec2(2.), sdh = vec2(1.);
vec4 ghosttyCol = texture(iChannel0, uv);
float ratio = iResolution.y / iResolution.x,
fw = max(fwidth(uv.x), fwidth(uv.y));
vec2 puv = floor(uv * vec2(60., 60. * ratio)) / 60.;
puv +=
(smoothstep(0., 0.7, noise2D(puv)) - 0.5) * 0.05 - vec2(0., iTime * 0.08);
uv = fract(vec2(uv.x, uv.y * ratio) * 10.);
float d = roundRectSDF((sd + 0.01) * (uv - .5), sdh, 0.075),
d2 = roundRectSDF((sd + 0.065) * (fract(uv * 6.) - .5), sdh, 0.2),
noiseTime = iTime * 0.03, noise = snoise(vec3(puv, noiseTime));
noise += snoise(vec3(puv * 1.1, noiseTime + 0.5)) + .1;
noise += snoise(vec3(puv * 2., noiseTime + 0.8));
noise = pow(noise, 2.);
vec3 col1 = vec3(0.), col2 = vec3(0.), col3 = vec3(0.07898),
col4 = vec3(0.089184),
fcol = mix(mix(mix(col1, col3, smoothstep(0.0, 0.3, noise)), col2,
smoothstep(0.0, 0.5, noise)),
col4, smoothstep(0.0, 1.0, noise));
fragColor = vec4(
ghosttyCol.rgb +
mix(col4, fcol, smoothstep(fw, -fw, d) * smoothstep(fw, -fw, d2)),
ghosttyCol.a);
}

View File

@@ -0,0 +1,8 @@
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
vec4 color = texture(iChannel0, uv);
fragColor = vec4(1.0 - color.x, 1.0 - color.y, 1.0 - color.z, color.w);
}

View File

@@ -0,0 +1,34 @@
// Original shader collected from: https://www.shadertoy.com/view/WsVSzV
// Licensed under Shadertoy's default since the original creator didn't provide any license. (CC BY NC SA 3.0)
// Slight modifications were made to give a green-ish effect.
float warp = 0.25; // simulate curvature of CRT monitor
float scan = 0.50; // simulate darkness between scanlines
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// squared distance from center
vec2 uv = fragCoord / iResolution.xy;
vec2 dc = abs(0.5 - uv);
dc *= dc;
// warp the fragment coordinates
uv.x -= 0.5; uv.x *= 1.0 + (dc.y * (0.3 * warp)); uv.x += 0.5;
uv.y -= 0.5; uv.y *= 1.0 + (dc.x * (0.4 * warp)); uv.y += 0.5;
// sample inside boundaries, otherwise set to black
if (uv.y > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0)
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
else
{
// determine if we are drawing in a scanline
float apply = abs(sin(fragCoord.y) * 0.5 * scan);
// sample the texture and apply a teal tint
vec3 color = texture(iChannel0, uv).rgb;
vec3 tealTint = vec3(0.0, 0.8, 0.6); // teal color (slightly more green than blue)
// mix the sampled color with the teal tint based on scanline intensity
fragColor = vec4(mix(color * tealTint, vec3(0.0), apply), 1.0);
}
}

View File

@@ -0,0 +1,28 @@
// Based on https://www.shadertoy.com/view/ms3cWn
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
float d = length(uv - 0.5) * 2.0;
float t = d * d * 25.0 - iTime * 2.0;
vec3 col = 0.5 + 0.5 * cos(t / 20.0 + uv.xyx + vec3(0.0,2.0,4.0));
vec2 center = iResolution.xy * 0.5;
float distCentre = distance(fragCoord.xy, center);
float dCSin = sin(distCentre * 0.05);
vec2 anim = vec2(map(sin(iTime),-1.0,1.0,0.0,iResolution.x),map(sin(iTime*1.25),-1.0,1.0,0.0,iResolution.y));
float distMouse = distance(fragCoord.xy, anim);
float dMSin = sin(distMouse * 0.05);
float greycol = (((dMSin * dCSin) + 1.0) * 0.5);
greycol = greycol * map(d, 0.0, 1.4142135623730951, 0.5, 0.0);
vec4 terminalColor = texture(iChannel0, uv);
vec3 blendedColor = mix(terminalColor.rgb, vec3(greycol * col.x, greycol * col.y, greycol * col.z), 0.25);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,193 @@
// Settings for detection
#define TARGET_COLOR vec3(0.0, 0.0, 0.0) // RGB target pixels to transform
#define REPLACE_COLOR vec3(0.0, 0.0, 0.0) // Color to replace target pixels
#define COLOR_TOLERANCE 0.001 // Color matching tolerance
// Smoke effect settings
#define SMOKE_COLOR vec3(1., 1., 1.0) // Base color of smoke
#define SMOKE_RADIUS 0.011 // How far the smoke spreads
#define SMOKE_SPEED 0.5 // Speed of smoke movement
#define SMOKE_SCALE 25.0 // Scale of smoke detail
#define SMOKE_INTENSITY 0.2 // Intensity of the smoke effect
#define SMOKE_RISE_HEIGHT 0.14 // How high the smoke rises
#define ALPHA_MAX 0.5 // Maximum opacity for smoke
#define VERTICAL_BIAS 1.0
// Ghost face settings
#define FACE_COUNT 1 // Number of ghost faces
#define FACE_SCALE vec2(0.03, 0.05) // Size of faces, can be wider/elongated
#define FACE_DURATION 1.2 // How long faces last, can be wider/elongated
#define FACE_TRANSITION 1.5 // Face fade in/out duration
#define FACE_COLOR vec3(0.0, 0.0, 0.0)
#define GHOST_BG_COLOR vec3(1.0, 1.0, 1.0)
#define GHOST_BG_SCALE vec2(0.03, 0.06)
float random(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}
float random1(float n) {
return fract(sin(n) * 43758.5453123);
}
vec2 random2(float n) {
return vec2(
random1(n),
random1(n + 1234.5678)
);
}
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}
// Modified elongated ellipse for more cartoon-like shapes
float cartoonEllipse(vec2 uv, vec2 center, vec2 scale) {
vec2 d = (uv - center) / scale;
float len = length(d);
// Add cartoon-like falloff
return smoothstep(1.0, 0.8, len);
}
// Function to create ghost background shape
float ghostBackground(vec2 uv, vec2 center) {
vec2 d = (uv - center) / GHOST_BG_SCALE;
float baseShape = length(d * vec2(1.0, 0.8)); // Slightly oval
// Add wavy bottom
float wave = sin(d.x * 6.28 + iTime) * 0.2;
float bottomWave = smoothstep(0.0, -0.5, d.y + wave);
return smoothstep(1.0, 0.8, baseShape) + bottomWave;
}
float ghostFace(vec2 uv, vec2 center, float time, float seed) {
vec2 faceUV = (uv - center) / FACE_SCALE;
float eyeSize = 0.25 + random1(seed) * 0.05;
float eyeSpacing = 0.35;
vec2 leftEyePos = vec2(-eyeSpacing, 0.2);
vec2 rightEyePos = vec2(eyeSpacing, 0.2);
float leftEye = cartoonEllipse(faceUV, leftEyePos, vec2(eyeSize));
float rightEye = cartoonEllipse(faceUV, rightEyePos, vec2(eyeSize));
// Add simple eye highlights
float leftHighlight = cartoonEllipse(faceUV, leftEyePos + vec2(0.1, 0.1), vec2(eyeSize * 0.3));
float rightHighlight = cartoonEllipse(faceUV, rightEyePos + vec2(0.1, 0.1), vec2(eyeSize * 0.3));
vec2 mouthUV = faceUV - vec2(0.0, -0.9);
float mouthWidth = 0.5 + random1(seed + 3.0) * 0.1;
float mouthHeight = 0.8 + random1(seed + 7.0) * 0.1;
float mouth = cartoonEllipse(mouthUV, vec2(0.0), vec2(mouthWidth, mouthHeight));
// Combine features
float face = max(max(leftEye, rightEye), mouth);
face = max(face, max(leftHighlight, rightHighlight));
// Add border falloff
face *= smoothstep(1.2, 0.8, length(faceUV));
return face;
}
float calculateSmoke(vec2 uv, vec2 sourcePos) {
float verticalDisp = (uv.y - sourcePos.y) * VERTICAL_BIAS;
vec2 smokeUV = uv * SMOKE_SCALE;
smokeUV.y -= iTime * SMOKE_SPEED * (1.0 + verticalDisp);
smokeUV.x += sin(iTime * 0.5 + uv.y * 4.0) * 0.1;
float n = noise(smokeUV) * 0.5 + 0.5;
n += noise(smokeUV * 2.0 + iTime * 0.1) * 0.25;
float verticalFalloff = 1.0 - smoothstep(0.0, SMOKE_RISE_HEIGHT, verticalDisp);
return n * verticalFalloff;
}
float isTargetPixel(vec2 uv) {
vec4 color = texture(iChannel0, uv);
return float(all(lessThan(abs(color.rgb - TARGET_COLOR), vec3(COLOR_TOLERANCE))));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord/iResolution.xy;
vec4 originalColor = texture(iChannel0, uv);
// Calculate smoke effect
float smokeAccum = 0.0;
float targetInfluence = 0.0;
float stepSize = SMOKE_RADIUS / 4.0;
for (float x = -SMOKE_RADIUS; x <= SMOKE_RADIUS; x += stepSize) {
for (float y = -SMOKE_RADIUS; y <= 0.0; y += stepSize) {
vec2 offset = vec2(x, y);
vec2 sampleUV = uv + offset;
if (sampleUV.x >= 0.0 && sampleUV.x <= 1.0 &&
sampleUV.y >= 0.0 && sampleUV.y <= 1.0) {
float isTarget = isTargetPixel(sampleUV);
if (isTarget > 0.0) {
float dist = length(offset);
float falloff = 1.0 - smoothstep(0.0, SMOKE_RADIUS, dist);
float smoke = calculateSmoke(uv, sampleUV);
smokeAccum += smoke * falloff;
targetInfluence += falloff;
}
}
}
}
smokeAccum /= max(targetInfluence, 1.0);
targetInfluence = smoothstep(0.0, 1.0, targetInfluence);
float smokePresence = smokeAccum * targetInfluence;
// Calculate ghost faces with backgrounds
float faceAccum = 0.0;
float bgAccum = 0.0;
float timeBlock = floor(iTime / FACE_DURATION);
if (smokePresence > 0.2) {
for (int i = 0; i < FACE_COUNT; i++) {
vec2 facePos = random2(timeBlock + float(i) * 1234.5);
facePos = facePos * 0.8 + 0.1;
float faceTime = mod(iTime, FACE_DURATION);
float fadeFactor = smoothstep(0.0, FACE_TRANSITION, faceTime) *
(1.0 - smoothstep(FACE_DURATION - FACE_TRANSITION, FACE_DURATION, faceTime));
// Add ghost background
float ghostBg = ghostBackground(uv, facePos) * fadeFactor;
bgAccum = max(bgAccum, ghostBg);
// Add face features
float face = ghostFace(uv, facePos, iTime, timeBlock + float(i) * 100.0) * fadeFactor;
faceAccum = max(faceAccum, face);
}
bgAccum *= smoothstep(0.2, 0.4, smokePresence);
faceAccum *= smoothstep(0.2, 0.4, smokePresence);
}
// Combine all elements
bool isTarget = all(lessThan(abs(originalColor.rgb - TARGET_COLOR), vec3(COLOR_TOLERANCE)));
vec3 baseColor = isTarget ? REPLACE_COLOR : originalColor.rgb;
// Layer the effects: base -> smoke -> ghost background -> face features
vec3 smokeEffect = mix(baseColor, SMOKE_COLOR, smokeAccum * SMOKE_INTENSITY * targetInfluence * (1.0 - faceAccum));
vec3 withBackground = mix(smokeEffect, GHOST_BG_COLOR, bgAccum * 0.7);
vec3 finalColor = mix(withBackground, FACE_COLOR, faceAccum);
float alpha = mix(originalColor.a, ALPHA_MAX, max(smokePresence, max(bgAccum, faceAccum) * smokePresence));
fragColor = vec4(finalColor, alpha);
}

View File

@@ -0,0 +1,242 @@
// adapted by Alex Sherwin for Ghstty from https://www.shadertoy.com/view/wl2Gzc
//Shader License: CC BY 3.0
//Author: Jan Mróz (jaszunio15)
#define SMOKE_INTENSITY_MULTIPLIER 0.9
#define PARTICLES_ALPHA_MOD 0.9
#define SMOKE_ALPHA_MOD 0.5
#define LAYERS_COUNT 8
#define BLACK_BLEND_THRESHOLD .4
#define VEC3_1 (vec3(1.0))
#define PI 3.1415927
#define TWO_PI 6.283185
#define ANIMATION_SPEED 1.0
#define MOVEMENT_SPEED .33
#define MOVEMENT_DIRECTION vec2(0.7, 1.0)
#define PARTICLE_SIZE 0.0025
#define PARTICLE_SCALE (vec2(0.5, 1.6))
#define PARTICLE_SCALE_VAR (vec2(0.25, 0.2))
#define PARTICLE_BLOOM_SCALE (vec2(0.5, 0.8))
#define PARTICLE_BLOOM_SCALE_VAR (vec2(0.3, 0.1))
#define SPARK_COLOR vec3(1.0, 0.4, 0.05) * 1.5
#define BLOOM_COLOR vec3(1.0, 0.4, 0.05) * 0.8
#define SMOKE_COLOR vec3(1.0, 0.43, 0.1) * 0.8
#define SIZE_MOD 1.05
float hash1_2(in vec2 x)
{
return fract(sin(dot(x, vec2(52.127, 61.2871))) * 521.582);
}
vec2 hash2_2(in vec2 x)
{
return fract(sin(x * mat2x2(20.52, 24.1994, 70.291, 80.171)) * 492.194);
}
//Simple interpolated noise
vec2 noise2_2(vec2 uv)
{
//vec2 f = fract(uv);
vec2 f = smoothstep(0.0, 1.0, fract(uv));
vec2 uv00 = floor(uv);
vec2 uv01 = uv00 + vec2(0,1);
vec2 uv10 = uv00 + vec2(1,0);
vec2 uv11 = uv00 + 1.0;
vec2 v00 = hash2_2(uv00);
vec2 v01 = hash2_2(uv01);
vec2 v10 = hash2_2(uv10);
vec2 v11 = hash2_2(uv11);
vec2 v0 = mix(v00, v01, f.y);
vec2 v1 = mix(v10, v11, f.y);
vec2 v = mix(v0, v1, f.x);
return v;
}
//Simple interpolated noise
float noise1_2(in vec2 uv)
{
// vec2 f = fract(uv);
vec2 f = smoothstep(0.0, 1.0, fract(uv));
vec2 uv00 = floor(uv);
vec2 uv01 = uv00 + vec2(0,1);
vec2 uv10 = uv00 + vec2(1,0);
vec2 uv11 = uv00 + 1.0;
float v00 = hash1_2(uv00);
float v01 = hash1_2(uv01);
float v10 = hash1_2(uv10);
float v11 = hash1_2(uv11);
float v0 = mix(v00, v01, f.y);
float v1 = mix(v10, v11, f.y);
float v = mix(v0, v1, f.x);
return v;
}
float layeredNoise1_2(in vec2 uv, in float sizeMod, in float alphaMod, in int layers, in float animation)
{
float noise = 0.0;
float alpha = 1.0;
float size = 1.0;
vec2 offset;
for (int i = 0; i < layers; i++)
{
offset += hash2_2(vec2(alpha, size)) * 10.0;
//Adding noise with movement
noise += noise1_2(uv * size + iTime * animation * 8.0 * MOVEMENT_DIRECTION * MOVEMENT_SPEED + offset) * alpha;
alpha *= alphaMod;
size *= sizeMod;
}
noise *= (1.0 - alphaMod)/(1.0 - pow(alphaMod, float(layers)));
return noise;
}
//Rotates point around 0,0
vec2 rotate(in vec2 point, in float deg)
{
float s = sin(deg);
float c = cos(deg);
return mat2x2(s, c, -c, s) * point;
}
//Cell center from point on the grid
vec2 voronoiPointFromRoot(in vec2 root, in float deg)
{
vec2 point = hash2_2(root) - 0.5;
float s = sin(deg);
float c = cos(deg);
point = mat2x2(s, c, -c, s) * point * 0.66;
point += root + 0.5;
return point;
}
//Voronoi cell point rotation degrees
float degFromRootUV(in vec2 uv)
{
return iTime * ANIMATION_SPEED * (hash1_2(uv) - 0.5) * 2.0;
}
vec2 randomAround2_2(in vec2 point, in vec2 range, in vec2 uv)
{
return point + (hash2_2(uv) - 0.5) * range;
}
vec3 fireParticles(in vec2 uv, in vec2 originalUV)
{
vec3 particles = vec3(0.0);
vec2 rootUV = floor(uv);
float deg = degFromRootUV(rootUV);
vec2 pointUV = voronoiPointFromRoot(rootUV, deg);
float dist = 2.0;
float distBloom = 0.0;
//UV manipulation for the faster particle movement
vec2 tempUV = uv + (noise2_2(uv * 2.0) - 0.5) * 0.1;
tempUV += -(noise2_2(uv * 3.0 + iTime) - 0.5) * 0.07;
//Sparks sdf
dist = length(rotate(tempUV - pointUV, 0.7) * randomAround2_2(PARTICLE_SCALE, PARTICLE_SCALE_VAR, rootUV));
//Bloom sdf
distBloom = length(rotate(tempUV - pointUV, 0.7) * randomAround2_2(PARTICLE_BLOOM_SCALE, PARTICLE_BLOOM_SCALE_VAR, rootUV));
//Add sparks
particles += (1.0 - smoothstep(PARTICLE_SIZE * 0.6, PARTICLE_SIZE * 3.0, dist)) * SPARK_COLOR;
//Add bloom
particles += pow((1.0 - smoothstep(0.0, PARTICLE_SIZE * 6.0, distBloom)) * 1.0, 3.0) * BLOOM_COLOR;
//Upper disappear curve randomization
float border = (hash1_2(rootUV) - 0.5) * 2.0;
float disappear = 1.0 - smoothstep(border, border + 0.5, originalUV.y);
//Lower appear curve randomization
border = (hash1_2(rootUV + 0.214) - 1.8) * 0.7;
float appear = smoothstep(border, border + 0.4, originalUV.y);
return particles * disappear * appear;
}
//Layering particles to imitate 3D view
vec3 layeredParticles(in vec2 uv, in float sizeMod, in float alphaMod, in int layers, in float smoke)
{
vec3 particles = vec3(0);
float size = 1.0;
// float alpha = 1.0;
float alpha = 1.0;
vec2 offset = vec2(0.0);
vec2 noiseOffset;
vec2 bokehUV;
for (int i = 0; i < layers; i++)
{
//Particle noise movement
noiseOffset = (noise2_2(uv * size * 2.0 + 0.5) - 0.5) * 0.15;
//UV with applied movement
bokehUV = (uv * size + iTime * MOVEMENT_DIRECTION * MOVEMENT_SPEED) + offset + noiseOffset;
//Adding particles if there is more smoke, remove smaller particles
particles += fireParticles(bokehUV, uv) * alpha * (1.0 - smoothstep(0.0, 1.0, smoke) * (float(i) / float(layers)));
//Moving uv origin to avoid generating the same particles
offset += hash2_2(vec2(alpha, alpha)) * 10.0;
alpha *= alphaMod;
size *= sizeMod;
}
return particles;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.x;
// float vignette = 1.1 - smoothstep(0.4, 1.4, length(uv + vec2(0.0, 0.3)));
float vignette = 1.3 - smoothstep(0.4, 1.4, length(uv + vec2(0.0, 0.3)));
uv *= 2.5;
float smokeIntensity = layeredNoise1_2(uv * 10.0 + iTime * 4.0 * MOVEMENT_DIRECTION * MOVEMENT_SPEED, 1.7, 0.7, 6, 0.2);
smokeIntensity *= pow(smoothstep(-1.0, 1.6, uv.y), 2.0);
vec3 smoke = smokeIntensity * SMOKE_COLOR * vignette * SMOKE_INTENSITY_MULTIPLIER * SMOKE_ALPHA_MOD;
//Cutting holes in smoke
smoke *= pow(layeredNoise1_2(uv * 4.0 + iTime * 0.5 * MOVEMENT_DIRECTION * MOVEMENT_SPEED, 1.8, 0.5, 3, 0.2), 2.0) * 1.5;
vec3 particles = layeredParticles(uv, SIZE_MOD, PARTICLES_ALPHA_MOD, LAYERS_COUNT, smokeIntensity);
vec3 col = particles + smoke + SMOKE_COLOR * 0.02;
col *= vignette;
col = smoothstep(-0.08, 1.0, col);
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb, col, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,42 @@
// Created by Paul Robello
// Smooth oscillating function that varies over time
float smoothOscillation(float t, float frequency, float phase) {
return sin(t * frequency + phase);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// Resolution and UV coordinates
vec2 uv = fragCoord.xy / iResolution.xy;
// Used to fix distortion when calculating distance to circle center
vec2 ratio = vec2(iResolution.x / iResolution.y, 1.0);
// Get the texture from iChannel0
vec4 texColor = texture(iChannel0, uv);
// Spotlight center moving based on a smooth random pattern
float time = iTime * 1.0; // Control speed of motion
vec2 spotlightCenter = vec2(
0.5 + 0.4 * smoothOscillation(time, 1.0, 0.0), // Smooth X motion
0.5 + 0.4 * smoothOscillation(time, 1.3, 3.14159) // Smooth Y motion with different frequency and phase
);
// Distance from the spotlight center
float distanceToCenter = distance(uv * ratio, spotlightCenter);
// Spotlight intensity based on distance
float spotlightRadius = 0.25; // Spotlight radius
float softness = 20.0; // Spotlight edge softness. Higher values have sharper edge
float spotlightIntensity = smoothstep(spotlightRadius, spotlightRadius - (1.0 / softness), distanceToCenter);
// Ambient light level
float ambientLight = 0.5; // Controls the minimum brightness across the texture
// Combine the spotlight effect with the texture
vec3 spotlightEffect = texColor.rgb * mix(vec3(ambientLight), vec3(1.0), spotlightIntensity);
// Final color output
fragColor = vec4(spotlightEffect, texColor.a);
}

View File

@@ -0,0 +1,158 @@
// transparent background
const bool transparent = false;
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
const float threshold = 0.15;
// divisions of grid
const float repeats = 30.;
// number of layers
const float layers = 21.;
// star colours
const vec3 blue = vec3(51., 64., 195.) / 255.;
const vec3 cyan = vec3(117., 250., 254.) / 255.;
const vec3 white = vec3(255., 255., 255.) / 255.;
const vec3 yellow = vec3(251., 245., 44.) / 255.;
const vec3 red = vec3(247, 2., 20.) / 255.;
float luminance(vec3 color) {
return dot(color, vec3(0.2126, 0.7152, 0.0722));
}
// spectrum function
vec3 spectrum(vec2 pos) {
pos.x *= 4.;
vec3 outCol = vec3(0);
if (pos.x > 0.) {
outCol = mix(blue, cyan, fract(pos.x));
}
if (pos.x > 1.) {
outCol = mix(cyan, white, fract(pos.x));
}
if (pos.x > 2.) {
outCol = mix(white, yellow, fract(pos.x));
}
if (pos.x > 3.) {
outCol = mix(yellow, red, fract(pos.x));
}
return 1. - (pos.y * (1. - outCol));
}
float N21(vec2 p) {
p = fract(p * vec2(233.34, 851.73));
p += dot(p, p + 23.45);
return fract(p.x * p.y);
}
vec2 N22(vec2 p) {
float n = N21(p);
return vec2(n, N21(p + n));
}
mat2 scale(vec2 _scale) {
return mat2(_scale.x, 0.0,
0.0, _scale.y);
}
// 2D Noise based on Morgan McGuire
float noise(in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
// Four corners in 2D of a tile
float a = N21(i);
float b = N21(i + vec2(1.0, 0.0));
float c = N21(i + vec2(0.0, 1.0));
float d = N21(i + vec2(1.0, 1.0));
// Smooth Interpolation
vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve
// Mix 4 corners percentages
return mix(a, b, u.x) +
(c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float perlin2(vec2 uv, int octaves, float pscale) {
float col = 1.;
float initScale = 4.;
for (int l; l < octaves; l++) {
float val = noise(uv * initScale);
if (col <= 0.01) {
col = 0.;
break;
}
val -= 0.01;
val *= 0.5;
col *= val;
initScale *= pscale;
}
return col;
}
vec3 stars(vec2 uv, float offset) {
float timeScale = -(iTime + offset) / layers;
float trans = fract(timeScale);
float newRnd = floor(timeScale);
vec3 col = vec3(0.);
// Translate uv then scale for center
uv -= vec2(0.5);
uv = scale(vec2(trans)) * uv;
uv += vec2(0.5);
// Create square aspect ratio
uv.x *= iResolution.x / iResolution.y;
// Create boxes
uv *= repeats;
// Get position
vec2 ipos = floor(uv);
// Return uv as 0 to 1
uv = fract(uv);
// Calculate random xy and size
vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05;
float rndSize = N21(ipos) * 100. + 200.;
vec2 j = (rndXY - uv) * rndSize;
float sparkle = 1. / dot(j, j);
// Set stars to be pure white
col += spectrum(fract(rndXY * newRnd * ipos)) * vec3(sparkle);
col *= smoothstep(1., 0.8, trans);
return col; // Return pure white stars only
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord / iResolution.xy;
vec3 col = vec3(0.);
for (float i = 0.; i < layers; i++) {
col += stars(uv, i);
}
// Sample the terminal screen texture including alpha channel
vec4 terminalColor = texture(iChannel0, uv);
if (transparent) {
col += terminalColor.rgb;
}
// Make a mask that is 1.0 where the terminal content is not black
float mask = 1 - step(threshold, luminance(terminalColor.rgb));
vec3 blendedColor = mix(terminalColor.rgb, col, mask);
// Apply terminal's alpha to control overall opacity
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,135 @@
// transparent background
const bool transparent = false;
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
const float threshold = 0.15;
// divisions of grid
const float repeats = 30.;
// number of layers
const float layers = 21.;
// star colors
const vec3 white = vec3(1.0); // Set star color to pure white
float luminance(vec3 color) {
return dot(color, vec3(0.2126, 0.7152, 0.0722));
}
float N21(vec2 p) {
p = fract(p * vec2(233.34, 851.73));
p += dot(p, p + 23.45);
return fract(p.x * p.y);
}
vec2 N22(vec2 p) {
float n = N21(p);
return vec2(n, N21(p + n));
}
mat2 scale(vec2 _scale) {
return mat2(_scale.x, 0.0,
0.0, _scale.y);
}
// 2D Noise based on Morgan McGuire
float noise(in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
// Four corners in 2D of a tile
float a = N21(i);
float b = N21(i + vec2(1.0, 0.0));
float c = N21(i + vec2(0.0, 1.0));
float d = N21(i + vec2(1.0, 1.0));
// Smooth Interpolation
vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve
// Mix 4 corners percentages
return mix(a, b, u.x) +
(c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float perlin2(vec2 uv, int octaves, float pscale) {
float col = 1.;
float initScale = 4.;
for (int l; l < octaves; l++) {
float val = noise(uv * initScale);
if (col <= 0.01) {
col = 0.;
break;
}
val -= 0.01;
val *= 0.5;
col *= val;
initScale *= pscale;
}
return col;
}
vec3 stars(vec2 uv, float offset) {
float timeScale = -(iTime + offset) / layers;
float trans = fract(timeScale);
float newRnd = floor(timeScale);
vec3 col = vec3(0.);
// Translate uv then scale for center
uv -= vec2(0.5);
uv = scale(vec2(trans)) * uv;
uv += vec2(0.5);
// Create square aspect ratio
uv.x *= iResolution.x / iResolution.y;
// Create boxes
uv *= repeats;
// Get position
vec2 ipos = floor(uv);
// Return uv as 0 to 1
uv = fract(uv);
// Calculate random xy and size
vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05;
float rndSize = N21(ipos) * 100. + 200.;
vec2 j = (rndXY - uv) * rndSize;
float sparkle = 1. / dot(j, j);
// Set stars to be pure white
col += white * sparkle;
col *= smoothstep(1., 0.8, trans);
return col; // Return pure white stars only
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord / iResolution.xy;
vec3 col = vec3(0.);
for (float i = 0.; i < layers; i++) {
col += stars(uv, i);
}
// Sample the terminal screen texture including alpha channel
vec4 terminalColor = texture(iChannel0, uv);
if (transparent) {
col += terminalColor.rgb;
}
// Make a mask that is 1.0 where the terminal content is not black
float mask = 1 - step(threshold, luminance(terminalColor.rgb));
vec3 blendedColor = mix(terminalColor.rgb, col, mask);
// Apply terminal's alpha to control overall opacity
fragColor = vec4(blendedColor, terminalColor.a);
}

23
ghostty/shaders/tft.glsl Normal file
View File

@@ -0,0 +1,23 @@
/** Size of TFT "pixels" */
float resolution = 4.0;
/** Strength of effect */
float strength = 0.5;
void _scanline(inout vec3 color, vec2 uv)
{
float scanline = step(1.2, mod(uv.y * iResolution.y, resolution));
float grille = step(1.2, mod(uv.x * iResolution.x, resolution));
color *= max(1.0 - strength, scanline * grille);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord.xy / iResolution.xy;
vec3 color = texture(iChannel0, uv).rgb;
_scanline(color, uv);
fragColor.xyz = color;
fragColor.w = 1.0;
}

View File

@@ -0,0 +1,74 @@
// adapted by Alex Sherwin for Ghostty from https://www.shadertoy.com/view/lljGDt
#define BLACK_BLEND_THRESHOLD .4
float hash21(vec2 p) {
p = fract(p * vec2(233.34, 851.73));
p += dot(p, p + 23.45);
return fract(p.x * p.y);
}
float rayStrength(vec2 raySource, vec2 rayRefDirection, vec2 coord, float seedA, float seedB, float speed)
{
vec2 sourceToCoord = coord - raySource;
float cosAngle = dot(normalize(sourceToCoord), rayRefDirection);
// Add subtle dithering based on screen coordinates
float dither = hash21(coord) * 0.015 - 0.0075;
float ray = clamp(
(0.45 + 0.15 * sin(cosAngle * seedA + iTime * speed)) +
(0.3 + 0.2 * cos(-cosAngle * seedB + iTime * speed)) + dither,
0.0, 1.0);
// Smoothstep the distance falloff
float distFade = smoothstep(0.0, iResolution.x, iResolution.x - length(sourceToCoord));
return ray * mix(0.5, 1.0, distFade);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
uv.y = 1.0 - uv.y;
vec2 coord = vec2(fragCoord.x, iResolution.y - fragCoord.y);
// Set the parameters of the sun rays
vec2 rayPos1 = vec2(iResolution.x * 0.7, iResolution.y * 1.1);
vec2 rayRefDir1 = normalize(vec2(1.0, 0.116));
float raySeedA1 = 36.2214;
float raySeedB1 = 21.11349;
float raySpeed1 = 1.1;
vec2 rayPos2 = vec2(iResolution.x * 0.8, iResolution.y * 1.2);
vec2 rayRefDir2 = normalize(vec2(1.0, -0.241));
const float raySeedA2 = 22.39910;
const float raySeedB2 = 18.0234;
const float raySpeed2 = 0.9;
// Calculate the colour of the sun rays on the current fragment
vec4 rays1 =
vec4(1.0, 1.0, 1.0, 0.0) *
rayStrength(rayPos1, rayRefDir1, coord, raySeedA1, raySeedB1, raySpeed1);
vec4 rays2 =
vec4(1.0, 1.0, 1.0, 0.0) *
rayStrength(rayPos2, rayRefDir2, coord, raySeedA2, raySeedB2, raySpeed2);
vec4 col = rays1 * 0.5 + rays2 * 0.4;
// Attenuate brightness towards the bottom, simulating light-loss due to depth.
// Give the whole thing a blue-green tinge as well.
float brightness = 1.0 - (coord.y / iResolution.y);
col.r *= 0.05 + (brightness * 0.8);
col.g *= 0.15 + (brightness * 0.6);
col.b *= 0.3 + (brightness * 0.5);
vec2 termUV = fragCoord.xy / iResolution.xy;
vec4 terminalColor = texture(iChannel0, termUV);
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
vec3 blendedColor = mix(terminalColor.rgb * 1.0, col.rgb * 0.3, alpha);
fragColor = vec4(blendedColor, terminalColor.a);
}

View File

@@ -0,0 +1,35 @@
#define TAU 6.28318530718
#define MAX_ITER 6
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec3 water_color = vec3(1.0, 1.0, 1.0) * 0.5;
float time = iTime * 0.5+23.0;
vec2 uv = fragCoord.xy / iResolution.xy;
vec2 p = mod(uv*TAU, TAU)-250.0;
vec2 i = vec2(p);
float c = 1.0;
float inten = 0.005;
for (int n = 0; n < MAX_ITER; n++)
{
float t = time * (1.0 - (3.5 / float(n+1)));
i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
}
c /= float(MAX_ITER);
c = 1.17-pow(c, 1.4);
vec3 color = vec3(pow(abs(c), 15.0));
color = clamp((color + water_color)*1.2, 0.0, 1.0);
// perterb uv based on value of c from caustic calc above
vec2 tc = vec2(cos(c)-0.75,sin(c)-0.75)*0.04;
uv = clamp(uv + tc,0.0,1.0);
fragColor = texture(iChannel0, uv);
// give transparent pixels a color
if ( fragColor.a == 0.0 ) fragColor=vec4(1.0,1.0,1.0,1.0);
fragColor *= vec4(color, 1.0);
}

View File

Binary file not shown.

BIN
grub/Elegant-Based/background.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More