概要
- CSS のみで DOOM のレンダリングを実現した技術解説
- 3D空間 での配置や計算を CSSカスタムプロパティ と 関数 で処理
- ゲームロジック はJavaScript、 描画 はCSSが担当
- DOOM座標系 と CSS 3D座標系 の変換・工夫
- アニメーション や テクスチャ の工夫も紹介
CSSでDOOMを構築した理由と経緯
- CSSの進化 を体感・証明するためのプロジェクト
- 壁・床・オブジェクト すべてを <div> で表現、 CSS transforms で3D配置
- ゲームロジック はJavaScript、 描画処理 はCSSのみで完結
- 限界への挑戦 と ブラウザの可能性の追求
- Github でソースコード公開
技術的なアプローチ
- DOOMのオリジナルデータ (頂点・ライン・セクター等)を抽出・利用
- 各壁・床 に DOOM座標 をカスタムプロパティとして付与
- 3D変換・幅・回転角 などは CSS関数 (hypot(), atan2()等)で計算
- JavaScript はWADデータの受け渡しとゲームループのみ担当
- CSS が三角関数・幾何計算を担う分業体制
DOOM座標系とCSS 3D座標系の対応
- DOOM座標系 :Y軸が北方向に増加する2Dシステム
- CSS 3D座標系 :Y軸が上方向、Z軸が手前方向
- translate3d(x, -z, -y) で座標を変換
- rotateY(atan2(Δy, Δx)) で壁の回転を自然に実装
- 座標変換の最小化 でシンプルな実装
カメラの代わりに世界を動かす手法
- CSSにはカメラ機能がない ため、 プレイヤーの移動=世界の反転移動
- --player-x, --player-y, --player-z, --player-angle の4つのカスタムプロパティで管理
- #scene に対して transform で逆方向に移動・回転を適用
- perspective 補正のために translate: 0 0 var(--perspective) を追加
- 移動・視点変更 は4つの値を更新するだけで完結
床・天井の表現とクリッピング
- 床は<div>をrotateX(90deg) で水平に配置
- clip-path: polygon() で多角形・不規則な形状にカット
- clip-path: path() と evenodd で穴あきや複雑な床も表現
- shape() の利用でパス定義を自然言語的に記述可能
- SVGパス による柔軟なクリッピング
テクスチャのタイル・整列
- 隣接セクター間のテクスチャ連続性 を確保
- background-position にワールド座標を使用し、全体で一貫したパターン
- 各<div>の配置座標 に応じてテクスチャ基点を調整
- background-size/repeat でDOOMらしいタイル表現
ドアやリフトのアニメーション
- ドア開閉 は 親<div> の transform を transition で滑らかにアニメーション
- state属性 の切り替えでCSSアニメーションを制御、JavaScriptループ不要
- リフト では --player-z も連動して更新、プレイヤーの上下移動を実現
- @property でカスタムプロパティを型登録し、スムーズなトランジションを可能化
- JavaScriptとCSSアニメーション の同期で自然な動きを演出
まとめ:CSSの可能性と今後
- ゲームレンダリング がCSSのみで実現可能な時代
- CSS関数・カスタムプロパティ・clip-path 等の進化が鍵
- JavaScriptは最小限、 CSSが主役 の新しいWeb表現
- CSSの限界を探る実験的プロジェクト としての価値
- 今後のCSS進化 とWeb表現の未来への期待