К содержанию
КОНСТРУКТ

Продукт · браузер

ENDLESS

Включается и летит, пока открыта вкладка. Местности, над которой идёт пролёт, нигде не существует: она вычисляется заново впереди камеры и забывается за спиной.

Открыть ENDLESS Все продукты

Что это

Сцена, в которой происходит ровно одно событие: камера идёт вперёд по каньону. Ни цели, ни счёта, ни конца — закрывается вкладкой. Делалась она для фона: под работу, под разговор, под запись часового ролика.

Это не видео и не зацикленный клип. Каждый кадр считается на месте, из сида и координаты. Участок под камерой не повторится ни через час, ни через сутки — не потому, что запас большой, а потому, что запаса нет вовсе: впереди всегда новая координата, и под неё всегда есть что посчитать.

Работает в браузере, ставить нечего. Сборок под настольную систему и телефон нет.

Мир не хранится — он вычисляется

Высота земли — чистая функция координаты и сида. Нигде нет массива с ландшафтом, нет и файла, из которого его можно было бы подгрузить: есть только правило, по которому высота получается из пары чисел.

Вокруг камеры живёт сетка чанков по 32 метра — шестнадцать клеток по два. Чанк, ушедший за спину, не удаляется: он переставляется вперёд и пересчитывается по новым координатам, в том же буфере вершин. Объектов в памяти ровно столько, сколько было в первом кадре, и в кадровом цикле не создаётся ни одного. За кадр строится не больше трёх чанков — иначе на старте был бы фриз.

Тот же приём с дымом и искрами: клубы не рождаются и не умирают, а пересеваются впереди, как только выходят из коробки вокруг камеры.

Основа формы — value noise на целочисленном хеше и fBm из пяти октав. Координата между октавами поворачивается на нецелый угол: без поворота гребни выстраиваются по осям сетки и рельеф читается шахматкой. Поверх этого работают семь слоёв.

Domain warpingкоордината сдвигается другим шумом на полторы сотни метров ещё до сэмпла. Без этого выходят ватные холмы, с ним — текучие выветренные гребни
Ridged fBmединица минус модуль шума, возведённая в степень: плато обрываются, а не сползают
Террасированиевысота клетки округляется до шага 1,7 метра — ровные полки и мезы вместо склона
Стенкивертикальная грань строится только там, где сосед ниже, одна на любую высоту уступа
Коридорамплитуда гасится квадратом маски вокруг оси каньона: у самой оси ровное дно, стены встают круто и вплотную к объективу
Региональная амплитудашум очень низкой частоты водит размах от 50 до 190 метров — равнины сами собой переходят в высокогорья
Валуныодиночная клетка на ступень-две выше, примерно на полпроцента клеток и только на ровном грунте: по ближнему плану глаз считает скорость

Как сделана картинка

Сцена рисуется во внутреннее разрешение — от 256 до 480 пикселей по ширине — и растягивается на окно. Плотность экрана не учитывается намеренно: полноэкранный пост-проход и так самое дорогое место кадра, а картинке из крупного пикселя ретина ничего не даёт.

Свет запечён в грань. Шейдер не считает освещение по кадру: верхняя площадка, бок по одной оси и бок по другой имеют свои фиксированные яркости, а солнечная добавка ложится только на вертикальные грани, смотрящие на солнце. Поворот камеры физически не может родить бегущий блик. Солнце стоит у горизонта, поэтому площадки как раз тусклые, а всю яркость забирают стенки — отсюда читаемость уступов.

Снап вершин — тот самый, из первой PlayStation, — делается в клип-спейсе по общей экранной сетке. Сетка рельефа равномерная, без LOD и без слияния квадов, поэтому совпадающие вершины соседних чанков садятся в одну точку: T-стыков нет и швы не трещат.

Дизеринг работает по яркости, а не по цвету. Квантуется только светлота, хрома несётся гладко — поэтому стипль получается серый, а не разноцветной сыпью. Порог берётся смесью матрицы Байера 8×8 с interleaved gradient noise: чистый Байер прибит к экрану и читается кафелем поверх кадра, а смесь ломает решётку, и крупа ложится по форме. Число уровней задаёт настроение: от четырнадцати в «Долгой Сери» до двадцати шести в «Песках».

Туман квадратичный по дистанции: порода в сорока метрах ещё чистая — тумана в ней меньше трёх процентов, — а дальняя кромка рельефа в двухстах уже наполовину ушла в цвет неба. Этот разрыв и даёт глубину. Дальше идут компрессия света вместо жёсткого клиппинга, bloom, хроматическая аберрация, виньетка и плёночное зерно.

Четыре настроения

Палитра каждого — три-четыре цвета и не больше; ограничение здесь и есть главный признак вкуса. Туман, низкое солнце и свечение со дна только разводят эти цвета по глубине.

Поверх настроения идёт медленный дрейф: угол и высота солнца, его ореол, плотность тумана, облака, свечение низа. Шесть периодов взяты несоизмеримыми — 373, 611, 661, 899, 1039 и 1277 секунд, — поэтому их сумма не повторится за час и зритель не поймает петлю. Дрейфует только то, что относится к взгляду; земля под камерой остаётся той же функцией координаты.

Камера — дрон, а не рельса

Ось каньона задаёт только желаемую точку. Фактическая идёт за ней критически задемпфированной пружиной: есть инерция и плавный вход в поворот, нет перелёта и болтанки. Точка взгляда тянется ещё ленивее, поэтому на вираже камера сначала уходит боком и лишь потом доворачивает. Крен берётся из настоящей угловой скорости — аппарат заваливается в поворот, а не изображает крен по таблице.

Порода входит в желаемую высоту заранее: она считается и под желаемой точкой, и под фактической. На вираже камеру сносит к стене, стена попадает в расчёт до того, как до неё дошли, и подъём отрабатывает та же пружина — вместо рывка от жёсткой страховки. Замер на трёх сидах, по десять минут пути каждый, на штатной скорости: крен до 8,9 градуса, вертикальное ускорение до 2,0 метра в секунду за секунду, срабатываний жёсткой страховки — ноль.

Как открыть

Нужен браузер с WebGL2 — Chrome, Edge или Firefox посвежее. Если его нет, страница честно скажет об этом и ничего не нарисует.

Зависимостей у сцены нет ни одной: ни библиотек, ни CDN. Движок, который должен посчитать двести шестнадцать тысяч кадров подряд, не имеет права зависеть от чужого сервера.

Качество выбирается в панели: лёгкое, обычное, полное. Оно управляет внутренним разрешением, масштабом вывода, дальностью прорисовки, количеством дыма и числом проходов bloom. По умолчанию стоит лёгкое — на слабой машине честные пятьдесят кадров важнее лишних пикселей, тем более что картинка всё равно пиксельная.

Hспрятать панель и счётчики — для чистого захвата
Rновый мир
Пробелпауза
Fполный экран
Escзакрыть панель
Перетащить аудиофайлсцена начинает слушать: бас двигает скорость, свечение и bloom

Участок задаётся прямо в адресе: seed, preset, q, z и speed. Мир детерминирован, поэтому по этим пяти числам воспроизводится любой кадр — например, /apps/endless/?seed=1874&preset=dolgaya&q=high&z=11500&speed=8.

Родство с «Долгой Серью»

Картинка говорит на языке «Долгой Сери» — созерцательной бродилки, которая делается на Godot и в браузер не пойдёт. Оттуда взяты низкое внутреннее разрешение, снап вершин, запечённый в грани свет и дизеринг по яркости; оттуда же одноимённое настроение с его монохромом.

Одно расхождение сделано сознательно. В самой «Долгой Сери» снап выключен: там неравномерная геометрия, и снапнутые вершины расходятся T-стыками. Здесь сетка рельефа равномерная, поэтому снап держится на полной силе — и именно он отвечает за дрожание кромок на ходу.

Открыть ENDLESS Все продукты Поддержка