TGViewer
UfoStation UfoStation @xufostation · 3.05K subscribers
Post #1041 1.12K
Почему cssDOOM это не DOOM 😒

Выше обещал разобраться насколько проект cssDoom близок к оригинальному doom. Короткий ответ: с точки зрения геймплея и реализация близка, а с точки зрения технической реализации рендеринга — нет.

Начну с того, что лично для себя я так и не понял, можно ли визуально похожие игры, но отличающиеся технически (со всеми вытекающими), считать одной и той же игрой? Вывод был бы однозначным, если бы не было такого понятия, как remastered. Это когда создатели берут старую игру и переводят ее на обновленный движок.

Интуитивно близкий подход к разработке Doom в браузере — это хранить где-то в памяти данные об уровне, затем на их основе вычислять геометрию уровня, текстуры, движение и прочее и прочее на стороне JavaScript, а с помощью Canvas API заниматься отрисовкой пикселей.

Автор проекта cssDoom, Нильс Линхеер выбрал другой подход. Отрисовка происходит через DOM. DOOM в DOM, каламбур. В его подходе для сцены создается множество <div /> элементов, вместо отрисовки на canvas. Каждая стена, пол, бочка и монстр — это отдельный элемент в DOM-дереве. У каждого <div /> есть набор CSS-свойств, которые устанавливаются из настроек уровня, например:

<div class="wall" style="
--start-x: 2560;
--start-y: -2112;
--end-x: 2560;
--end-y: -2496;
--floor-z: 32;
--ceiling-z: 88;
">


Затем все дальнейшие расчеты берет на себя CSS. В репозитории проекта прямо так и пишется, что на стороне CSS вычисляет ширину, высоту и 3D-преобразования с помощью тригонометрических функций:

.wall {
--delta-x: calc(var(--end-x) - var(--start-x));
--delta-y: calc(var(--end-y) - var(--start-y));

width: calc(hypot(var(--delta-x), var(--delta-y)) * 1px);
height: calc((var(--ceiling-z) - var(--floor-z)) * 1px);

transform:
translate3d(
calc(var(--start-x) * 1px),
calc(var(--ceiling-z) * -1px),
calc(var(--start-y) * -1px)
)
rotateY(atan2(var(--delta-y), var(--delta-x)));
}


Здесь можно дальше погружаться в описание проекта и его исходный код, чтобы найти использование множества CSS свойств для отрисовки, и по итогу воскликнуть: А что так можно было что ли? Однако здесь я поднимаю другой вопрос.

Насколько это реализация повторяет оригинальный DOOM

Если изучить код WAD-файл и исходники, то можно заметить, что автор отказался от использования BSP-дерева (бинарного разбиения пространства). Напомню, что именно этот алгоритм, реализованный Джоном Кармаком, позволил оригинальному Doom эффективно работать на слабом железе 90-х: движок обходил только видимые стены и не тратил ресурсы на отрисовку перекрытых областей.

В cssDoom всё иначе. Вместо эффективного обхода стен и исключения ранее нарисованных при отрисовке следующих, автор рисует сразу все стены и предметы — используя CSS-свойство translate3d.

Что это дает это свойство?

➡️ Графика перестает быть плоской 2D или условно трехмерной (2.5D), а становится полноценной 3D. То есть благодаря CSS-трансформациям каждый объект получает реальные координаты в пространстве. Кстати, в превью к заметке добавлена специально трехмерная версия игры, cssDoom сам такое позволяет делать.

➡️ Каждый элемент <div /> после попадает в отдельный композитный слой браузера в понятиях браузерного рендеринга. При изменении страницы происходит (пере)компоновка этих слоев — эту работу берет на себя GPU.

➡️ В оригинальном Doom всё рисовалось исключительно на процессоре, пиксель за пикселем, с кучей ручных оптимизаций. В cssDoom мы уходим от идеи «нарисовать для уровня 1 пиксель 1 раз» — вместо этого браузерный движок сам решает, как и когда обновлять слои через видеокарту.

Что же это тогда

Разработчики прошлого старались искать всевозможные оптимизации, чтобы добиться максимальной скорости отрисовки на слабых машинах. Проект cssDoom это скорее концепт или технический эксперимент, способный визуально повторить и показать возможности современного CSS, но безусловно достойный внимания и уважения 🎩
  • 🔥 8
  • ❤ 4
  • 👍 2
More from @xufostation
  1. Sep 1, 2026Результаты розыгрыша: Комментарий с порядковым номером 4 побеждает (среди тех, что с тэгам…
  2. Aug 27, 2026В этом году также как в прошлом и в позапрошлом хочу подарить случайному подписчику канала…
  3. Aug 12, 2026Литания о Фронтенде Некоторое время назад у меня было желание рассказывать о своем погруже…
  4. Aug 12, 2026Переключился на тему webassembly и готовлю для вас медленно, но верно, свои заметки. А пок…
  5. Jul 21, 2026Post #1048
  6. Jul 21, 2026Друзья, важный вопрос ❔ С одной стороны я заметил, что доклад про отрисовщик как DOOM понр…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →