순수 CSS로 구현한 Doom: Canvas나 WebGL 없이 렌더링
개발자 Niels Lehner가 cssDoom 프로젝트를 공개했습니다. 이 프로젝트는 고전 게임 Doom을 완벽하게 구현한 것으로, 모든 그래픽이 CSS만으로 렌더링됩니다. 게임 로직은 JavaScript로 구현되었으며, canvas나 WebGL을 사용하지 않습니다. id Software의 원본 Doom 소스 코드를 사용하며, 이는 WAD 파일로 제공됩니다. 프로젝트는 GitHub에 GPLv2 라이선스로 호스팅되어 있습니다.
모든 시각적 요소—스프라이트, 텍스처 벽, 레벨, 이펙트—는 div 요소로 구성됩니다. 이들은 CSS 속성 transform과 transform-style: preserve-3d를 사용해 3D 공간에 배치됩니다. JavaScript는 스타일에 직접 개입하지 않고, WAD 파일의 정점 지오메트리에 기반한 사용자 정의 CSS 속성을 설정합니다. CSS는 삼각 함수를 사용해 너비, 높이, 변환을 독립적으로 계산합니다.
좌표계 적응과 게임 루프
Doom의 좌표계는 CSS 3D와 다릅니다. Doom은 Y가 북쪽으로 증가하는 2D 시스템을 사용하지만, CSS에서는 Y가 위쪽을 향하고 Z가 관찰자를 향합니다. 변환은 translate3d(x, -z, -y)로 구현됩니다. 사용자 정의 속성은 Doom 좌표로 정의되며, CSS가 이를 해석합니다.
JavaScript의 게임 루프는 플레이어 위치, 입력, 충돌, 적 AI를 추적합니다. 이는 원본 코드의 직접적인 포트입니다. 분리는 엄격합니다. JS는 --player-x, --player-y, --player-z, --player-angle 같은 핵심 속성만 업데이트합니다. CSS는 플레이어에 상대적인 전체 세계를 이동시켜 카메라를 시뮬레이션합니다(CSS에는 카메라가 없습니다). 이동과 시야는 이 네 속성의 업데이트일 뿐입니다.
1인칭 시점을 지원하며, 맵 개요로 전환할 수 있습니다.
장면 구성의 기술적 세부 사항
프로세스는 WAD 파일 파싱부터 시작합니다. 라인 정의, 사이드 정의, 섹터 매개변수가 추출됩니다. 이로부터 원본 정점 지오메트리를 가진 div 요소가 생성됩니다. CSS는 calc()를 계산에 사용합니다.
- 요소의 너비와 높이는 시야 각도와 거리에 따라 결정됩니다.
- 변환은 원근을 고려합니다.
간소화된 사용자 정의 속성 구조 예시:
:root {
--player-x: 0;
--player-y: 0;
--player-angle: 0;
}
.scene-element {
width: calc(var(--doom-width) * var(--perspective-factor));
height: calc(var(--doom-height) * var(--perspective-factor));
transform: translate3d(
calc(var(--doom-x)),
calc(-var(--doom-z)),
calc(-var(--doom-y))
) rotateY(var(--player-angle));
}
이 접근 방식은 성능을 보장합니다. 브라우저의 CSS 렌더러가 GPU에서 3D 변환을 최적화하기 때문입니다.
다른 실험과의 비교
cssDoom은 비전통적인 Doom 포트의 연장선입니다. 이전에 Adam Rice가 Doom Over DNS를 개발했습니다. 이 게임은 Cloudflare DNS TXT 레코드를 통해 실행됩니다. WAD 파일이 ~1964개의 레코드로 압축되어 PowerShell 스크립트가 실시간으로 압축 해제합니다. .NET DLL은 디스크에 쓰지 않고 메모리에 로드됩니다. 이는 프로토콜 한계를 보여주지만, 시각적 복잡도에서는 cssDoom에 미치지 못합니다.
| 항목 | cssDoom | Doom Over DNS |
|--------------|----------------------|---------------------|
| 렌더링 | CSS 3D div | 표준 (브라우저) |
| 로직 | JS (Doom 포트) | PowerShell + .NET |
| 종속성 | CSS/JS만 | DNS 쿼리 |
| 접근성 | GitHub | 공개 Cloudflare 존 |
주요 포인트
- CSS에서 완전한 Doom 렌더링: 3D 공간의 div가 레이캐스팅을 시뮬레이션합니다.
- WAD 데이터로부터 동적 변환을 위한 사용자 정의 속성 + calc().
- 최적화를 위한 JS(로직)와 CSS(시각)의 엄격한 분리.
- 축 반전을 통한 Doom 좌표의 CSS 3D 적응.
- GitHub에서 오픈 소스, GPLv2 라이선스.
이 프로젝트는 게임 개발에서 CSS3의 한계를 연구하는 데 유용합니다. 특히 실시간 시나리오에서의 transform 애니메이션과 사용자 정의 속성입니다.
— Editorial Team
아직 댓글이 없습니다.