3D megjelenítés
Az első alap dolog, amit tudnunk kell az, hogy hogyan lehet egy 3D-s pontot leképezni a 2D-s képernyőre.
Azt tudnunk kell, hogy az egész 3D-t úgy kell elképzelni, mintha egy ablakon (képernyőn) néznénk ki, csak azt kell kiszámolni, hogy a képernyőn hol látszana a pont. Ha tényleg kinéznénk. Ha minden pontot leképeztünk, akkor kész a 3D-s ábra. Ennyi.
Láthatjuk, hogy egy egyszerű párhuzamos szelők tételéből ki lehet hozni azt, hogy hol lesz a pont. Csupán az x és y koordinátákat kell megszorozni z/d-vel, és meg is van a koordináta. A pontot már csak el kell tolni, hogy a távolabbi pontok képe a képernyő közepe felé tartson.
Elég lesz a következő képleteket kiszámolni:
Vagy transzformációs mátrixszal:
Itt lx és ly a képernyőfelbontásának a fele.
Lényegében ennyi. Elég egyszerű.
A vonalak rajzolása nem okoz különösebb problémát 3D-ben. Elég egyszerűen kiszámolni a két végpontot, majd egyenes vonallal összekötni őket.
Ha az alakzat egyszínű, akkor a csúcspontok kiszámolása után csak egyszerűen a poligonrajzoló eljárással megrajzoljuk a sokszöget.
Textúrázás
Ha nem csak egyszínű poligonokkal akarunk dolgozni, hanem szeretnénk a poligonokra alakzatot is feszíteni, akkor textúráznunk kell.
A textúrázásnak sokféle módja van.
Kezdjük a legegyszerűbbel.
Bizonyára mindenki észrevette, hogy régi kezdetleges 3D-s játékokban csak és kizárólag függőleges és vízszintes falak vannak. Továbbá csak téglalap alakúak. Nyilván azért, mert ezeket a legegyszerűbb megjeleníteni.
Vegyünk egy függőleges falat. A hozzánk közelebbi és távolabbi része is ugyanolyan magas, azonban a távolabbi oldala kisebbnek látszik. Ily módon van egy trapézunk, amelynek párhuzamos oldalai függőlegesek, ezért könnyű textúrát feszíteni rá.
Elkezdjük a falat a bal oldalánál render-elni, közben folyamatosan figyeljük, hogy mikor lépünk egy oszloppal arrébb a textúrában. Mindig egy pixelnyi oszloppal lépünk előre, és pixelenként rajzoljuk ki a falat. Az eljárás addig tart, amíg eljutunk a trapézunk jobb oldaláig.
Az renderelő eljárás pszeudokódja (azoknak, akik leakarják ezt programozni):
Paraméterek:
Left: a trapéz bal oldalának X koordinátája
Right: a trapéz jobb oldalának X koordinátája
lt: a trapéz bal felső sarkának Y koordinátája
lb: - || - bal alsó - || -
rt: - || - jobb felső - || -
rb: - || - jobb alsó - || -
lz: a trapéz bal oldalának távolsága (Z koordinátája)
rz: a trapéz jobb oldalának Z koordinátája (az lz-ből is kiszámolható!)
tw: textúra oszlopok száma (példánkban ez 5)
th: textúra sorainak száma (ez is 5 itt)
txw: textúra kép szélessége (pixel)
txh: textúra kép magassága (pixel)
tdata: textúrát tartalmazó tömb
Megjegyzések:
Ha tw>txw vagy th>txh, akkor az eljárás a megadott falat kicsempézi a megadott textúrával.
Az X és Y koordináták képernyő-koordinátákban értendők, míg a Z koordináta továbbra is világkoordináta.
ELJÁRÁS Render(Left,Right,lt,lb,rt,rb,lz,rz,d,tw,th,tdata[0..txw-1][0..txh-1])
HA Left=Right AKKOR
ELJÁRÁS MEGSZAKÍTÁS
ELÁGAZÁS VÉGE
HA Left>Right AKKOR
Left<=>Right (Értékcsere)
lt<=>rt
lb<=>rb
ELÁGAZÁS VÉGE
HA lt>lb AKKOR lt<=>lb
HA rt>rb AKKOR rt<=>rb
zdiff:=rz-lz
xdiff:=Right-Left
ytdiff:=rt-lt
ybdiff:=rb-lb
klz:=d/lz
krz:=d/rz
zstep:=zdiff/tw
ytstep:=ytdiff/xdiff
ybstep:=ybdiff/xdiff
xstep:=xdiff/tw
CurrentZ:=lz+zstep
HA kdiff<>0 AKKOR
NextX:=Right-(d/CurrentZ-krz)/kdiff*xdiff
KÜLÖNBEN
NextX:=Left+xstep
ELÁGAZÁS VÉGE
CurrentX:=0
ystart:=lt
yend:=lb
CIKLUS i:=Left-TŐL Right-IG
HA i<0 AKKOR
ystart:=ystart-i*ytstep
yend:=yend-i*ybstep
i:=0
ELÁGAZÁS VÉGE
HA i>FelbontásX AKKOR
ELJÁRÁS MEGSZAKÍTÁS
ELAGAZÁS VÉGE
CIKLUS AMÍG i>NextX
CurrentX:=CurrentX+1
HA kdiff<>0 AKKOR
CurrentZ:=CurrentZ+zstep
NextX:=Right-(d/CurrentZ-krz)/kdiff*xdiff
KÜLÖNBEN
NextX:=Left+(CurrentX+1)*xstep
ELÁGAZÁS VÉGE
HA CurrentX>=tw AKKOR
CurrentX:=tw-1
CIKLUS MEGSZAKÍTÁS
ELÁGAZÁS VÉGE
CIKLUS VÉGE
ystart:=ystart+ytstep
yend:=yend+ybstep
ysediff:=(yend-ystart)/th
tyc:=0
CIKLUS j:=ystart-TÓL yend-IG
HA j<0 AKKOR
tyc:=tyc-j
j:=0
ELÁGAZÁS VÉGE
HA j>FelbontásY AKKOR
CIKLUS MEGSZAKÍTÁS
ELÁGAZÁS VÉGE
tyc:=tyc+1
CurrentY:=Kerekít(tyc/ysediff)
PixelBeállít(i,j,tdata[CurrentX MOD txw][CurrentY MOD txh])
CIKLUS VÉGE
CIKLUS VÉGE
ELJÁRÁS VÉGE
Egy kis optimalizálás után ez az eljárás elég gyors lehet ahhoz, hogy akár egy DOOM-szerű játékban a falak megjelenítésére lehessen használni.
Persze tovább is fejleszthető. (Például átlátszó részek, eltolt kép, elforgatott textúra stb.)