|
Az FPS és az Ugrások
Az FPS szám a közhiedelemmel ellentétben igenis befolyásolja az ugrásokat, pontosabban azok magasságát. Alább látható egy táblázat, alsó és felső fps értékhatárokkal, melyekhez tartozik egy-egy ugrás-magasság érték. A negyedik oszlopban milliszekundumban látható az az eltelt idő, ami alatt a játékos [az adott fps érték-intervallumban] eléri a harmadik oszlopban feltüntetett maximális magasságot [world unit-ban].
Jó dolog áttanulmányozni, főleg ha eddig nem is tudtuk, hogy miért nem sikerülnek bizonyos trükk-ugrások [pl. t2 telejump, dm6 railjump stb.]
Fontos! Nem szabad megelégednünk a táblázatban található értékek egyszerű elfogadásával! Mayday írását szinte kivétel nélkül mindenkinek kötelező áttanulmányozni (vagy ha bonyolult, akkor legalább egyszer elolvasni)!
| Alsó határ [fps] |
Felső határ [fps] |
Magasság [wu] |
Eltelt idő [ms] |
| 1 |
22 |
63 |
43-66 [Quake által rögzítve 66 ms-nál] |
| 23 |
- |
64 |
42-43 |
| 24 |
25 |
63 |
40-41 |
| 26 |
- |
64 |
38-39 |
| 27 |
29 |
63 |
35-37 |
| 30 |
- |
64 |
33 |
| 31 |
- |
62 |
32 |
| 32 |
34 |
63 |
30-21 |
| 35 |
- |
64 |
28 |
| 36 |
37 |
62 |
27 |
| 38 |
41 |
63 |
25-26 |
| 42 |
43 |
64 |
23-24 |
| 44 |
45 |
62 |
22 |
| 46 |
50 |
63 |
20-21 |
| 51 |
55 |
64 |
18-19 |
| 56 |
58 |
64 |
17 |
| 59 |
62 |
62 |
16 |
| 63 |
66 |
63 |
15 |
| 67 |
71 |
64 |
14 |
| 72 |
76 |
65 |
13 |
| 77 |
83 |
61 |
12 |
| 84 |
90 |
62 |
11 |
| 91 |
100 |
63 |
10 |
| 101 |
111 |
64 |
9 |
| 113 |
125 |
66 |
8 |
| 126 |
142 |
60 [!] |
7 |
| 143 |
166 |
61 |
6 |
| 167 |
200 |
63 |
5 |
| 201 |
250 |
66 + bug |
4 |
| 251 |
333 |
72 [!!!] |
3 |
| 334 |
500 |
<=54 |
2 |
| 501 |
1000 |
<=52 - bug |
1 [egyáltalán nincs air control!] |
| 1001 |
- |
fagyás... |
<1 [nem működik!] |
Mértékegységek:
ms = [milliszekundum] 1/1000 sec, egy ezred másodperc
wu = [world units] ilyen egységekben méri a Quake3 a távolságot horizontálisan és vertikálisan
fps = [frame per second] a másodpercenként kirajzolt képkockák száma. Jelen esetben az "ms" érték fontosabb, mint az "fps" érték!
Megjegyzés:
A framerate-ek csoportosítva vannak, az ugrás magasságára vonatkozólag [pl. ahogy látod, 23 fps a legalsó határ, amivel még elérheted a megahealth-et q3dm13-on]
Emlékeztetés képpen:
A 66 world unit magas ugrással sikerül a t2 telejump. Persze vannak kivételek, bug-os mozgási okokból [lásd: 201-250fps]. 64 world unit kell a megahealth jump-hoz q3dm13-on, vagy a shard-ok eléréséhez ztn3t1-en illetve t2-n.
Nos, ez eddig biztos OK.
Most jöjjön a Mayday féle
- abszolút tudományos és komoly -
oldala a dolognak.
[A most közölt fordítás Coriollisnak (coriollis@hotmail.com)
a www.quake3world.com-on megjelent 'The DEFINITVE fps physics', illetve
az UpsetChaps Quake3 Guideban megtalálható 'Why Your Framerate
Affects Jumping' írásai alapján készült. A forditás
közben bizonyos esetekben (>...) között rövid magyarázó
szövegeket helyeztem el a könnyebb érthetőség érdekében
- Mayday].
Figyelmeztetés: hosszú matematikai jellegű értekezés
képekkel.
Nos, belemerültem a (>q3) forrás kódba, hogy lássam,
hogyan hat az FPS az ugrások magasságára / távolságára.
A 'wu' -t mint quake3 world unit (>quake3 virtuális világbeli
egység) definiálom. A forrásból az alábbi
konstansokat kaptam:
Gravitáció : 800 wu / s2 (>wu / másodperc a négyzeten)
Futási sebesség : 320 wu / s
Ugrási sebesség : 270 wu / s
A quake3-nak a sebességedet egy elég darabos lineáris
közelitéssel kell modelleznie az aktuális pályagörbéhez
viszonyitva, köszönhetően a pillanatnyi korlátozott ismeretnek.
Különösen akkor, amikor az nem is sejti, hogy falnak, lövedéknek,
más játékosnak fogsz ütközni, vagy pl. ugrásközbeni
gyorsitást fogsz alkalmazni irányváltáshoz. Ez
azt jelenti, hogy nem tudja előrejelezni a teljes pályavonalat, csak
előrevisz annak mentén; csak a pillanatnyi irányitást
látja, és egy időközzel visz előbbre azon az útvonalon.
Ez az időköz (>másodpercekben mérve) kb. 1 / képkirajzolások
száma. Az időköz mindig kevesebb mint 0.066 másodperc.
Még arra is rájöttem, hogy ha a g_syncronousClients 0,
akkor a szerver a kliens képkirajzolási idejét használja,
hogy az ebből adódó időközzel megjósolja a kliens
mozgását. Ez valószinűleg azért van igy, hogy
biztositsa a konzisztenciát a kliens és a szerver között.
Ez döntő jelentőségű a képkirajzolási idő függő
ugrások működéséhez.
Emlékezzünk vissza fizikából arra a tényre,
hogy a gravitáció egy gyorsuló mozgást eredményez.
Ez a z irányú (>x y z Descartes-koordináta rendszert
feltételezve, ahol x és y a vizszintes sikot fedi le) függőleges
gyorsulási vektorod mentén hat. A quake3 egy átlagos
függőleges gyorsulási sebességet használ minden
időközben, hogy kiszámolja a sebesség megváltozását
az idököz elejéhez és végéhez viszonyitva,
a gravitáció függvényében. Ez nem maximalizálja
az elérhető függőleges sebességet; ahogy én látom,
a levegő hatása nincs figyelembe véve, ezért aztán
nincs is maximalizált végsebesség.
Mindenesetre, szimuláltam a leirtakat lebegőpontos aritmetika használatával.
A végeredmény a következő képen látható:
fekete : ideális röppálya
vörös : 120 fps
zöld : 100 fps
sárga : 85 fps
kék : 80 fps
bibor : 60 fps
cián kék : 40 fps
fehér : 15 fps
Ahogy azt látod, minden röppálya az ideális görbét
követi majdnem tökéletesen. Ez nem egészen az, amit
én vártam. Aztán rájöttem, hogy a quake3
világa (>a quake3 által megjelenitett virtuális térrész)
nem tekinthető folytonosnak (mind idő, mind távolság szempontjából),
inkább önálló időintervallumok és távolságok
összességének, igy aztán megismételtem a
kisérletet, amelyben az időt egész értékekre kerekitettem.
Az előző beállitásokat használva, a következő eredményt
kaptam:
Igy aztán, a képkirajzolási időtől való függőségnek
két oka van:
1. Az aktuális folyamatos függvénnyel leirható
mozgás közelitése lineáris függvénnyel.
2. Kerekitési hibák.
Ezeket sehogy sem lehet kiküszöbölni. Az egyetlen lehetséges
dolog, amit tehetsz, hogy az időközt állandó értéken
próbálod tartani, de az megneheziti a kliens oldali képkirajzolásokat.
Egyik nap kora este Ctrl közölte, hogy elégedetlen volt
az előzőleg adott magyarázatommal azzal kapcsolatban, hogy az fps
miért van hatással az ugrásokra. Így aztán további
kutatásokba kezdtem. Speciálisan ebből a célból
irtam egy MOD-ot, hogy mérni tudjam az ugrásokat.
A felfedezéseim az alábbi lényeges pontokból
állnak:
1. A végsebesség vektorának értékei mindig
egész számokra vannak kerekítve azután, hogy a játékos
mozgását kiszámító kód meghívódik.
Ez a gyors gépek esetén minden képkocka esetén
megtörténik, de sohasem lehet kevesebb, mint másodpercenkénti
20 kiszámolás.
2. Ez a konverzió az (int)x függvénnyel történik,
ahol x egy lebegőpontos szám.
3. A quake3 virtuális értelmezője (vm, qvm) által végzett
kerekítés nem ANSI C kompatibilis. Az ANSI C szabvány szerinti
kerekítés úgy történik, hogy el kell hagyni a
törtrészt (> int(2.7) = 2, int(2.3 ) = 2 ). A quake3 vm-je
a legközelebbi egész számra kerekít (> int(2.7) =
3, int(2.3) = 2 ).
A harmadik pont világosan megmagyarázza, hogy a DLL-es megvalósítások
miért eredményeznek kisebb sebességet és ugrási
magasságot, mint a qvm-es változatok. A qvm-es megvalósításban
a kerekítés a legközelebbi egész számra történik,
igy a számolási hibák mintegy maguktól szűrődnek
ki. A DLL-ekben a kerekítések mindig lefelé történnek,
így a hibák mindig is csökkentik a sebességet, és
csak összeadódnak. A DLL-ek kerekítési hibája
egy, a mozgás során jelentkező plusz súrlódásként
jelenik meg. Úgy gondolom, hogy a DLL-ek ezen hibája úgy
kerülhető meg, hogy újra kell írni a 'SnapVector' makrót
úgy, hogy emulálja a qvm kerekítési eljárását.
Most térjünk vissza az ugrásokhoz. Elméletileg,
a kerekitési hibáknak egy ugrás során maguktól
ki kellene szűrődniük. Ez feltételezi azt is, hogy ezek a fel
és lefelé kerekitések nagy valószinűséggel
azonosak. Viszont a gyakorlatban nem ez áll fenn. Minden képkocka
kirajzolása nagyjából annyi ideig tart, mint az előző.
A sebesség megváltozása egyenlő a gyorsulás és
a képkocka kirajzolási idejének szorzatával. A
gyorsulás a gravitáció függvénye, a gravitáció
pedig állandó. Mivel a képkocka kirajzolási idők
nagyjából állandók, igy a sebesség változása
képkockánként szintén konstansnak tekinthető.
Mivel a kezdősebesség (az új sebesség kiszámolásához
használt) egész számként van tárolva, a
változások pedig nagyjából mindig ugyanakkorák,
egy kb. azonos fps-t feltételezve mindig ugyanazt a kerekitési
hibát kapjuk. állandó fps értéket feltételezve
a q3 kerekitési hibái összegződnek. Bizonyos fps értékek
esetén ezek állandóan felfelé kerekitődnek, mások
esetén pedig állandóak lefelé.
Alapul véve ezt, az ideális fps egy olyan lenne, amely a legnagyobb
azon fps értékek közül, amely esetén a törtrész
közel van a 0.5-hez, de nagyobb annál. A q3 gravitációs
konstansa 800, igy a törtrész a 800/fps hányadosból
adódik, és ennek kell 0.5-nél nagyobbnak lennie. Azért,
hogy védve legyél az fps ingadozások ellen, egy olyat
garantáltat kell találni, amelynél ez a 0.5-hez közeli,
annál nagyobb törtrész meg van. Viszonylag sok lehetséges
fps érték jöhet szóba, azért, hogy az elvárt
legnagyobb ilyen kerekitési hibából adódó
pozitiv hiba megjelenjen.
A következő táblázatban az egyes oszlopokban az alábbi
értékek találhatóak:
(1) fps, (2) a 800/fps osztásból a törtrész, (3)
a képkockák száma 0.675 másodperc alatt, (4) 0.675
másodperc alatt a maximális pozitiv kerekitési hibák
száma.
A táblázatban az összes fps érték megtalálható
20 és 200 között (ahol a törtrész nagyobb 0.5-nél):
23 0.78 15 3.26
26 0.77 17 3.92
27 0.63 18 6.67
28 0.57 18 7.71
29 0.59 19 7.86
30 0.67 20 6.67
31 0.81 20 3.87
34 0.53 22 10.35
35 0.86 23 3.29
37 0.62 24 9.08
39 0.51 26 12.67
41 0.51 27 13.17
43 0.60 29 11.47
45 0.78 30 6.67
48 0.67 32 10.67
51 0.69 34 10.67
54 0.81 36 6.67
55 0.55 37 16.82
58 0.79 39 8.07
59 0.56 39 17.19
62 0.90 41 3.97
63 0.70 42 12.67
67 0.94 45 2.69
68 0.76 45 10.59
69 0.59 46 18.67
73 0.96 49 2.01
74 0.81 49 9.27
75 0.67 50 16.67
76 0.53 51 24.16
81 0.88 54 6.67
82 0.76 55 13.41
83 0.64 56 20.24
84 0.52 56 26.67
89 0.99 60 0.67
90 0.89 60 6.67
91 0.79 61 12.74
92 0.70 62 18.87
93 0.60 62 24.67
94 0.51 63 30.83
101 0.92 68 5.39
102 0.84 68 10.67
103 0.77 69 16.08
104 0.69 70 21.54
105 0.62 70 26.67
106 0.55 71 32.15
115 0.96 77 3.35
116 0.90 78 8.07
117 0.84 78 12.67
118 0.78 79 17.41
119 0.72 80 22.18
120 0.67 81 27.00
121 0.61 81 31.46
122 0.56 82 36.30
123 0.50 83 41.16
134 0.97 90 2.69
135 0.93 91 6.74
136 0.88 91 10.71
137 0.84 92 14.77
138 0.80 93 18.87
139 0.76 93 22.75
140 0.71 94 26.86
141 0.67 95 30.99
142 0.63 95 34.79
143 0.59 96 38.94
144 0.56 97 43.11
145 0.52 97 46.83
161 0.97 108 3.35
162 0.94 109 6.73
163 0.91 110 10.12
164 0.88 110 13.41
165 0.85 111 16.82
166 0.82 112 20.24
167 0.79 112 23.47
168 0.76 113 26.90
169 0.73 114 30.36
170 0.71 114 33.53
171 0.68 115 36.99
172 0.65 116 40.47
173 0.62 116 43.58
174 0.60 117 47.07
175 0.57 118 50.57
176 0.55 118 53.64
177 0.52 119 57.15
A táblázat elkészitéséhez az alábbi
C++ kódot használtam:
#include <stdio.H>
int main(int argc, char* argv[])
{
for( int i=20; i<300; i++ )
{
double f = 800.0 / i;
int ipart = (int)f;
double fpart = f - ipart;
if( fpart > 0.5f )
{
printf( "%3d %.2f %3d %6.2f\n", i, fpart, (int)(i * .675), (1.0-fpart)
* (int)(i*.675) );
}
}
return 0;
}
Összevetve az elvárásainkat a táblázat
eredményeivel, előre megmondható, hogy a legmegfelelőbb fps
értékek azok, amelyek a 29,41,83,92,120,140 és a 170
környékén vannak. Megjegyzem, hogy ezek az értékek
elég közel vannak azokhoz az értékekhez, amelyet
mások kisérletezgetéssel kaptak. Az elmélet és
a gyakorlat ilyen hasonlósága hitelt ad a használt modellnek...
Aztán tovább törtem a fejem.
A q3 egy képkocka ezredmásodpercekben mért kirajzolási
idejét egész számként tárolja. Ez azt jelenti,
hogy csak bizonyos fps értékek adódhatnak emiatt... speciálisan,
az fps nem más mint 1000 / N, ahol N az ezredmásodperc érték.
Ha ezt adottnak tekintjük, az alábbi lehetséges fps értékek
adódnak variálva N lehetséges értékeit:
200
166-167
142-143
125
111-112
100
90-91
83-84
76-77
71-72
66-67
62-63
58-59
55-56
52-53
50
47-48
45-46
43-44
41-42
40
38-39
37-38
35-36
34-35
33-34
32-33
31-32
30-31
29-30
28-29
27-28
26-27
25-26
25
24-25
23-24
22-23
21-22
20-21
20
Ahol egy sorban több érték is szerepel, azok olyan
értékek, amelyek nem osztói az 1000-nek, igy pl.
nem kaphatsz pontosan 142 v. 143 fps értéket, hanem e kettő
között fog ugrálni.
Igy aztán, amikor a com_maxfps által tesztelendő
értékekről beszélünk, csak az alább
felsoroltakat érdemes kipróbálni:
200
166
142
125
111
100
90
83
76
71
66
62
58
55
52
50
47
45
43
40-41
37-38
20-35
Eddig a cikk. Akik esetleg elvesztek a cikk olvasása közben, röviden összefoglalnám nekik az olvasottakat:
- Játék közben a q3 a virtuális térben (ami maga a pálya) történő elméletileg folyamatos mozgást időben és térben nem folyamatos mozgás elemekből épiti fel.
- Minden egyes új pozició kiszámitásához alapul veszi az aktuális poziciót és irányvektorokat, valamint az irányitó eszközök (billentyű, egér, stb.) állapotát.
- A számolás folyamán a végeredmény eltér az elméletileg várt tényleges értéktől: lineáris függvényeket használ, illetve az eredményeket egész számként tárolja, vagyis levágja a törtrészt, mégpedig úgy, hogy a legközelebbi egész számra kerekit. Ez felfelé kerekités esetén növekedést, lefelé kerekités esetén csökkenést eredményez
az ugrás magasságában és távolságában.
- Olyan, viszonylag stabil FPS értéket kell produkálni játék közben, amely esetén mindig felfelé kerekités történik, vagyis a kerekités előtti törtrésznek 0.5 felett kell lennie, de minél közelebb ahhoz.
- A q3 a képkockák kirajzolásának idejét nem közvetleül FPS-ben méri, hanem ezredmásodpercben kifejezve egy képkocka kirajzolásának idejét. Ebből számolja ki a képernyőre is kiiratható FPS értéket. Ha egy képkocka kirajzolási ideje N ezredmásodpercig tartott, akkor 1 másodperc (1000
ezredmásodperc) alatt 1000 / N képkocka rajzolható ki. Mivel az osztás végeredménye szintén egész szám, csak bizonyos FPS értékek jöhetnek ki ennek eredménye képpen (ha pl. beirod, hogy com_maxfps 92, ennek ellenére be fog villanni a 100 FPS, mivel a 92 egy nem lehetséges FPS érték, a belső számláló túlfut, és megáll a következő lehetségesnél, a 100-nál) .
- Egy adott grafikai konfiguráció mellett végezz egy timedemo mérést (timedemo 1, com_maxfps 0). Nézd meg a kapott FPS értéket, és válassz a táblázatból egy ennél kisebb lehetséges FPS értéket, és az legyen a com_maxfps. És, ami fontos: kisérletezz az egyes lehetséges FPS értékekkel.
|