Сквозь лёд
Плазма, текущая за толстой плитой прозрачного голубого льда. Три самостоятельные страницы, каждая — один HTML-файл без внешних зависимостей (WebGL1 + GLSL ES 1.0).
ice_plasma.html— просто плазма за льдом.ice_object.html— в лёд вморожен огранённый кристалл, преломлённый вместе со льдом.ice_fish.html— тёмные силуэты рыб с холодными голубыми глазами проплывают сквозь плиту.
Открыть любой файл в браузере. Мышь — параллакс, − / = — скорость. Цикл плазмы 30 с.
Рендеры
Плазма за льдом
Огранённый кристалл вморожен в плиту: лёд преломляет его так же, как всё за собой
Рыбы: тёмные силуэты с холодными голубыми глазами
Кадры сняты с текущих шейдеров в 1280×720; время в них зафиксировано параметром
#shot&t=… (см. «Проверка»). Сами страницы живые: плазма течёт, рыбы проплывают,
кристалл стоит вмороженный и преломляется.
Как устроено
Два прохода на кадр:
- Сцена (
6_ice_plasma.frag,8_ice_scene.frag,10_ice_fish.frag) — плазма рисуется в атлас 4×2 из восьми листов, каждый лист — свой слой на своей глубине. Глубина записывается в альфу:(0.42 + layer * 0.26) / 2.6. Там, где вместо плазмы твёрдый объект (кристалл, рыба), в альфе лежит покрытие, а не глубина. - Лёд (
7_ice_over.frag,9_ice_over_obj.frag,11_ice_over_fish.frag) — для каждого слоя по его глубине считается путь луча во льду, отсюда своё преломление, свой параллакс и своё поглощениеexp(-SIGMA * path). Поверхность — неподвижный рельеф с трещинами; трещины дают ступеньку в склоне и рвут плазму на гранях.
Листы с объектами хранят покрытие вместо глубины, поэтому пасс 2 берёт для них глубину по номеру листа, а не из альфы.
Сборка
python3 build_plasma.py # -> ice_plasma.html
python3 build_plasma.py 8_ice_scene.frag 9_ice_over_obj.frag ice_object.html
python3 build_plasma.py 10_ice_fish.frag 11_ice_over_fish.frag ice_fish.html
build_plasma.py вставляет оба шейдера в шаблон страницы. После правки шейдеров страницу
надо пересобрать — HTML сам по себе не обновляется.
Проверка
python3 -m unittest test_ice
Рендерит ice_plasma.html в headless Firefox и проверяет, что кадр не пустой, плазма
движется, цикл замыкается и мышь меняет картинку. Нужны Firefox и Pillow; сами страницы —
нет.
Кадр вручную: firefox --headless --screenshot=/tmp/x.png "file://$PWD/ice_fish.html#shot&t=8".
Параметр t фиксирует время, mx/my — позицию мыши.
Оговорки
9_ice_over_obj.fragи11_ice_over_fish.frag— копии7_ice_over.frag: правки рельефа и преломления льда надо переносить во все три файла.debug_fish.frag+debug_fish.html— плоский рендер силуэтов рыб для отладки формы.renders/*.jpg— картинки для этого README, к сборке отношения не имеют.build.pyсобираетplayground.htmlсо всеми.fragподряд,render.py/shot.py— старые вспомогательные скрипты.


