Modalità 7 è un effetto molto semplice. Proietta una trama (o piastrelle) 2D x / y su un pavimento / soffitto. I vecchi SNES usano l'hardware per fare questo, ma i computer moderni sono così potenti che puoi farlo in tempo reale (e non hai bisogno di ASM come dici).
La formula matematica 3D di base per proiettare un punto 3D (x, y, z) su un punto 2D (x, y) è:
x' = x / z;
y' = y / z;
Quando ci pensi, ha senso. Gli oggetti lontani sono più piccoli degli oggetti vicini a te. Pensa ai binari della ferrovia che non vanno da nessuna parte:
Se guardiamo indietro ai valori di input della formula: x
e y
sarà il pixel corrente che stiamo elaborando e z
saranno le informazioni sulla distanza su quanto dista il punto. Per capire cosa z
dovrebbe essere, guarda quell'immagine, mostra i z
valori per l'immagine sopra:
viola = vicino distanza, rosso = lontano
Quindi, in questo esempio, il z
valore è y - horizon
(assumendo(x:0, y:0)
sia al centro dello schermo)
Se mettiamo tutto insieme, diventa: (pseudocodice)
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
...
}
Un'ultima cosa: se vuoi creare un gioco di Mario Kart, suppongo che tu voglia anche ruotare la mappa. Beh, è anche molto semplice: ruotare sx
e sy
prima di ottenere il valore della trama. Ecco la formula:
x' = x * cos(angle) - y * sin(angle);
y' = x * sin(angle) + y * cos(angle);
e se vuoi spostarti attraverso la mappa, aggiungi un po 'di offset prima di ottenere il valore della trama:
get2DTexture(sx * scaling + xOffset, sy * scaling + yOffset);
NOTA: ho testato l'algoritmo (quasi copia-incolla) e funziona. Ecco l'esempio: http://glslsandbox.com/e#26532.3 (richiede un browser recente e abilitato WebGL)
NOTA 2: uso la matematica semplice perché hai detto che vuoi qualcosa di semplice (e non mi sembra familiare con la matematica vettoriale). Puoi ottenere le stesse cose usando la formula di Wikipedia o i tutorial che dai. Il modo in cui lo hanno fatto è molto più complesso ma hai molte più possibilità di configurare l'effetto (alla fine funziona allo stesso modo ...).
Per ulteriori informazioni, suggerisco di leggere: http://en.wikipedia.org/wiki/3D_projection#Perspective_projection