モード7は非常にシンプルな効果です。2D x / yテクスチャ(またはタイル)を床/天井に投影します。古いSNESはこれを行うためにハードウェアを使用しますが、最新のコンピューターは非常に強力であるため、このリアルタイムを実行できます(言及したようにASMは必要ありません)。
3Dポイント(x、y、z)を2Dポイント(x、y)に射影するための基本的な3D数式は次のとおりです。
x' = x / z;
y' = y / z;
あなたがそれについて考えるとき、それは理にかなっています。遠くにあるオブジェクトは、近くのオブジェクトよりも小さくなります。どこにも行かない線路について考えてみましょう:
我々は、式の入力値に戻って見れば:x
とy
私たちが処理している現在のピクセルになり、z
ポイントがどれだけ離れているかについての距離情報となります。どうあるz
べきかを理解するには、その写真を見てください。z
上の画像の値が表示されています。
紫=近距離、赤=遠い
したがって、この例では、 z
は値は y - horizon
((x:0, y:0)
画面の中央にあると仮定)です。
すべてをまとめると、(擬似コード)になります。
for (y = -yres/2 ; y < yres/2 ; y++)
for (x = -xres/2 ; x < xres/2 ; x++)
{
horizon = 20; //adjust if needed
fov = 200;
px = x;
py = fov;
pz = y + horizon;
//projection
sx = px / pz;
sy = py / pz;
scaling = 100; //adjust if needed, depends of texture size
color = get2DTexture(sx * scaling, sy * scaling);
//put (color) at (x, y) on screen
...
}
最後に、マリオカートゲームを作成する場合は、マップも回転させたいと思います。まあその非常に簡単:回転しsx
、sy
テクスチャ値を取得する前に。ここに式があります:
x' = x * cos(angle) - y * sin(angle);
y' = x * sin(angle) + y * cos(angle);
マップ内を移動したい場合は、テクスチャ値を取得する前にオフセットを追加するだけです:
get2DTexture(sx * scaling + xOffset, sy * scaling + yOffset);
注:アルゴリズムをテストし(ほぼコピーアンドペースト)、動作します。次に例を示します。http://glslsandbox.com/e#26532.3(最新のブラウザーを必要とし、WebGLのは有効)
注2:私はあなたが単純なものが欲しいと言ったので単純な数学を使用します(そしてベクトル数学に精通していないようです)。ウィキペディアの公式やチュートリアルを使用して、同じことを達成できます。彼らがそれをした方法ははるかに複雑ですが、エフェクトを設定するためのはるかに多くの可能性があります(最終的には同じように動作します...)。
詳細については、読むことをお勧めします:http : //en.wikipedia.org/wiki/3D_projection#Perspective_projection