tm2027 · борд шейдеров · 2026-09-05

Что можно повесить на gpui шейдером

В gpui 0.2.2 публичного API для своих шейдеров нет: сцена состоит из семи примитивов (quad, shadow, path, underline, два спрайта, surface), и всё остальное вуали из #497 уже выжимают из квадов. Но gpui у нас вендорен с тремя патчами, и четвёртый открывает дверь: в directx_renderer.rs уже есть готовый шаблон — пути рисуются в промежуточную MSAA-текстуру, а потом спрайтом на экран. Тот же приём для всего кадра: сцена → offscreen-текстура → один fullscreen-треугольник со своим HLSL и constant-buffer'ом (время, прямоугольник стекла, параметры). Это ~1 мс на 4K, включается тумблером в GLASS · Screen рядом с вуалями. Каждая карточка ниже — настоящий фрагментный шейдер (WebGL2, GLSL), запущенный на одном и том же экране Claude Code; в деке он переписывается в HLSL один к одному.

Один пост-проход scene → RTV(offscreen) → fullscreen pass → swapchain. Bloom, дизер, LUT, виньетка живут в одном проходе и почти бесплатны; blur и persistence читают уже нарисованный кадр, значит offscreen-текстура обязательна.
Три бэкенда Патч нужен в shaders.hlsl (Windows), shaders.metal (macOS, фича runtime-shaders уже есть) и shaders.wgsl (blade/Linux). Иначе Мак Вадика остаётся без эффекта.
Пиксельная сетка После #496 клетка стоит на целых device-пикселях. Всё, что двигает пиксели (кривизна, аберрация), ставит на этом крест — только под явным тумблером Tube, не дефолт.
Кадры, а не миллисекунды Пост-проход дёшев, но живые шейдер-обои и persistence — это постоянные кадры, та самая ловушка холостого CPU из #267. Только при активном окне и на 10–15 к/с, как retrace.
DPR
0 Эталон то, что есть сейчас

Без пост-прохода

Голое стекло после #496 и #497: клетка на целых пикселях, вуали квадами, шейдеров нет.

#497

Tube + Retrace квадами

Нынешний потолок без шейдера: виньетка четырьмя градиентами, лента обратного хода, интерлейс.

I Профессионально тихие, не ломают сетку · клик — выбор
1

Acrylic · размытие под слоем

Backdrop blur под модалками (SURE?, палитра, SUBS), под pause-veil и полупрозрачными панелями. Двухпроходный dual-Kawase по копии кадра под областью, сверху тон панели и зерно, чтобы не было пластика. Самый заметный «дорогой» эффект — то, что делает vibrancy в macOS и acrylic в Windows 11, и то, чего квадами не сделать в принципе.

Проход: кадр → mip-цепочка 2–3 уровня → up-sample с тонировкой. Прямоугольники слоёв приходят в constant-buffer, остальное стекло копируется как есть. Ручка: GLASS → «Layers: FLAT · ACRYLIC». Reduce transparency в системе = FLAT автоматически.
1

Модалка на стекле

Радиус 18px, тон панели .55, зерно .015, тень 24px наружу.

1′

Pause-veil матовым стеклом

Спящий таб: всё стекло в размытии 10px и тоне .35, подпись остаётся резкой.

2

Bloom · свечение ярких клеток

Порог по яркости, размытие, сложение обратно с малой силой. Bold, курсор, зелёные «ok» и жёлтые предупреждения начинают чуть светиться, текст остаётся резким, потому что складывается только размытая копия ярких мест. В тихой дозе читается не как эффект, а как «дорогой монитор».

Проход: threshold + 24–48 тапов диском Фогеля (или mip-blur) + add. Один проход, без второй текстуры. Ручка: GLASS → «Bloom: OFF · SOFT · GLOW». Сила и порог — константы.
2

Soft

Порог .45, радиус 6px, сила .55. Дефолт для «профессионально».

2′

Glow

Порог .35, радиус 14px, сила 1.1. Уже ретро, но без сканлайнов.

3

Дизер · чистые градиенты

Шум в 1/64 тона перед квантованием убивает бандинг на градиентах обоев, вуалей и виньеток. Незаметен в упор, но картинка становится «чистой» — ступеньки на тёмных переходах исчезают. Interleaved gradient noise без текстур; blue-noise текстура 64×64 — если захочется совсем тихо.

Проход: две строки в конце fullscreen-прохода. Стоит ноль. Ручка: не нужна — всегда включён, когда включён пост-проход. На карточке слева — без дизера, справа — с ним; градиент квантован до 64 уровней, чтобы бандинг был виден на любом мониторе.
3

Без / с дизером

Слева ступеньки на градиенте обоев, справа IGN-шум 1/48 тона.

4

LUT · грейдинг всего кадра

Одна 3D-текстура 32³ перекрашивает кадр целиком: тёплый ночной режим, тон темы под обои, гамма под конкретный монитор. Ни один цвет темы не трогается — грейдинг лежит поверх и выключается одним битом. Здесь LUT заменён формулой (температура, гамма, насыщенность).

Проход: одна выборка из 3D-текстуры. LUT-файлы .cube лежат рядом с обоями в %APPDATA%\tm2027. Ручка: GLASS → «Grade: OFF · WARM · COOL · file.cube». По часам — WARM после заката, как Night Light.
4

Warm · ночь

Температура 1.08/.97/.82, гамма .95, насыщенность .92.

4′

Cool · контраст

Гамма 1.12, тон .94/1.0/1.08, насыщенность .85, чёрный поднят на .01.

5

Bezel · виньетка и внутренняя тень

То, что Tube делает четырьмя градиентами, шейдер делает точно: радиальная виньетка, а не крест из линейных, и внутренняя тень по скруглённой рамке через SDF — стекло «сидит» в раме, как экран в корпусе. Бесплатно внутри того же прохода.

Проход: два smoothstep и один sdRoundBox. Заменяет квады Tube, освобождает ~7 квадов на тайл. Ручка: становится реализацией нынешнего «Screen: TUBE», отдельной ручки нет.
5

Рама

Радиус 22px, внутренняя тень 26px до .45, виньетка до .4.

II Красиво ретро, только над стеклом
6

CRT · настоящий кинескоп

Barrel-кривизна, апертурная решётка по субпикселям (R·G·B через пиксель), профиль сканлайна по гауссу вместо чёрной линии, лёгкий bloom и тень по краю трубки. Всё, что вуали обещают квадами, здесь честно. Кривизна пересэмплирует текст, поэтому это чисто режим Tube.

Проход: curve → sample → bloom → mask → scanline → edge. Cool-retro-term в 40 строк HLSL. Ручка: GLASS → «Screen: CRT» рядом с TUBE/RETRACE; «flat» вариант держит сетку и годится в дефолт для ретро-миров.
6

С кривизной

Кривизна 1/5.5 · 1/4.2, решётка .82+.18, сканлайн .55–1.0 период 3px.

6′

Плоский

То же без кривизны: сетка #496 цела, текст не мылится.

7

Persistence · след фосфора

Ping-pong с прошлым кадром и затуханием: за курсором, за бегущим выводом и за прогресс-баром остаётся угасающий след, как на люминофоре. Единственный эффект с памятью — нужна вторая текстура и кадр за кадром, пока след не потух.

Проход: max(scene, prev·decay), decay .86/.90/.84 по каналам. Кадры только пока след виден (~300 мс после последнего изменения). Ручка: GLASS → «Afterglow» ON/OFF; гасится с reduce motion. Включите движение вверху, иначе следа нет.
7

Afterglow

Зелёный канал держится дольше — след чуть зеленит, как P1.

8

Analog · дрожь, мерцание, аберрация

Хроматическая аберрация к краям, редкий строчный джиттер, мерцание яркости на 3%. По чуть-чуть — иначе шум. Честно: это «красиво» на демо и утомляет за час; в списке для полноты, не для дефолта.

Проход: три выборки со сдвигом по каналам + шум по времени. Кадры постоянные — самый дорогой по кадрам эффект после обоев. Ручка: GLASS → «Screen: ANALOG». Reduce motion = выключено.
8

Аналог

Аберрация до 1.2px у края, джиттер 1.5% кадров, мерцание .97–1.0.

9

Живые обои · процедурная туманность

Вместо PNG-обоев из 16 миров — шейдер: fbm-туманность, медленно дышит, звёзды по хешу. Красиво и без файлов, но это постоянные кадры — та же ловушка, что #267. Только при активном окне, 10–15 к/с, и стекло поверх обоев на .55, чтобы текст читался.

Проход: 5 октав value-noise, домен-варп, ~60 инструкций на пиксель. На 4K это ~2 мс кадра на встроенной графике. Ручка: ещё один «мир» в списке обоев: «Nebula (live)». Пейсер как у retrace.
9

Nebula

Синий/фиолетовый/бирюзовый, дрейф .05/с, стекло .55 поверх.

III Первый шаг что бы я взял

Один патч, три эффекта

Acrylic + дизер + мягкий bloom: три эффекта в одном пост-проходе, без анимации, без лишних кадров, и дека сразу выглядит на уровень дороже. Патч: vendor/gpui/src/platform/windows/directx_renderer.rs (offscreen RTV + fullscreen pass), shaders.hlsl (один новый пиксельный шейдер), Window получает set_post_effect(PostEffect) — так же, как сегодня set_glass_veil хранит альфу вуали. macOS и Linux — тот же шейдер на Metal/WGSL следом, за один PR каждый. CRT, persistence и обои — отдельными тумблерами позже, по выбору здесь.

ничего не выбрано