アットウィキロゴ

Mode 7

Mode 7は、スーパーファミコン(SNES)で背景レイヤーを回転・拡大縮小・投影変換するグラフィック機能。
2Dグラフィックを擬似的に3D空間のように表現し、当時のゲーム(F-ZERO、マリオカートなど)に奥行き感や高速な視点移動をもたらした重要な技術です。


主な特徴と効果

回転と拡大縮小
背景の1レイヤーに対して自由な回転とスケーリングをスキャンライン単位で実行可能。
擬似3D表現
背景を水平面として描写し、奥のものを小さく、手前のものを大きくすることでパースペクティブ(遠近法)を再現。
テクスチャマッピング
2D画面を3D空間に見せるため、床面にテクスチャ(画像)を貼り付けたような効果を生成。
歴史的背景
1990年代初頭のスーパーファミコンの看板技術であり、任天堂のライバル機に対する強力な強みとなった。
主にレースゲーム(マリオカート、F-ZERO)やシューティングゲーム(スターフォックスなど)の舞台となる地面の描写に使用された。
技術的な詳細
スキャンラインベースの処理により、各行の描写ごとにパラメータ(行列)を変化させることで、複雑な回転・拡大縮小を1画面内で組み合わせる。
特殊な構造: 256色の背景レイヤーを回転・縮小し、VRAM上に1024x1024ピクセルのタイルマップとして管理。

Playdateにおける "Mode 7" の実装方法

Playdateの1ビット画面と限られたCPUリソース(Cortex-M7)で、スーパーファミコンの「Mode 7」のような擬似3D背景を実装する場合、「水平スキャンラインごとのアフィン変換」と「テクスチャの水平スライス」が現実的なアプローチになります。
Playdateにはハードウェアによるスプライトのスケーリングや回転の支援はありますが、背景レイヤー全体を3D投影する専用機能はないため、ソフトウェア側で工夫が必要です。
1. 基本的なレンダリングの仕組み
Mode 7の視覚効果は、2Dのタイルマップを遠近法(パースペクティブ)に基づいて変形させることで実現します。画面上の各行(スキャンライン) y方向 に対して、以下の手順を適用します。
1. 距離(スケール)の計算
画面下部ほど自機に近く(拡大)、上部ほど遠い(縮小)ため、行ごとに垂直方向のスケール $z$ を算出します。
2. テクスチャ座標の決定
算出した "z" に基づいて、ソース画像(背景タイルマップ)からサンプリングする座標の開始点と移動ベクトルを求めます。
3. 描画
1行分のピクセルを画面に転送します。

2. Lua SDK での実装:水平スライス法
Luaでピクセル単位のループを回すと処理落ちするため、画像を「1ピクセル高さの横長スライス」として扱い、SDKの drawSampledBitmap や drawWithTransform を利用するのが効率的です。
実装手順は以下の通りです。
画像の分割
背景となる大きな画像を、1ピクセル高さの `playdate.graphics.image` の配列として保持します。
スキャンラインごとの描画
  • 画面の Y座標ごとに、その行が表現する「擬似的な奥行き」を計算します
  • playdate.graphics.drawSampledBitmap を使い、ソース画像の特定行をスケーリング・オフセットして描画します
-- 擬似コードのイメージ
for screenY = horizon, displayHeight do
    local z = focalLength / (screenY - horizon)
    local width = textureWidth * z
    local xOffset = (displayWidth - width) / 2 + scrollX * z
 
    -- 特定の行(スライス)を拡大縮小して描画
    imageSlices[textureY]:drawSampled(xOffset, screenY, width, 1)
end

3. C SDK での実装:直接バッファ操作
最高のパフォーマンスを求めるなら、C言語による直接的なフレームバッファ操作が推奨されます。
固定小数点演算の活用
PlaydateのCPUは浮動小数点演算も可能ですが、スキャンライン内のピクセルループでは固定小数点(Fixed-point)を使用することで、演算コストを最小限に抑えられます。
インクリメンタルな座標更新
各ピクセル "x" において、テクスチャ座標 "(u, v)" を以下の形式で更新します。
  • u_{x+1} = u_x + du
  • v_{x+1} = v_x + dv
ここでの "du, dv" はその行における回転とスケールに基づく定数です。

4. Playdate特有の最適化と制約
PlaydateでMode 7を「らしく」見せるためのテクニックです。
1ビット画面とディザリング
  • 遠くの景色が単色で塗りつぶされると距離感が失われます。
  • 距離 "z" に応じてディザリングのパターン(playdate.graphics.setDitherType)を切り替えると、1ビットでも擬似的な霧(フォグ)やグラデーションを表現でき、奥行きが強調されます。
ルックアップテーブル(LUT)の利用
  • "1 / z" の計算や "sin/cos" の計算は重いため、あらかじめ配列に計算結果を格納しておく(LUT化する)ことで、実行時の負荷を大幅に削減できます。
クランク(Crank)との連動
クランクの回転角をアフィン変換行列の回転パラメータ(θ)に直接代入することで、F-ZEROのような急旋回操作を直感的に実装できます。

推奨される学習リソース
Playdateコミュニティでは、この種の手法を「Mode 7-style scaling」や「Pseudo-3D floor」と呼びます。SDKに同梱されているサンプルコードや、GitHub上の Playdate-Samples にある描画最適化の例を参考にすると、実装のヒントが見つかりやすいはずです。

関連ページ

最終更新:2026年05月04日 15:24