01.08.2013 Views

Ray Tracing op GPU en CPU - EDM - UHasselt

Ray Tracing op GPU en CPU - EDM - UHasselt

Ray Tracing op GPU en CPU - EDM - UHasselt

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Ray</strong> <strong>Tracing</strong> <strong>op</strong> <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong><br />

Thesis voorgedrag<strong>en</strong> tot het behal<strong>en</strong> van de graad van Lic<strong>en</strong>tiaat in de<br />

Informatica / Master in de Informatica / Doctorandus in de<br />

K<strong>en</strong>nistechnologie, afstudeervariant Multimedia<br />

Yannick Franck<strong>en</strong><br />

Promotor: Prof. dr. Philippe Bekaert<br />

Begeleiders: Erik Hubo, Bert De Decker<br />

Academiejaar 2004-2005


Inhouds<strong>op</strong>gave<br />

1 Inleiding 2<br />

2 Achtergrond 4<br />

2.1 R<strong>en</strong>dering vergelijking . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

2.2 <strong>Ray</strong> tracing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.2.1 Algoritme . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.2.2 Eig<strong>en</strong>schapp<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

3 Grafische hardware 15<br />

3.1 Geschied<strong>en</strong>is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

3.2 Graphics pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

3.2.1 Applicatie . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

3.2.2 Geometrie verwerking . . . . . . . . . . . . . . . . . . . . 17<br />

3.2.3 Rasterisatie . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

3.3 <strong>GPU</strong> versus <strong>CPU</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

4 <strong>GPU</strong> programmer<strong>en</strong> 20<br />

4.1 Stream programming model . . . . . . . . . . . . . . . . . . . . . 20<br />

4.2 Voorbeeldtaal: Cg . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

4.2.1 Kernels . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

4.2.2 Input <strong>en</strong> output stream . . . . . . . . . . . . . . . . . . . 22<br />

4.2.3 Read-only geheug<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . 24<br />

4.2.4 Voorbeeld vertex <strong>en</strong> fragm<strong>en</strong>t shader . . . . . . . . . . . . 25<br />

4.3 G<strong>en</strong>eral Purpose <strong>GPU</strong> programmer<strong>en</strong> . . . . . . . . . . . . . . . 27<br />

4.4 Moeilijkhed<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

5 Implem<strong>en</strong>tatie 29<br />

5.1 Gegev<strong>en</strong>sstructur<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

5.1.1 Mesh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

5.1.2 Normal<strong>en</strong> <strong>en</strong> kleur<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . 33<br />

5.1.3 Regular grid . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

5.2 Algoritm<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.2.1 <strong>CPU</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

5.2.2 <strong>GPU</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

5.2.3 Converter<strong>en</strong> <strong>GPU</strong> naar <strong>CPU</strong> . . . . . . . . . . . . . . . . 42<br />

i


6 Resultat<strong>en</strong> 45<br />

6.1 Systeemspecificatie . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

6.2 Model beschrijving<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

6.3 R<strong>en</strong>dertijd<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

6.3.1 Verschill<strong>en</strong>de configuraties . . . . . . . . . . . . . . . . . . 47<br />

6.3.2 Tiled r<strong>en</strong>dering . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

6.4 Mogelijke verklaring<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

6.4.1 Configuraties . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

6.4.2 Tiled r<strong>en</strong>dering . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

6.5 Vergelijking van conditionele structur<strong>en</strong> . . . . . . . . . . . . . . 56<br />

6.5.1 SISD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />

6.5.2 SIMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

6.6 Scre<strong>en</strong>shots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

7 Toekomstig werk 68<br />

8 Conclusie 69<br />

A Vertex-driehoek coher<strong>en</strong>tie 70<br />

ii


Lijst van figur<strong>en</strong><br />

2.1 Verdeling van invall<strong>en</strong>d licht, hoek 0 radiaal . . . . . . . . . . . . 5<br />

2.2 Verdeling van invall<strong>en</strong>d licht, hoek π/3 radiaal . . . . . . . . . . 5<br />

2.3 Naïef foton<strong>en</strong>-schiet algoritme . . . . . . . . . . . . . . . . . . . . 7<br />

2.4 <strong>Ray</strong> tracing algoritme . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

2.5 Parameters voor primaire stral<strong>en</strong> . . . . . . . . . . . . . . . . . . 10<br />

2.6 Reflecter<strong>en</strong> van stral<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.7 Parameters voor reflectieformule . . . . . . . . . . . . . . . . . . 11<br />

2.8 Gerefracteerde stral<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

2.9 Spatiale subdivisie structur<strong>en</strong> . . . . . . . . . . . . . . . . . . . . 14<br />

3.1 Graphics pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

4.1 Stream Programming Model schema . . . . . . . . . . . . . . . . 21<br />

4.2 Stream Programming Model schema voor de <strong>GPU</strong> . . . . . . . . 22<br />

4.3 Scre<strong>en</strong>shot refractie b<strong>en</strong>adering in Cg . . . . . . . . . . . . . . . 25<br />

5.1 Voorbeeld van e<strong>en</strong> mesh . . . . . . . . . . . . . . . . . . . . . . . 30<br />

5.2 Functieverlo<strong>op</strong> 3a<br />

5.3<br />

3+a . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

Texturelayout voor de driehoek<strong>en</strong> . . . . . . . . . . . . . . . . . .<br />

31<br />

32<br />

5.4 Texturelayout voor de normal<strong>en</strong> <strong>en</strong> kleur<strong>en</strong> . . . . . . . . . . . . 33<br />

5.5 Regular grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

5.6 Lijst van driehoek<strong>en</strong>verzameling<strong>en</strong> . . . . . . . . . . . . . . . . . 35<br />

5.7 Regular grid textures . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

5.8 3D scanconversie van driehoek<strong>en</strong> <strong>en</strong> bounding boxes . . . . . . . 38<br />

5.9 Regular gird doorl<strong>op</strong><strong>en</strong> . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

5.10 Driehoekintersectie buit<strong>en</strong> de voxel . . . . . . . . . . . . . . . . . 40<br />

6.1 R<strong>en</strong>dertijd<strong>en</strong> per pixel . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

6.2 R<strong>en</strong>dertijd<strong>en</strong> per frame in ms. . . . . . . . . . . . . . . . . . . . . 48<br />

6.3 Volgorde van pixel-inkleuring . . . . . . . . . . . . . . . . . . . . 49<br />

6.4 If-structur<strong>en</strong> gridtraversie . . . . . . . . . . . . . . . . . . . . . . 57<br />

6.5 Kost<strong>en</strong> if-structur<strong>en</strong> gridtraversie . . . . . . . . . . . . . . . . . . 58<br />

6.6 Kost<strong>en</strong> ge<strong>op</strong>timaliseerde if-structur<strong>en</strong> gridtraversie . . . . . . . . 62<br />

6.7 Axe (800 × 600) . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

6.8 Gnome (800 × 600) . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

6.9 Bed (800 × 600) . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

6.10 Bed (1024 × 768) . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

6.11 Truck (1024 × 768) . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

6.12 Tafel (1024 × 768) . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

iii


6.13 Kerk (1024 × 768) . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

6.14 Bugatti met time-outs (1024 × 768) . . . . . . . . . . . . . . . . 67<br />

iv


Lijst van tabell<strong>en</strong><br />

6.1 Systeemspecificatie . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

6.2 Modelinformatie . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

6.3 R<strong>en</strong>dertijd<strong>en</strong> <strong>op</strong> de <strong>CPU</strong> . . . . . . . . . . . . . . . . . . . . . . . 47<br />

6.4 R<strong>en</strong>dertijd<strong>en</strong> <strong>op</strong> de <strong>GPU</strong> . . . . . . . . . . . . . . . . . . . . . . . 47<br />

6.5 Snelheidswinst <strong>op</strong> <strong>CPU</strong> door tiled r<strong>en</strong>dering t.o.v. scanlijn r<strong>en</strong>dering<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

6.6 Pad<strong>en</strong>coher<strong>en</strong>tie . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

6.7 Aantal verschill<strong>en</strong>de pad<strong>en</strong> . . . . . . . . . . . . . . . . . . . . . 53<br />

6.8 N-pad<strong>en</strong>coher<strong>en</strong>tie . . . . . . . . . . . . . . . . . . . . . . . . . . 54<br />

6.9 Aantal verschill<strong>en</strong>de n-pad<strong>en</strong> . . . . . . . . . . . . . . . . . . . . 55<br />

6.10 R<strong>en</strong>dertijd<strong>en</strong> per boomstructuur <strong>op</strong> de <strong>GPU</strong> . . . . . . . . . . . . 63<br />

A.1 Vertex-driehoek coher<strong>en</strong>tie . . . . . . . . . . . . . . . . . . . . . . 70<br />

v


Lijst van codefragm<strong>en</strong>t<strong>en</strong><br />

2.1 Pseudocode ray tracing . . . . . . . . . . . . . . . . . . . . . . . 8<br />

4.1 Cg kernel code structuur . . . . . . . . . . . . . . . . . . . . . . . 23<br />

4.2 Cg vertex shader voor refractie . . . . . . . . . . . . . . . . . . . 25<br />

4.3 Cg fragm<strong>en</strong>t shader voor refractie . . . . . . . . . . . . . . . . . . 26<br />

vi


Sam<strong>en</strong>vatting<br />

In deze thesis wordt beschrev<strong>en</strong> hoe e<strong>en</strong> klassieke ray tracer herschrev<strong>en</strong> kan<br />

word<strong>en</strong> voor uitvoering <strong>op</strong> de laatste g<strong>en</strong>eratie grafische hardware. Hiervan<br />

is e<strong>en</strong> voorbeeldimplem<strong>en</strong>tatie gerealiseerd in Cg alsook e<strong>en</strong> analoge versie in<br />

C++, die gebruikt wordt voor e<strong>en</strong> vergelijk<strong>en</strong>de studie.<br />

De Cg versie blijkt tot meerdere mal<strong>en</strong> sneller te zijn dan de hieruit afgeleide<br />

C++ versie. Vooral bij het r<strong>en</strong>der<strong>en</strong> van hogere resoluties is er e<strong>en</strong> beduid<strong>en</strong>de<br />

snelheidswinst <strong>op</strong> de grafische kaart. Dit is naar alle waarschijnlijkheid te wijt<strong>en</strong><br />

aan e<strong>en</strong> meer coher<strong>en</strong>te program flow van de in parallel l<strong>op</strong><strong>en</strong>de programma’s<br />

(fragm<strong>en</strong>t shaders). Wat ook e<strong>en</strong> niet te verwaarloz<strong>en</strong> rol speelt in het voordeel<br />

van de Cg versie, is het feit dat de ray tracer geschrev<strong>en</strong> <strong>en</strong> ge<strong>op</strong>timaliseerd is<br />

in Cg, <strong>en</strong> daarna pas vertaald naar C++.<br />

Indi<strong>en</strong> de grafische kaart<strong>en</strong> blijv<strong>en</strong> evoluer<strong>en</strong> zoals dat nu het geval is, zal het<br />

in de toekomst mogelijk word<strong>en</strong> om e<strong>en</strong> aanzi<strong>en</strong>lijke snelheidswinst te boek<strong>en</strong><br />

inzake ray tracing. Het verwez<strong>en</strong>lijk<strong>en</strong> van e<strong>en</strong> ray tracer <strong>op</strong> de <strong>GPU</strong> zal ook<br />

e<strong>en</strong>voudiger word<strong>en</strong> vanwege de versoepeling van de huidige beperking<strong>en</strong> van<br />

<strong>en</strong>erzijds de grafische kaart, <strong>en</strong> anderzijds de huidige compilers.


Dankwoord<br />

Dit werk zou niet tot stand gekom<strong>en</strong> zijn zonder de hulp van bepaalde m<strong>en</strong>s<strong>en</strong>.<br />

Deze zou ik hiervoor dan ook graag dank toe zegg<strong>en</strong>.<br />

Philippe Bekaert bedank ik voor het promot<strong>en</strong> van deze thesis. Door hem<br />

heb ik interessante weg<strong>en</strong> wet<strong>en</strong> te vind<strong>en</strong> doorhe<strong>en</strong> het doolhof van de literatuur.<br />

Ik heb vrij mijn weg kunn<strong>en</strong> bepal<strong>en</strong>, <strong>en</strong> dit <strong>op</strong> basis van nuttige hints<br />

van de promotor, zonder dat er mij mete<strong>en</strong> e<strong>en</strong> bepaalde uitgang gewez<strong>en</strong> werd.<br />

Hartelijk dank hiervoor.<br />

Bert De Decker <strong>en</strong> Erik Hubo, de c<strong>op</strong>romotors van deze thesis, b<strong>en</strong> ik ook<br />

uitermate dankbaar voor hun hulp. Bij h<strong>en</strong> kon ik steeds terecht voor het stell<strong>en</strong><br />

van vrag<strong>en</strong>, het voer<strong>en</strong> van <strong>op</strong>bouw<strong>en</strong>de discussies <strong>en</strong> het verkrijg<strong>en</strong> van allerlei<br />

“tips and tricks” voor het mak<strong>en</strong> van e<strong>en</strong> thesis. Heel erg bedankt hiervoor.<br />

Hoewel Tom Mert<strong>en</strong>s ge<strong>en</strong> rechstreekse begeleider was voor deze thesis, b<strong>en</strong><br />

ik meermaals met vrag<strong>en</strong> bij hem terecht gekunn<strong>en</strong>, waarvoor ook mijn dank.<br />

Verder zijn er nog verscheid<strong>en</strong>e collega’s die mij geholp<strong>en</strong> hebb<strong>en</strong> bij het<br />

tot stand br<strong>en</strong>g<strong>en</strong> van deze thesis. Hierbij d<strong>en</strong>k ik meer in het bijzonder aan<br />

Nicolas Barbier, Johan Huysmans, Bart Corneliss<strong>en</strong>, Rob Van Dyck <strong>en</strong> Dirk<br />

Vand<strong>en</strong> Boer. Door de gevoerde gesprekk<strong>en</strong>, b<strong>en</strong> ik vaak tot nieuwe inzicht<strong>en</strong><br />

gekom<strong>en</strong>, waarvoor ik h<strong>en</strong> zeer dankbaar b<strong>en</strong>.<br />

Mijn vri<strong>en</strong>din, Tanja, b<strong>en</strong> ik ook zeer dankbaar voor de geleverde steun. Op<br />

de moeilijkere mom<strong>en</strong>t<strong>en</strong> kon ze me steeds weer motiver<strong>en</strong> <strong>en</strong> stimuler<strong>en</strong> om<br />

met volle moed verder te zett<strong>en</strong>.<br />

Uiteindelijk zou ik graag nog alle niet vernoemde m<strong>en</strong>s<strong>en</strong>, die in meer of<br />

mindere mat<strong>en</strong> hebb<strong>en</strong> bijgedrag<strong>en</strong> tot deze thesis, bedank<strong>en</strong>. Ik d<strong>en</strong>k hierbij<br />

aan mijn ouders, familie, vri<strong>en</strong>d<strong>en</strong>, doc<strong>en</strong>t<strong>en</strong>, <strong>en</strong> nog vele ander<strong>en</strong>.<br />

1


Hoofdstuk 1<br />

Inleiding<br />

De laatste jar<strong>en</strong> heeft de grafische hardware e<strong>en</strong> gigantische evolutie gek<strong>en</strong>d.<br />

E<strong>en</strong> belangrijke stuw<strong>en</strong>de kracht hierbij is de game-industrie. Deze hardware<br />

is niet meer <strong>en</strong>kel geschikt voor het rasteriser<strong>en</strong> van driehoek<strong>en</strong>, maar wordt<br />

meer <strong>en</strong> meer gebruikt als algeme<strong>en</strong> programmeerbare hardware. Dit is onder<br />

andere te wijt<strong>en</strong> aan de toeg<strong>en</strong>om<strong>en</strong> (<strong>en</strong> nog steeds to<strong>en</strong>em<strong>en</strong>de) performantie,<br />

programmeerbaarheid <strong>en</strong> precisie van deze hardware.<br />

Het computer graphics domein is ook zeker niet onveranderd geblev<strong>en</strong>. Er<br />

bestaan zulke volledige globale illuminatie modell<strong>en</strong> dat dit domein zelfs niet<br />

meer voor verbetering vatbaar lijkt te zijn. Merk <strong>op</strong> dat verbetering hier<br />

geïnterpreteerd moet word<strong>en</strong> als grafisch van betere kwaliteit zijnde. De tijd<br />

nodig om e<strong>en</strong> fotorealistisch beeld te g<strong>en</strong>erer<strong>en</strong> ligt namelijk nog steeds aan de<br />

hoge kant. Waar er realtime interactiviteit vereist is in 3D applicaties, is er<br />

nog steeds e<strong>en</strong> <strong>op</strong>zettelijke verlaging van de kwaliteit vereist om de r<strong>en</strong>dertijd<br />

te beperk<strong>en</strong>.<br />

In deze thesis wordt er getracht door middel van de grafische hardware<br />

e<strong>en</strong> implem<strong>en</strong>tatie te mak<strong>en</strong> die interactieve r<strong>en</strong>dering toelaat door middel van<br />

klassieke ray tracing.<br />

Per hoofdstuk zal er nu e<strong>en</strong> kort overzicht gegev<strong>en</strong> word<strong>en</strong> van de materie<br />

die er in behandeld wordt:<br />

Hoofdstuk 1: Inleiding Dit hoofdstuk.<br />

Hoofdstuk 2: Achtergrond In dit hoofdstuk zull<strong>en</strong> <strong>en</strong>kele belangrijke, zak<strong>en</strong><br />

waar<strong>op</strong> dit werk steunt, besprok<strong>en</strong> word<strong>en</strong>. Eerst zal de r<strong>en</strong>dering<br />

vergelijking uit de doek<strong>en</strong> word<strong>en</strong> gedaan. Met dit als achtergrond wordt<br />

vervolg<strong>en</strong>s de ray tracing techniek uitgelegd.<br />

Hoofdstuk 3: Grafische hardware Dit hoofdstuk geeft e<strong>en</strong> inleiding tot grafische<br />

hardware. Eerst wordt er geschetst hoe deze hardware de laatste 10<br />

jaar geëvolueerd is. Vervolg<strong>en</strong>s zal de huidige r<strong>en</strong>dering pipeline nader<br />

word<strong>en</strong> toegelicht. Uiteindelijk word<strong>en</strong> de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong> naast elkaar<br />

gezet, <strong>en</strong> word<strong>en</strong> de belangrijkste voor- <strong>en</strong> nadel<strong>en</strong> besprok<strong>en</strong>.<br />

Hoofdstuk 4: <strong>GPU</strong> programmer<strong>en</strong> Dit hoofdstuk handelt over hoe de <strong>GPU</strong><br />

geprogrammeerd kan word<strong>en</strong>. Vooraleer we daar toe kom<strong>en</strong>, zull<strong>en</strong> we de<br />

<strong>GPU</strong> abstraher<strong>en</strong> tot het stream programming model. Vervolg<strong>en</strong>s zull<strong>en</strong><br />

2


we dit mapp<strong>en</strong> <strong>op</strong> e<strong>en</strong> concrete taal, namelijk Cg 1 . Er zal aangehaald word<strong>en</strong><br />

hoe typische shaders, alsook g<strong>en</strong>eral purpose shaders, eruitzi<strong>en</strong> in Cg.<br />

Uiteindelijk word<strong>en</strong> de moeilijkhed<strong>en</strong> van het huidige <strong>GPU</strong> programmer<strong>en</strong><br />

in kaart gebracht.<br />

Hoofdstuk 5: Implem<strong>en</strong>tatie In dit hoofdstuk zal de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong> implem<strong>en</strong>tatie<br />

besprok<strong>en</strong> word<strong>en</strong>. Eerst word<strong>en</strong> de gekoz<strong>en</strong> gegev<strong>en</strong>sstructur<strong>en</strong><br />

behandeld, daarna de algoritm<strong>en</strong> die er<strong>op</strong> <strong>op</strong>erer<strong>en</strong>.<br />

Hoofdstuk 6: Resultat<strong>en</strong> Dit hoofdstuk bevat e<strong>en</strong> beschrijving van de bekom<strong>en</strong><br />

resultat<strong>en</strong> van de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong> implem<strong>en</strong>tatie, met mogelijke verklaring<strong>en</strong><br />

hiervoor. Aangezi<strong>en</strong> veel van de bekom<strong>en</strong> resultat<strong>en</strong> systeemspecifiek zijn,<br />

zull<strong>en</strong> eerst de systeemparamaters gegev<strong>en</strong> word<strong>en</strong>. E<strong>en</strong> belangrijk deel<br />

van de verklaring<strong>en</strong> heeft betrekking tot de coher<strong>en</strong>tie tuss<strong>en</strong> de geschot<strong>en</strong><br />

stral<strong>en</strong> doorhe<strong>en</strong> de acceleratiestructuur. E<strong>en</strong> onderzoek van de pad<strong>en</strong>coher<strong>en</strong>tie<br />

zal bijgevolg e<strong>en</strong> belangrijk aandeel vorm<strong>en</strong> van dit hoofdstuk.<br />

Verder zal er nog e<strong>en</strong> model geconstrueerd word<strong>en</strong> voor het evaluer<strong>en</strong> van<br />

de kost van verschill<strong>en</strong>de if-structur<strong>en</strong>. Dit zal gebruikt word<strong>en</strong> voor e<strong>en</strong><br />

vergelijk<strong>en</strong>de studie tuss<strong>en</strong> algoritm<strong>en</strong> uit de literatuur, <strong>en</strong> het algoritme<br />

dat voor deze thesis geïmplem<strong>en</strong>teerd werd.<br />

Hoofdstuk 7: Toekomstig werk Zak<strong>en</strong> die niet binn<strong>en</strong> het bestek van deze<br />

thesis past<strong>en</strong>, maar toch mooi zoud<strong>en</strong> aansluit<strong>en</strong>, zull<strong>en</strong> hier aangehaald<br />

word<strong>en</strong>.<br />

Hoofdstuk 8: Conclusie Conclusies die getrokk<strong>en</strong> kunn<strong>en</strong> word<strong>en</strong> uit dit werk,<br />

word<strong>en</strong> in dit hoofdstuk besprok<strong>en</strong>.<br />

1 C for graphics [nVi]<br />

3


Hoofdstuk 2<br />

Achtergrond<br />

In dit hoofdstuk zull<strong>en</strong> <strong>en</strong>kele belangrijke, zak<strong>en</strong> waar<strong>op</strong> dit werk steunt, besprok<strong>en</strong><br />

word<strong>en</strong>. Eerst zal de r<strong>en</strong>dering vergelijking uit de doek<strong>en</strong> word<strong>en</strong> gedaan.<br />

Met dit als achtergrond wordt vervolg<strong>en</strong>s de ray tracing techniek uitgelegd.<br />

2.1 R<strong>en</strong>dering vergelijking<br />

Vooraleer we ons kunn<strong>en</strong> toespits<strong>en</strong> <strong>op</strong> ray tracing, is het belangrijk om eerst<br />

e<strong>en</strong> notie te hebb<strong>en</strong> van het gedrag van licht in de reële wereld. Lichtbronn<strong>en</strong><br />

z<strong>en</strong>d<strong>en</strong> <strong>en</strong>ergie uit onder de vorm van foton<strong>en</strong>. Deze foton<strong>en</strong> beweg<strong>en</strong> zich voort<br />

in de ruimte <strong>en</strong> kaats<strong>en</strong> af (of door) fysische object<strong>en</strong> totdat ze geabsorbeerd<br />

zijn door de omgeving. Merk <strong>op</strong> dat zo e<strong>en</strong> fysisch object e<strong>en</strong> camera of e<strong>en</strong><br />

oog kan zijn, dat e<strong>en</strong> deel van de foton<strong>en</strong> van e<strong>en</strong> omgeving absorbeert, <strong>en</strong> deze<br />

<strong>en</strong>ergie omzet in e<strong>en</strong> beeld.<br />

E<strong>en</strong> wiskundige vergelijking die dit beschrijft, is de bek<strong>en</strong>de r<strong>en</strong>dering vergelijking.<br />

Deze vergelijking onderstelt dat licht<strong>en</strong>ergie zich og<strong>en</strong>blikkelijk pr<strong>op</strong>ageert<br />

(dus bv. ge<strong>en</strong> fluoresc<strong>en</strong>tie), <strong>en</strong> dat er ge<strong>en</strong> participer<strong>en</strong>de media aanwezig zijn.<br />

Ze ziet er als volgt uit:<br />

<br />

L(x → Θ) = Le(x → Θ) + fr(x, Ψ → Θ)L(x ← Ψ)cos(Nx, Ψ)dωΨ<br />

Θx<br />

L(x → Θ) stelt de hoeveelheid uitgaande radiantie (<strong>en</strong>ergie per <strong>op</strong>pervlakte)<br />

voor <strong>op</strong> positie x in de richting Θ. Analoog is L(x ← Ψ) de inkom<strong>en</strong>de radiantie<br />

uit de richting Ψ. Ook Le(x → Θ) is analoog hieraan, maar betreft <strong>en</strong>kel<br />

de zelf uitgestraalde radiantie. Indi<strong>en</strong> x zich niet <strong>op</strong> e<strong>en</strong> lichtbron bevindt is<br />

bijgevolg Le = 0. fr(x, Ψ → Θ) is de BRDF 1 . Dit geeft aan “hoeveel” van het<br />

inkom<strong>en</strong>de licht in e<strong>en</strong> punt x uit richting Ψ er gekaatst wordt in de richting<br />

Θ. De factor cos(Nx, Ψ), waarbij Nx de normaal <strong>op</strong> x voorstelt, zorgt ervoor<br />

dat het uitsmer<strong>en</strong> van het licht over het <strong>op</strong>pervlak rond x in rek<strong>en</strong>ing wordt<br />

gebracht. Hoe schuiner het licht binn<strong>en</strong>valt, hoe meer de hoek tuss<strong>en</strong> Nx <strong>en</strong> Ψ<br />

nadert naar π/2 rad, dus hoe meer de cos(Nx, Ψ) nadert naar 0. Dit strookt<br />

met de intuïtie, aangezi<strong>en</strong> de radiantie dan inderdaad verdeeld di<strong>en</strong>t te word<strong>en</strong><br />

over e<strong>en</strong> oneindige <strong>op</strong>pervlakte. Dit zal verduidelijkt word<strong>en</strong> aan de hand van<br />

situatieschets<strong>en</strong> 2.1 <strong>en</strong> 2.2.<br />

1 bidirectional reflectance distribution function<br />

4


Figuur 2.1: Verdeling van invall<strong>en</strong>de licht, onder e<strong>en</strong> hoek van 0 radiaal t.o.v.<br />

de normaal Nx, zodat cos(Nx, Ψ) = cos(0) = 1.<br />

1<br />

In figuur 2.1 kom<strong>en</strong> de invall<strong>en</strong>de lichtstral<strong>en</strong> ev<strong>en</strong>wijdig aan de normaal Nx<br />

<strong>op</strong> het <strong>op</strong>pervlak. De cosinus tuss<strong>en</strong> beide vector<strong>en</strong> is duidelijk gelijk aan 1.<br />

In figuur 2.2 kom<strong>en</strong> de invall<strong>en</strong>de lichtstral<strong>en</strong> onder e<strong>en</strong> hoek van π/3 rad met<br />

de normaal Nx <strong>op</strong> het <strong>op</strong>pervlak, dus de cosinus ervan is gelijk aan 1/2. De<br />

<strong>en</strong>ergie die binn<strong>en</strong>komt wordt als het ware uitgesmeerd over e<strong>en</strong> twee maal zo<br />

groot <strong>op</strong>pervlak.<br />

1<br />

2<br />

N x<br />

x<br />

N x<br />

1<br />

X<br />

pi / 3<br />

Figuur 2.2: Verdeling van invall<strong>en</strong>de licht, onder e<strong>en</strong> hoek van π/3 radiaal<br />

t.o.v. de normaal Nx, zodat cos(Nx, Ψ) = cos(π/3) = 1/2.<br />

Nu elk afzonderlijk deel van de vergelijking toegelicht is, gaan we deze als<br />

e<strong>en</strong> geheel tracht<strong>en</strong> te interpreter<strong>en</strong>. De hoeveelheid uitgaande radiantie in e<strong>en</strong><br />

richting Θ vanuit e<strong>en</strong> punt x, is de som van de radiantie die het materiaal zelf<br />

uitz<strong>en</strong>dt in die richting (Le(x → Θ)), <strong>en</strong> het weerkaatste deel van de inkom<strong>en</strong>de<br />

radiantie volg<strong>en</strong>s de richting Θ. Laat ons het gereflecteerde deel noter<strong>en</strong> als Θ<br />

5<br />

1


Lr(x → Θ). Dit geeft volg<strong>en</strong>de e<strong>en</strong>voudigere vorm:<br />

waarbij<br />

L(x → Θ) = Le(x → Θ) + Lr(x → Θ)<br />

<br />

Lr(x → Θ) = fr(x, Ψ → Θ)L(x ← Ψ)cos(Nx, Ψ)dωΨ<br />

Θx<br />

Het gereflecteerde deel Lr(x → Θ) kan gezi<strong>en</strong> word<strong>en</strong> als de “som” van de<br />

inkom<strong>en</strong>de radiantie uit alle richting<strong>en</strong> Ψ, uitgesmeerd over het raak<strong>op</strong>pervlak,<br />

<strong>en</strong> daarvan <strong>en</strong>kel het weerkaatste deel in de richting Θ.<br />

Voor de m<strong>en</strong>s<strong>en</strong> die e<strong>en</strong> meer formele <strong>en</strong> volledigere beschrijving w<strong>en</strong>s<strong>en</strong> inzake<br />

r<strong>en</strong>dering vergelijking ed., word<strong>en</strong> doorverwez<strong>en</strong> naar het boek “Advanced<br />

Global Illumination” [DBB03].<br />

2.2 <strong>Ray</strong> tracing<br />

<strong>Ray</strong> tracing is e<strong>en</strong> techniek om beeld<strong>en</strong> te g<strong>en</strong>erer<strong>en</strong> van virtuele scènes. In<br />

deze sectie zal het ray tracing algoritme, de eig<strong>en</strong>schapp<strong>en</strong> ervan, <strong>en</strong> mogelijke<br />

acceleratiestructur<strong>en</strong> uit de doek<strong>en</strong> word<strong>en</strong> gedaan.<br />

De (<strong>GPU</strong>) ray tracer implem<strong>en</strong>tatie voor deze thesis is vrij sam<strong>en</strong>l<strong>op</strong><strong>en</strong>d<br />

met de (<strong>CPU</strong>) versie die voorgesteld wordt in het boek “Realistic <strong>Ray</strong> <strong>Tracing</strong>”<br />

van Peter Shirley [Shi00]. Hierin wordt stapsgewijs e<strong>en</strong> klassieke ray tracer<br />

gebouwd, met telk<strong>en</strong>s e<strong>en</strong> verantwoording waarom er voor bepaalde algoritm<strong>en</strong>,<br />

datastructur<strong>en</strong>, formules, e.a. ge<strong>op</strong>teerd werd. Dikwijls werd<strong>en</strong> bepaalde keuz<strong>en</strong><br />

gemaakt, puur voor de e<strong>en</strong>voud, t<strong>en</strong> koste van efficiëntie. E<strong>en</strong> voorbeeld hiervan<br />

is het gebruik van e<strong>en</strong> regular grid in plaats van bijvoorbeeld k-d tree. Dit was in<br />

vele gevall<strong>en</strong> welgekom<strong>en</strong> om de <strong>GPU</strong>-code beperkt te houd<strong>en</strong> qua complexheid<br />

<strong>en</strong> aantal instructies.<br />

In de doctoraatsthesis “Realtime <strong>Ray</strong> <strong>Tracing</strong> and Interactive Global Illumination”<br />

van Ingo Wald [Wal04] kom<strong>en</strong> allerlei techniek<strong>en</strong> <strong>en</strong> afweging<strong>en</strong> naar<br />

vor<strong>en</strong> om realtime ray tracing mogelijk te mak<strong>en</strong>. Bepaalde <strong>op</strong>timalisaties, zoals<br />

gebruik van SSE 2 , geheug<strong>en</strong>indeling <strong>en</strong> cache alignm<strong>en</strong>t zijn niet zonder meer<br />

over te nem<strong>en</strong> voor e<strong>en</strong> programma dat uitgevoerd wordt <strong>op</strong> de <strong>GPU</strong>.<br />

2.2.1 Algoritme<br />

Als we e<strong>en</strong> waarheidsgetrouw beeld w<strong>en</strong>s<strong>en</strong> te bepal<strong>en</strong> van e<strong>en</strong> gegev<strong>en</strong> virtuele<br />

scène, zoud<strong>en</strong> we als volgt te werk kunn<strong>en</strong> gaan. Eerst <strong>en</strong> vooral plaats<strong>en</strong><br />

we onze fictieve camera in de wereld. We iterer<strong>en</strong> over alle lichtbronn<strong>en</strong> <strong>en</strong><br />

per lichtbron schiet<strong>en</strong> we lichtdeeltjes (foton<strong>en</strong>) de wereld in. We volg<strong>en</strong> deze<br />

doorhe<strong>en</strong> de scène volg<strong>en</strong>s de wett<strong>en</strong> van de fysica, totdat all<strong>en</strong> geabsorbeerd<br />

zijn of zich niet meer in de beschouwde scène bevind<strong>en</strong>. Dieg<strong>en</strong>e die <strong>op</strong> de onze<br />

camera zijn terechtgekom<strong>en</strong> <strong>en</strong> door het brandpunt gaan (zie figuur 2.3), gev<strong>en</strong><br />

we weer <strong>op</strong> de corresponder<strong>en</strong>de plaats <strong>op</strong> ons beeldscherm.<br />

2 Streaming SIMD Ext<strong>en</strong>sions (Intel). Door hiervan gebruik te mak<strong>en</strong> is het mogelijk 4<br />

floats te verwerk<strong>en</strong> in slechts één klok cyclus. E<strong>en</strong> ray tracer kan hiervoor herschrev<strong>en</strong> word<strong>en</strong><br />

zodat 4 stral<strong>en</strong> tegelijkertijd word<strong>en</strong> verwerkt. [WBWS01]<br />

6


Duidelijk vergt dit e<strong>en</strong> <strong>en</strong>orm groot aantal geschot<strong>en</strong> foton<strong>en</strong> alvor<strong>en</strong>s er<br />

sprake is van e<strong>en</strong> bruikbaar beeld. Gelukkig heeft licht de reciprociteitseig<strong>en</strong>schap<br />

dat het mogelijk maakt om de foton<strong>en</strong> in omgekeerde volgorde te tracer<strong>en</strong>.<br />

<strong>Ray</strong> tracing maakt hier uitbundig gebruik van. Voor elke pixel wordt de straal<br />

bepaald die door pixel <strong>en</strong> oogpunt gaat (oogstraal). Deze straal wordt dan<br />

gevolgd vanuit het oog, door de betreff<strong>en</strong>de pixel, totdat deze e<strong>en</strong> object uit de<br />

scène intersecteert. De kleur van de pixel wordt nu bepaald aan de hand van<br />

de materiaaleig<strong>en</strong>schapp<strong>en</strong> van het geïntersecteerde object. Indi<strong>en</strong> het object<br />

reflecter<strong>en</strong>d is, zal er recursief verder e<strong>en</strong> weerkaatste straal geschot<strong>en</strong> word<strong>en</strong><br />

om zo verder de kleur te bepal<strong>en</strong>. Analoog geldt voor refractieve object<strong>en</strong> dat<br />

er e<strong>en</strong> straal wordt gebrok<strong>en</strong> in plaats van weerkaatst. Meer hierover verder<br />

in deze sectie. Pseudocode 2.1 beschrijft het klassieke ray tracing algoritme in<br />

meer detail.<br />

Als we figuur 2.3 met figuur 2.4 vergelijk<strong>en</strong> zi<strong>en</strong> we duidelijk dat er sneller<br />

e<strong>en</strong> beeld gevormd wordt door te ray trac<strong>en</strong> in plaats van het naïeve algoritme.<br />

Dit is te wijt<strong>en</strong> aan het feit dat er bij het naïeve algoritme <strong>en</strong>orm veel stral<strong>en</strong><br />

word<strong>en</strong> gevolgd die niet bijdrag<strong>en</strong> tot het uiteindelijke beeld. Bij ray tracing is<br />

dit niet het geval.<br />

Object<br />

Object<br />

Licht bron<br />

Transparant<br />

Object<br />

Beeld<br />

Figuur 2.3: Naïef algoritme om beeld<strong>en</strong> te vorm<strong>en</strong>. Vanuit elke lichtbron word<strong>en</strong>,volg<strong>en</strong>s<br />

de wett<strong>en</strong> van de fysica, foton<strong>en</strong> geschot<strong>en</strong> <strong>en</strong> gevolgd tot deze door<br />

de camera geabsorbeerd word<strong>en</strong>.<br />

Primaire stral<strong>en</strong><br />

We beschouw<strong>en</strong> e<strong>en</strong> doelbeeld van nx <strong>op</strong> ny pixels. De camera (pinhole) bevindt<br />

zich <strong>op</strong> positie e, gericht volg<strong>en</strong>s g, loodrecht <strong>op</strong> het view-plane <strong>op</strong> e<strong>en</strong> afstand<br />

s. vup is de view-up vector die naar de “bov<strong>en</strong>kant” van de scène wijst. Lat<strong>en</strong><br />

we de grootte van het view-plane noter<strong>en</strong> als sx <strong>en</strong> sy. Figuur 2.5 geeft hier e<strong>en</strong><br />

7


Voor e l k e p i x e l in beeld {<br />

s t r a a l = p i x e l − oogpunt<br />

t D i c h t s t e O b j e c t = o n e i n d i g<br />

d i c h t s t e O b j e c t = achtergond<br />

}<br />

Voor e l k o b j e c t in sc<strong>en</strong>e {<br />

Als s t r a a l o b j e c t i n t e r s e c t e e r t {<br />

Als t k l e i n e r i s a l s t D i c h t s t e O b j e c t {<br />

t D i c h t s t e O b j e c t = t<br />

d i c h t s t e O b j e c t = o b j e c t<br />

}<br />

}<br />

}<br />

Als d i c h t s t e O b j e c t i s achtergond {<br />

p i x e l = achtergrondKleur<br />

} anders {<br />

S c h i e t s t r a a l naar e l k e p u n t l i c h t b r o n<br />

<strong>en</strong> c o n t r o l e e r o f oorspong in schaduw<br />

Indi<strong>en</strong> r e f l e c t e r e n d , g e n e r e e r r e f l e c t i e s t r a a l <strong>en</strong><br />

herhaal deze stapp<strong>en</strong> voor bekom<strong>en</strong> s t r a a l<br />

Indi<strong>en</strong> transparant , g e n e r e e r r e f r a c t i e s t r a a l<br />

herhaal deze stapp<strong>en</strong> voor bekom<strong>en</strong> s t r a a l<br />

Bepaal k l e u r adhv de shading f u n c t i e<br />

}<br />

Codefragm<strong>en</strong>t 2.1: Pseudocode ray tracing<br />

8


Object<br />

Object<br />

Licht bron<br />

Transparant<br />

Object<br />

Beeld<br />

Figuur 2.4: <strong>Ray</strong> tracing algoritme.<br />

grafische repres<strong>en</strong>tatie van.<br />

Eerst bepal<strong>en</strong> we e<strong>en</strong> ass<strong>en</strong>stelsel (u, v, w) voor de camera.<br />

w = g<br />

g<br />

u = − vup × w<br />

vup × w<br />

v = w × u<br />

De primaire stral<strong>en</strong>, ook wel oogstral<strong>en</strong> g<strong>en</strong>oemd, kunn<strong>en</strong> nu als volgt bepaald<br />

word<strong>en</strong>. Per pixel i, j is de bijbehor<strong>en</strong>de straal gelijk aan<br />

<br />

i 1<br />

j 1<br />

p(t) = e + t sx − u + sy − v + sw<br />

nx − 1 2 ny − 1 2<br />

Deze formule is e<strong>en</strong> aangepaste versie van de formule gegev<strong>en</strong> in [Shi00].<br />

Objectintersectie<br />

Om te kunn<strong>en</strong> bepal<strong>en</strong> welk object geraakt wordt door de betreff<strong>en</strong>de lichtstraal,<br />

moet er voor elke soort gebruikte primitieve e<strong>en</strong> e<strong>en</strong> intersectie methode<br />

aanwezig zijn. Indi<strong>en</strong> er gebruik gemaakt wordt van e<strong>en</strong> acceleratiestructuur,<br />

di<strong>en</strong><strong>en</strong> er voor het doorl<strong>op</strong><strong>en</strong> ervan ook de juiste intersectie method<strong>en</strong> aanwezig<br />

te zijn. Veelgebruikte primitiev<strong>en</strong> zijn driehoek<strong>en</strong>, boll<strong>en</strong>, vlakk<strong>en</strong> <strong>en</strong> axis<br />

aligned boxes. E<strong>en</strong> intersectiealgoritme geeft typisch aan of er daadwerkelijk<br />

sprake was van e<strong>en</strong> intersectie, de positie van het intersectiepunt <strong>op</strong> de straal,<br />

<strong>en</strong> de normaal <strong>op</strong> het inslagpunt.<br />

9


e<br />

v_up<br />

g<br />

s<br />

(0, 0)<br />

(i, j)<br />

s_x<br />

(n_x, n_y)<br />

Figuur 2.5: Parameters gebruikt voor het g<strong>en</strong>erer<strong>en</strong> van de primaire stral<strong>en</strong>.<br />

E<strong>en</strong> concreet voorbeeld dat gegev<strong>en</strong> wordt, is de intersectie van e<strong>en</strong> straal<br />

met e<strong>en</strong> bol. Dit is e<strong>en</strong> typisch voorbeeld vanwege de e<strong>en</strong>voudige wiskundige<br />

<strong>op</strong>lossing <strong>en</strong> de mooie resultat<strong>en</strong>. Beschouw e<strong>en</strong> bol met c<strong>en</strong>trum c <strong>en</strong> straal R,<br />

dan geldt:<br />

(p − c) · (p − c) − R 2 = 0<br />

voor alle punt<strong>en</strong> p die zich <strong>op</strong> de bol bevind<strong>en</strong>. E<strong>en</strong> straal met oorsprong o <strong>en</strong><br />

richting d kunn<strong>en</strong> we beschrijv<strong>en</strong> als e<strong>en</strong> rechte, met volg<strong>en</strong>de vergelijking:<br />

p(t) = o + td<br />

We zoek<strong>en</strong> nu de kleinst mogelijk t zodanig dat (p(t) − c) · (p(t) − c) − R2 = 0.<br />

Met e<strong>en</strong> minimum aan rek<strong>en</strong>werk kom<strong>en</strong> we aan:<br />

<br />

−d · (o − c) ± (d · (o − c))<br />

t = 2 − (d · d) ((o − c) · (o − c) − R2 )<br />

d · d<br />

Indi<strong>en</strong> de discriminant (onder de vierkanstwortel) negatief is, is er ge<strong>en</strong> intersectie<br />

met dit object. Anders wordt de kleinste positieve t g<strong>en</strong>om<strong>en</strong> aangezi<strong>en</strong><br />

dit de eerste (dus dichtstbijzijnde) intersectie is met de bol. Indi<strong>en</strong> deze waarde<br />

niet bestaat, is er ge<strong>en</strong> sprake van e<strong>en</strong> intersectie. De normaal n is ook triviaal<br />

te bepal<strong>en</strong>, namelijk n = (p − c)/R.<br />

Het intersecter<strong>en</strong> van vlakk<strong>en</strong> of axis aligned boxes is min of meer van<br />

dezelfde complexiteit. Zie voor meer info [Shi00]. Driehoek<strong>en</strong> daar<strong>en</strong>teg<strong>en</strong> zijn<br />

al iets geavanceerder om <strong>op</strong> effeciënte wijze af te handel<strong>en</strong>. E<strong>en</strong> veel gebruikt<br />

algoritme hiervoor is Moller-Trumbore [MT97], wat in detail behandeld wordt<br />

in hoofdstuk 5.2. Verder zie [Wal04].<br />

Reflectie<br />

Bij het ray trac<strong>en</strong> van e<strong>en</strong> reflecter<strong>en</strong>d <strong>op</strong>pervlak is de kleur niet <strong>en</strong>kel afhankelijk<br />

van het materiaal van het geïntersecteerde object, maar ook van object<strong>en</strong><br />

10<br />

s_y


geraakt door de afgekaatste stral<strong>en</strong>. In de situatieschets 2.6 is de bijdrage van<br />

de straal aangegev<strong>en</strong> door de dikte ervan. Duidelijk is de primaire straal de<br />

dikste. Aangezi<strong>en</strong> elk object hier 50 % reflecter<strong>en</strong>d is, halveert de dikte van<br />

straal na elke bosting met e<strong>en</strong> object, alsook de bijdrage tot de kleur.<br />

Object<br />

Object<br />

Object<br />

beeld<br />

Figuur 2.6: Reflecter<strong>en</strong> van stral<strong>en</strong>. De dikte van de straal geeft aan voor<br />

hoeveel proc<strong>en</strong>t deze straal de kleur beïnvloedt, gaande van 100% voor de dikste<br />

straal, tot 12,5% voor de dunste.<br />

De uitgaande reflectiestraal r is afhankelijk van de normaal n <strong>en</strong> invall<strong>en</strong>de<br />

straalrichting d als volgt:<br />

d · n<br />

r = d + 2 2 n<br />

n<br />

Hoe deze formule tot stand komt is duidelijk af te lez<strong>en</strong> van de bijbehor<strong>en</strong>de<br />

schets 2.7. Merk <strong>op</strong> dat d·n<br />

n 2 n voorgesteld wordt als a.<br />

n<br />

d r<br />

Figuur 2.7: Parameters voor de reflectieformule, waarbij r de uitgaande reflectiestraal<br />

is, n de normaal <strong>en</strong> a = d·n<br />

n 2 n<br />

Refractie<br />

Wanneer licht botst <strong>op</strong> bijvoorbeeld glas, water, diamant, . . . zal het gerefracteerd<br />

word<strong>en</strong>. Licht dat zich van e<strong>en</strong> <strong>op</strong>tisch ijlere, naar e<strong>en</strong> <strong>op</strong>tisch dichtere<br />

11<br />

d<br />

a<br />

a


stof of omgekeerd begeeft, zal afgebog<strong>en</strong> word<strong>en</strong> <strong>en</strong> zich verder door de materie<br />

begev<strong>en</strong> volg<strong>en</strong>s de wet van Snell. Dit f<strong>en</strong>ome<strong>en</strong> heet refractie. Aangezi<strong>en</strong> in<br />

de <strong>GPU</strong> ray tracer implem<strong>en</strong>tatie ge<strong>en</strong> refractie aanwezig is, zal er hier niet in<br />

detail <strong>op</strong> ingegaan word<strong>en</strong>. Zie alweer [Shi00] voor formules <strong>en</strong> meer details.<br />

In figuur 2.8 wordt één lichtstraal gevolgd, die twee maal gerefracteerd wordt<br />

<strong>en</strong> vervolg<strong>en</strong>s botst <strong>op</strong> e<strong>en</strong> niet transparant object (bol).<br />

Schaduw<br />

Object<br />

Transparant<br />

Object<br />

Transparant Object<br />

beeld<br />

Figuur 2.8: Gerefracteerde stral<strong>en</strong>.<br />

Het bepal<strong>en</strong> of e<strong>en</strong> intersectiepunt zich in e<strong>en</strong> schaduw gebied van e<strong>en</strong> bepaalde<br />

lichtbron bevindt, is zeer recht-toe-recht-aan. Creëer e<strong>en</strong> straal met oorsprong<br />

het intersectiepunt <strong>en</strong> eindpunt het beschouwde puntlichtbron. Controleer vervolg<strong>en</strong>s<br />

of lijnstuk één of meerdere object<strong>en</strong> in de scène kruist. Indi<strong>en</strong> ja, bevindt<br />

dit punt zich in e<strong>en</strong> schaduw gebied, anders in e<strong>en</strong> belicht gebied. Merk <strong>op</strong> dat<br />

deze stapp<strong>en</strong> voor elke lichtbron di<strong>en</strong><strong>en</strong> ondernom<strong>en</strong> te word<strong>en</strong>.<br />

Spatiale subdivisie<br />

Het ray tracing algoritme dat we tot nog toe hebb<strong>en</strong> voorgesteld, is weinig<br />

effeciënt voor grote scènes. Met grote scène wordt bedoeld: bestaande uit<br />

e<strong>en</strong> groot aantal primitiev<strong>en</strong>. Voor het bepal<strong>en</strong> van e<strong>en</strong> straal-scène intersectie<br />

di<strong>en</strong><strong>en</strong> alle primitiev<strong>en</strong> getest te word<strong>en</strong>, om vervolg<strong>en</strong>s te bepal<strong>en</strong> welke<br />

het dichtstbijzijnde intersectiepunt <strong>op</strong>levert. Dikwijls maakt m<strong>en</strong> gebruik van<br />

driehoek<strong>en</strong> als primitiev<strong>en</strong>. Ook gekromde <strong>op</strong>pervlakk<strong>en</strong> di<strong>en</strong><strong>en</strong> dan b<strong>en</strong>aderd<br />

te word<strong>en</strong> door voldo<strong>en</strong>de (meestal veel) driehoek<strong>en</strong>, om er smooth uit te zi<strong>en</strong>.<br />

Het r<strong>en</strong>der<strong>en</strong> van e<strong>en</strong> gemiddeld 3D model dat iets of wat realistisch oogt, zou<br />

12


al snel leid<strong>en</strong> tot gigantische r<strong>en</strong>dertijd<strong>en</strong>. Dit probleem is e<strong>en</strong>voudig <strong>op</strong> te<br />

loss<strong>en</strong> door onze ruimte <strong>op</strong> te del<strong>en</strong> in deelruimt<strong>en</strong> (spatiale subdivisie). Per<br />

deelruimte houd<strong>en</strong> we dan e<strong>en</strong> lijst bij van welke primitiev<strong>en</strong> zich er al dan niet<br />

volledig in bevind<strong>en</strong>. Dit maakt dat we <strong>en</strong>kel die primitiev<strong>en</strong> moet<strong>en</strong> controler<strong>en</strong>,<br />

die zich in de geïntersecteerde deelruimt<strong>en</strong> bevind<strong>en</strong>. Indi<strong>en</strong> e<strong>en</strong> gepaste<br />

acceleratiestructuur zorgvuldig geconstrueerd wordt, <strong>en</strong> <strong>op</strong> e<strong>en</strong> slimme manier<br />

doorl<strong>op</strong><strong>en</strong>, kan dit e<strong>en</strong> <strong>en</strong>orme snelheidswinst <strong>op</strong>lever<strong>en</strong>. E<strong>en</strong> kd-tree <strong>en</strong> BSPtree<br />

kunn<strong>en</strong> bijvoorbeeld doorl<strong>op</strong><strong>en</strong> word<strong>en</strong> in O(log n) t.o.v. O(n) voor e<strong>en</strong><br />

regular grid, waarbij n het aantal primitiev<strong>en</strong> is.<br />

Hieronder volgt e<strong>en</strong> lijst van veelgebruikte spatiale subdivisie structur<strong>en</strong>,<br />

met telk<strong>en</strong>s e<strong>en</strong> korte omschrijving hoe deze de ruimte <strong>op</strong>del<strong>en</strong>. In figuur 2.9<br />

wordt elk van deze structur<strong>en</strong>, toegepast <strong>op</strong> e<strong>en</strong> voorbeeldscène, geïllustreerd<br />

aan de hand van e<strong>en</strong> schematische voorstelling.<br />

Regular grid (Uniform grid) Dit is e<strong>en</strong> axis aligned bounding box waarbij<br />

elke as verdeeld wordt in e<strong>en</strong> aantal gelijke del<strong>en</strong>. Hierdoor wordt de<br />

ruimte <strong>op</strong>gesplitst in allemaal gelijke voxels, die axis aligned zijn.<br />

Bounding volume hierarchy Rond groep<strong>en</strong> van primitiev<strong>en</strong> word<strong>en</strong> bounding<br />

volumes gekoz<strong>en</strong>, <strong>en</strong> deze volumes kunn<strong>en</strong> dan weer ondergebracht<br />

word<strong>en</strong> in grotere volumes <strong>en</strong>z., zodat er sprake is van e<strong>en</strong> hiërarchie van<br />

bounding volumes.<br />

Octree Dit is e<strong>en</strong> axis aligned bounding box dat in acht gelijke deelruimt<strong>en</strong><br />

verdeeld is door e<strong>en</strong> x-, y- <strong>en</strong> z-vlak gaande door het middelpunt van deze<br />

box. Dit kan per verkreg<strong>en</strong> ruimte recursief verder gebeur<strong>en</strong>, tot er aan<br />

e<strong>en</strong> gegev<strong>en</strong> st<strong>op</strong>voorwaarde voldaan is.<br />

Kd-tree Dit is e<strong>en</strong> boomstructuur waarbij de ruimte telk<strong>en</strong>s in twee del<strong>en</strong><br />

gedeeld wordt, afwissel<strong>en</strong>d door e<strong>en</strong> x-, y- of z-vlak. Dit gebeurt recursief<br />

verder tot er aan e<strong>en</strong> gegev<strong>en</strong> st<strong>op</strong>voorwaarde voldaan is.<br />

BSP-tree Dit is e<strong>en</strong> veralgeme<strong>en</strong>de kd-tree aangezi<strong>en</strong> elke ruimte <strong>op</strong>gedeeld<br />

kan word<strong>en</strong> door e<strong>en</strong> willekeurig vlak, in plaats van <strong>en</strong>kel door e<strong>en</strong> x-, yof<br />

z-vlak.<br />

Voor e<strong>en</strong> gedetailleerde uitwerking <strong>en</strong> vergelijk<strong>en</strong>de studie van spatiale datastructur<strong>en</strong>,<br />

zie [Hav00]. Voor e<strong>en</strong> zeer ge<strong>op</strong>timaliseerde kd-tree implem<strong>en</strong>tatie,<br />

zie [Wal04]<br />

2.2.2 Eig<strong>en</strong>schapp<strong>en</strong><br />

E<strong>en</strong> pittig detail aan het klassieke ray tracing algoritme is dat het niet strookt<br />

met de r<strong>en</strong>dering vergelijking. Om de kleur te bepal<strong>en</strong> <strong>op</strong> e<strong>en</strong> bepaald intersectiepunt<br />

x di<strong>en</strong>t er rek<strong>en</strong>ing gehoud<strong>en</strong> te word<strong>en</strong> met het invall<strong>en</strong>de licht vanuit<br />

de omgeving van x, <strong>en</strong> niet <strong>en</strong>kel met het licht vanuit de ideale reflectie- (of<br />

refractie-) richting. E<strong>en</strong> klassieke ray tracer is wel e<strong>en</strong>voudig aan te pass<strong>en</strong> naar<br />

e<strong>en</strong> zog<strong>en</strong>aamde “stochastic ray tracer”, die wel degelijk voldoet aan de r<strong>en</strong>dering<br />

vergelijking [Shi00, DBB03]. Eig<strong>en</strong>lijk is dit e<strong>en</strong> redelijk rechtstreekse<br />

implem<strong>en</strong>tatie van de r<strong>en</strong>dering vergelijking waarbij er door middel van Monte<br />

Carlo method<strong>en</strong> het aantal samples per intersectiepunt aanzi<strong>en</strong>lijk verlaagd kan<br />

word<strong>en</strong>. Voor meer details, zie de gegev<strong>en</strong> refer<strong>en</strong>ties.<br />

13


(a) (b) (c)<br />

(d) (e)<br />

Figuur 2.9: Spatiale subdivisie structur<strong>en</strong>. (a) Regular grid (b) Bounding volume<br />

hierarchy (c) Octree (d) Kd tree (e) Bsp tree<br />

Effect<strong>en</strong> zoals “soft shadows”, “caustics” <strong>en</strong> “color bleeding” zijn met e<strong>en</strong><br />

klassieke ray tracer onmogelijk te verkrijg<strong>en</strong>. Omdat e<strong>en</strong> stochastic ray tracer<br />

veel samples per pixel (<strong>en</strong> dus rek<strong>en</strong>tijd) nodig heeft om te converger<strong>en</strong> naar e<strong>en</strong><br />

correct beeld, wordt er voor het verkrijg<strong>en</strong> van caustics <strong>en</strong> color bleeding meestal<br />

gebruik gemaakt van photon mapping. Hierbij word<strong>en</strong> foton<strong>en</strong> geschot<strong>en</strong> vanuit<br />

de lichtbronn<strong>en</strong>, zoals bij het naïeve algoritme, maar word<strong>en</strong> <strong>op</strong>geslag<strong>en</strong> in e<strong>en</strong><br />

zog<strong>en</strong>aamde photon map. De combinatie van e<strong>en</strong> stochastic ray tracer <strong>en</strong> e<strong>en</strong><br />

photon mapper (voor de indirecte belichting) is dus efficiënter om e<strong>en</strong> fotorealistisch<br />

beeld te g<strong>en</strong>erer<strong>en</strong> dan slechts één van beide techniek<strong>en</strong> te verkiez<strong>en</strong>.<br />

Meer details hierover zijn te vind<strong>en</strong> in [J<strong>en</strong>01, DBB03].<br />

14


Hoofdstuk 3<br />

Grafische hardware<br />

Dit hoofdstuk geeft e<strong>en</strong> inleiding tot grafische hardware. Eerst wordt er geschetst<br />

hoe deze hardware de laatste 10 jaar geëvolueerd is. Vervolg<strong>en</strong>s zal de huidige<br />

r<strong>en</strong>dering pipeline nader word<strong>en</strong> toegelicht. Uiteindelijk word<strong>en</strong> de <strong>GPU</strong> <strong>en</strong><br />

<strong>CPU</strong> naast elkaar gezet, <strong>en</strong> word<strong>en</strong> de belangrijkste voor- <strong>en</strong> nadel<strong>en</strong> besprok<strong>en</strong>.<br />

De informatie waar<strong>op</strong> dit hoofdstuk gebaseerd is, is afkomstig van [nVi, ATI].<br />

3.1 Geschied<strong>en</strong>is<br />

Ruim 10 jaar geled<strong>en</strong> was de grafische hardware, onder de vorm van beeldkaart<strong>en</strong>,<br />

<strong>en</strong>kel voorzi<strong>en</strong> van 2D rasterisatie functionaliteit. Ontwerpers van 3D<br />

applicaties (CAD, games, . . . ) di<strong>en</strong>d<strong>en</strong> zelf over software te beschikk<strong>en</strong> die in<br />

staat was om e<strong>en</strong> virtuele scène te kunn<strong>en</strong> r<strong>en</strong>der<strong>en</strong>, zonder hardware ondersteuning.<br />

Vanzelfsprek<strong>en</strong>d was het programmer<strong>en</strong> van interactieve 3D applicaties<br />

e<strong>en</strong> <strong>en</strong>orm complexe zaak vanwege de beperkte resources. Low-level programmer<strong>en</strong><br />

met de nodige voorzichtigheid, al dan niet gedeeltelijk in machinetaal,<br />

was dus de boodschap voor het r<strong>en</strong>der<strong>en</strong> van de meest e<strong>en</strong>voudige 3D wereld.<br />

Gelukkig is hier de laatste 10 jaar verandering in gebracht.<br />

In 1995 kwam 3dfx met de Voodoo kaart <strong>op</strong> de markt, die het mogelijk<br />

maakte getextureerde 3D driehoek<strong>en</strong> correct <strong>op</strong> het scherm te ton<strong>en</strong>. Door<br />

middel van hardwarematige Z-buffering werd<strong>en</strong> deze driehoek<strong>en</strong> in de juiste<br />

volgorde <strong>op</strong> het scherm getek<strong>en</strong>d. Deze kaart werkte via de PCI 1 interface.<br />

In 1998 kwam<strong>en</strong> de TNT (van nVidia) <strong>en</strong> Rage (van ATI) kaart<strong>en</strong> met<br />

ingebouwde multitexturing <strong>op</strong> de markt. Deze kaart<strong>en</strong> communiceerd<strong>en</strong> via de<br />

AGP 2 poort.<br />

Vanaf 1999 versch<strong>en</strong><strong>en</strong> er kaart<strong>en</strong> die e<strong>en</strong> zog<strong>en</strong>aamde TnL unit bevatt<strong>en</strong><br />

(GeForce 256, GeForce 2, Radeon 7500, Savage3D). De naam TnL staat voor<br />

“Transform and Lighting”. Standaard belichting<strong>en</strong> <strong>en</strong> transformaties (projecties,<br />

rotaties, . . . ) kond<strong>en</strong> vanaf to<strong>en</strong> overg<strong>en</strong>om<strong>en</strong> word<strong>en</strong> door de beeldkaart.<br />

Ook bump mapping, cube texture mapping <strong>en</strong> projective texture mapping werd<br />

ingebakk<strong>en</strong> in de hardware.<br />

In het jaar 2001 k<strong>en</strong>de de grafische hardware e<strong>en</strong> belangrijke vooruitgang,<br />

1 Peripheral Compon<strong>en</strong>t Interconnect<br />

2 Accelerated Graphics Port<br />

15


namelijk kaart<strong>en</strong> met programmeerbare vertex shaders met static flow control 3<br />

dok<strong>en</strong> <strong>op</strong> (GeForce 3 <strong>en</strong> 4, Radeon 8500). Ook volume texture mapping, shadow<br />

mapping <strong>en</strong> antialiasing werd allemaal mogelijk door de hardware. Er is natuurlijk<br />

niet <strong>en</strong>kel extra functionaliteit toegevoegd <strong>op</strong> de grafische kaart, maar ook<br />

<strong>op</strong>timalisaties (zoals Z-culling) zijn gerealiseerd.<br />

E<strong>en</strong> jaar later, in 2002, werd<strong>en</strong> de beeldkaart<strong>en</strong> nog meer programmeerbaar.<br />

Eerst <strong>en</strong> vooral kwam<strong>en</strong> er programmeerbare fragm<strong>en</strong>t shaders bij (met static<br />

flow control). Ook niet onbelangrijk is het feit dat vanaf to<strong>en</strong> de vertex shaders<br />

static <strong>en</strong> dynamic flow control ondersteund<strong>en</strong>! MRT 4 deed ook zijn intrede.<br />

De to<strong>en</strong>malige laatste nieuwe 3D-kaart<strong>en</strong> war<strong>en</strong> de GeForce FX, Radeon 9600,<br />

9800, X600 tot X800.<br />

Dynamic branching <strong>op</strong> de fragm<strong>en</strong>t shader werd pas in 2004 e<strong>en</strong> feit. Ondertuss<strong>en</strong><br />

had ook PCIe 5 zijn intrede gedaan, is de GeForce 6 reeks versch<strong>en</strong><strong>en</strong>, is er<br />

64 bit kleur<strong>en</strong> ondersteuning, . . . . Kaart<strong>en</strong> van de GeForce 6 reeks, bezitt<strong>en</strong> tot<br />

16 pixel pipelines <strong>en</strong> 6 vertex <strong>en</strong>gines, die parallel draai<strong>en</strong> <strong>op</strong> e<strong>en</strong> kloksnelheid<br />

van 450 Mhz.<br />

Het is zonder meer duidelijk dat de ontwikkeling van grafische (3D) kaart<strong>en</strong><br />

e<strong>en</strong> <strong>en</strong>orme evolutie heeft gek<strong>en</strong>d in de laatste 10 jaar. De hardware is ondertuss<strong>en</strong><br />

zo algeme<strong>en</strong> programmeerbaar geword<strong>en</strong> dat het zelfs interessant wordt<br />

om deze hardware te “mis”bruik<strong>en</strong> voor totaal andere doeleind<strong>en</strong>, zoals het<br />

<strong>op</strong>loss<strong>en</strong> van stelsels vergelijking<strong>en</strong>, videocompressie, ray tracing, e.a.<br />

3.2 Graphics pipeline<br />

De graphics pipeline is e<strong>en</strong> pipeline 6 waar langs de <strong>en</strong>e kant door de applicatie<br />

e<strong>en</strong> scène beschrijving wordt ingest<strong>op</strong>t, <strong>en</strong> langs de andere kant e<strong>en</strong> ger<strong>en</strong>derd<br />

beeld uit komt. Zoals met e<strong>en</strong> reële pijpleiding, zal de doorvoer volledig afhang<strong>en</strong><br />

van de traagste stage (dunste deel van de buis). Er bestaat e<strong>en</strong> waaier aan<br />

verschill<strong>en</strong>de schematische voorstelling<strong>en</strong> van de graphics pipeline (veel / weinig<br />

detail, wel / niet platformspecifiek, . . . ). Hier is er ge<strong>op</strong>teerd voor e<strong>en</strong> e<strong>en</strong>voudig<br />

model, met als doel de vertex <strong>en</strong> fragm<strong>en</strong>t shaders hierin te kunn<strong>en</strong> plaats<strong>en</strong>.<br />

Beschouw figuur 3.1. Opvall<strong>en</strong>d aan deze voorstelling is dat ze iets te highlevel<br />

is om praktisch nuttig te zijn voor het beoogde doel. Daarom zal stage per<br />

stage meer in detail getred<strong>en</strong> word<strong>en</strong> door telk<strong>en</strong>s e<strong>en</strong> <strong>op</strong>somming te gev<strong>en</strong> van<br />

de zak<strong>en</strong> die plaatsvind<strong>en</strong> in de desbetreff<strong>en</strong>de stage. De laatste stage verzorgt<br />

<strong>en</strong>kel de uiteindelijke uitvoer, dus wordt hieronder niet verder uitgewerkt.<br />

3.2.1 Applicatie<br />

De applicatie stuurt e<strong>en</strong> beschrijving van de scène (geometrie, material<strong>en</strong>, positie,<br />

lichtbronn<strong>en</strong>, . . . ) door naar de grafische kaart. E<strong>en</strong> eerste vorm van softwarematige<br />

geometrie verwerking kan hier reeds plaatsvind<strong>en</strong>. D<strong>en</strong>k hierbij aan<br />

3 verder in de tekst zal duidelijk word<strong>en</strong> wat hiermee bedoeld wordt<br />

4 Multiple R<strong>en</strong>der Target: dit maakt het mogelijk om meerdere waard<strong>en</strong> terug te gev<strong>en</strong> na<br />

het uitvoer<strong>en</strong> van e<strong>en</strong> fragm<strong>en</strong>t shader<br />

5 Peripheral Compon<strong>en</strong>t Interconnect Express<br />

6 reeks aan elkaar geslot<strong>en</strong> gegev<strong>en</strong>sverwerk<strong>en</strong>de elem<strong>en</strong>t<strong>en</strong> (dikwijls in parallel uitvoerbaar),<br />

waarbij de output van e<strong>en</strong> elem<strong>en</strong>t wordt doorgegev<strong>en</strong> als input voor het volg<strong>en</strong>de<br />

elem<strong>en</strong>t<br />

16


Applicatie<br />

Geometrie verwerking<br />

Rasterisatie<br />

Uitvoerbeeld<br />

Figuur 3.1: Graphics pipeline.<br />

frustum culling van complexe modell<strong>en</strong>, LOD 7 selectie, <strong>en</strong>kel zichtbare sector<strong>en</strong><br />

van de wereld r<strong>en</strong>der<strong>en</strong>, . . . .<br />

3.2.2 Geometrie verwerking<br />

De geometrie verwerking is gedeeltelijk programmeerbaar door middel van vertex<br />

shaders. Laat ons “gedeeltelijk” nader specifiër<strong>en</strong>. Enkel de transformatie<br />

van coördinat<strong>en</strong>, normal<strong>en</strong> <strong>en</strong> textuur coördinat<strong>en</strong>, <strong>en</strong> de standaard belichting,<br />

kan geherprogrammeerd word<strong>en</strong>.<br />

Hier volgt e<strong>en</strong> overzicht van de toegewez<strong>en</strong> tak<strong>en</strong>:<br />

• Transformatie van coördinat<strong>en</strong> <strong>en</strong> normal<strong>en</strong> (model → wereld, wereld →<br />

oog)<br />

• Vertex belichting<br />

• Transformatie van texture coördinat<strong>en</strong><br />

• Backface culling<br />

• Transformatie naar clip space<br />

• Assembler<strong>en</strong> van vertices in primitiev<strong>en</strong><br />

• Clipp<strong>en</strong> over viewing frustum<br />

7 Level Of Detail<br />

17


3.2.3 Rasterisatie<br />

In de rasterisatiefase vindt de scanconversie plaats, waarna per pixel e<strong>en</strong> kleurwaarde<br />

bepaald wordt. Het bepal<strong>en</strong> van deze kleurwaarde gebeurt door middel<br />

van de fragm<strong>en</strong>t shader, die teg<strong>en</strong>woordig herprogrammeerbaar is. De fragm<strong>en</strong>t<br />

shader krijgt de waard<strong>en</strong> zoals geïnterpoleerde texture coördinat<strong>en</strong> <strong>en</strong> kleur<strong>en</strong><br />

binn<strong>en</strong>, <strong>en</strong> de programmeur gebruikt deze dan om e<strong>en</strong> kleur te bepal<strong>en</strong> <strong>op</strong> de<br />

gew<strong>en</strong>ste manier. Voorhe<strong>en</strong>, zijnde voor 2002, was de fragm<strong>en</strong>t shader ingebakk<strong>en</strong><br />

in hardware waardoor deze niet aangepast kon word<strong>en</strong>.<br />

3.3 <strong>GPU</strong> versus <strong>CPU</strong><br />

In deze sectie zull<strong>en</strong> de voor- <strong>en</strong> nadel<strong>en</strong> van de <strong>GPU</strong> t<strong>en</strong> <strong>op</strong>zichte van de<br />

<strong>CPU</strong> overl<strong>op</strong><strong>en</strong> word<strong>en</strong>. Hierdoor zal duidelijk word<strong>en</strong> waarom er interesse is in<br />

het gebruik van de grafische hardware voor algem<strong>en</strong>e doeleind<strong>en</strong>, hoewel deze<br />

hardware daar oorsponkelijk niet voor ontworp<strong>en</strong> was.<br />

Het parallellisme is de belangrijkste aanzet geweest tot het ontstaan van<br />

GP<strong>GPU</strong> 8 programmer<strong>en</strong>. Op de grafische kaart bevind<strong>en</strong> zich namelijk meerdere<br />

processor<strong>en</strong> die in parallel instructies kunn<strong>en</strong> uitvoer<strong>en</strong>. Aangezi<strong>en</strong> in grafische<br />

toepassing<strong>en</strong> relatief veel 3- <strong>en</strong> 4-tupel <strong>op</strong>eraties aanwezig zijn, is de teg<strong>en</strong>woordige<br />

grafische kaart hiervoor ge<strong>op</strong>timaliseerd. D<strong>en</strong>k hierbij aan vertices<br />

(x, y, z, w), kleur<strong>en</strong> (R, G, B, A), texture coördinat<strong>en</strong> (S, T, R, Q), . . . . We kunn<strong>en</strong><br />

dus sprek<strong>en</strong> van e<strong>en</strong> vector processor, die de standaard 4-tupel <strong>op</strong>eraties<br />

in slechts één clock cycle kan voorzi<strong>en</strong>. De typische “grafische” <strong>op</strong>eraties zoals<br />

dot product, cross product, matrix product, . . . kunn<strong>en</strong> dus aan e<strong>en</strong> lage kost<br />

uitgevoerd word<strong>en</strong>.<br />

De huidige g<strong>en</strong>eratie grafische kaart<strong>en</strong> (bv. GeForce 6800 GT) zijn voorzi<strong>en</strong><br />

van 16 pixel pipelines <strong>en</strong> 6 vertex pipelines. De hed<strong>en</strong>daagse vertex processor<strong>en</strong><br />

zijn reeds MIMD 9 , wat wil zegg<strong>en</strong> dat deze volledig in parallel, verschill<strong>en</strong>de instructies<br />

kunn<strong>en</strong> uitvoer<strong>en</strong>. Spijtig g<strong>en</strong>oeg zijn de fragm<strong>en</strong>t shaders nog SIMD 10 .<br />

Het lijkt voor de programmeur dat hij software schrijft voor e<strong>en</strong> MIMD processor,<br />

hoewel dit geëmuleerd wordt <strong>op</strong> e<strong>en</strong> SIMD processor. Het is dus van belang<br />

dat de fragm<strong>en</strong>t shaders die in parallel uitgevoerd word<strong>en</strong>, e<strong>en</strong> coher<strong>en</strong>te program<br />

flow bezitt<strong>en</strong>. Dit is echter ge<strong>en</strong> verplichting, maar zal dikwijls leid<strong>en</strong> tot<br />

e<strong>en</strong> kortere uitvoeringstijd. Merk <strong>op</strong> dat dit bij vertex shaders niet of nauwelijks<br />

(door instructiecaching?) snelheidswinst zal <strong>op</strong>lever<strong>en</strong>, aangezi<strong>en</strong> er meerdere<br />

aparte processor<strong>en</strong> aanwezig zijn.<br />

De beschikbare bandbreedte voor on-board geheug<strong>en</strong>toegang is ook e<strong>en</strong> stuk<br />

hoger (grote orde ×10) dan die tuss<strong>en</strong> <strong>CPU</strong> <strong>en</strong> systeemgeheug<strong>en</strong>. Maar toch is<br />

het zeker niet allemaal roz<strong>en</strong>geur <strong>en</strong> maneschijn. De bandbreedte tuss<strong>en</strong> <strong>GPU</strong><br />

<strong>en</strong> <strong>CPU</strong>, is relatief zeer laag. Het terughal<strong>en</strong> van data van de grafische kaart is<br />

makkelijk 100 × trager dan de <strong>GPU</strong> ↔ on-board geheug<strong>en</strong> communicatie, via<br />

e<strong>en</strong> AGP poort. Het upload<strong>en</strong> van data is ongeveer 10 keer trager (ipv 100).<br />

PCIe heeft hierin gelukkig verandering gebracht. Upload <strong>en</strong> download snelhed<strong>en</strong><br />

zijn gelijk, <strong>en</strong> verhoogd tot (theoretisch) ±8 GB/s, t.o.v. ±2 GB/s upload <strong>en</strong><br />

±200 MB/s download bij AGP.<br />

8 G<strong>en</strong>eral Purpose <strong>GPU</strong> programmer<strong>en</strong><br />

9 Multiple Instruction Multiple Data<br />

10 Single Instruction Multiple Data<br />

18


De teg<strong>en</strong>woordige <strong>CPU</strong>’s zijn nochtans ook gepipelined, hebb<strong>en</strong> streaming<br />

instructies (SSE 11 ), ondersteun<strong>en</strong> hyperthreading 12 , . . . Toch verkiest m<strong>en</strong> meer<br />

<strong>en</strong> meer de <strong>GPU</strong> voor parallelliseerbare algoritm<strong>en</strong>. De red<strong>en</strong> hiervoor is dat<br />

deze hardware veel “meer parallel” is dan de huidige verkrijgbare <strong>CPU</strong>’s.<br />

11 Streaming SIMD Ext<strong>en</strong>sions (Intel)<br />

12 simultane multithreading (Intel)<br />

19


Hoofdstuk 4<br />

<strong>GPU</strong> programmer<strong>en</strong><br />

Dit hoofdstuk handelt over hoe de <strong>GPU</strong> geprogrammeerd kan word<strong>en</strong>. Vooraleer<br />

we daar toe kom<strong>en</strong>, zull<strong>en</strong> we de <strong>GPU</strong> abstraher<strong>en</strong> tot het stream programming<br />

model. Vervolg<strong>en</strong>s zull<strong>en</strong> we dit mapp<strong>en</strong> <strong>op</strong> e<strong>en</strong> concrete taal, namelijk Cg 1 .<br />

Er zal aangehaald word<strong>en</strong> hoe typische shaders, alsook g<strong>en</strong>eral purpose shaders,<br />

eruitzi<strong>en</strong> in Cg. Uiteindelijk word<strong>en</strong> de moeilijkhed<strong>en</strong> van het huidige <strong>GPU</strong><br />

programmer<strong>en</strong> in kaart gebracht.<br />

4.1 Stream programming model<br />

Het stream programming model is e<strong>en</strong> model dat programma’s <strong>op</strong>legt <strong>op</strong> e<strong>en</strong><br />

bepaalde manier geschrev<strong>en</strong> te zijn. Localiteit in de inputdata <strong>en</strong> parallellisme<br />

di<strong>en</strong><strong>en</strong> hiervoor expliciet aangegev<strong>en</strong> te zijn in het programma. Dit maakt dat<br />

het gecompileerd <strong>en</strong> ge<strong>op</strong>timaliseerd kan word<strong>en</strong> voor stream processor<strong>en</strong>.<br />

Het stream programming model bestaat <strong>en</strong>kel uit streams, kernels <strong>en</strong> e<strong>en</strong><br />

read-only geheug<strong>en</strong>. E<strong>en</strong> stream is e<strong>en</strong> verzameling van records, waar<strong>op</strong> e<strong>en</strong><br />

kernel <strong>op</strong>eraties kan uitvoer<strong>en</strong>. E<strong>en</strong> kernel is e<strong>en</strong> proces dat gegev<strong>en</strong> e<strong>en</strong> record<br />

van de input stream, e<strong>en</strong> output stream record g<strong>en</strong>ereert. Meerdere output<br />

streams zijn ev<strong>en</strong>tueel mogelijk (bv. handig voor het sorter<strong>en</strong> van data). Zie<br />

figuur 4.1 voor e<strong>en</strong> schematische voorstelling.<br />

De <strong>GPU</strong> kunn<strong>en</strong> we beschouw<strong>en</strong> als e<strong>en</strong> stream processor, wat natuurlijk de<br />

red<strong>en</strong> is waarom we dit model besprek<strong>en</strong>. E<strong>en</strong> vertex shader krijgt als input<br />

stream e<strong>en</strong> verzameling vertices (met normal<strong>en</strong>, kleur<strong>en</strong>, . . . ). De shader zelf<br />

is dus de voorg<strong>en</strong>oemde kernel. De output stream bevat <strong>op</strong>nieuw vertices (<strong>en</strong><br />

dergelijke), die dan <strong>op</strong>gebouwd zijn <strong>op</strong> basis van e<strong>en</strong> input record, <strong>en</strong> het readonly<br />

geheug<strong>en</strong>. Het read-only geheug<strong>en</strong> kan bijvoorbeeld bestaan uit 3D vector<strong>en</strong>,<br />

e<strong>en</strong> array van floats, . . . . Dit geheug<strong>en</strong> is dus constant voor alle records.<br />

Daarom dat er ook wel gesprok<strong>en</strong> wordt van globaal read-only geheug<strong>en</strong>. E<strong>en</strong><br />

concrete <strong>GPU</strong> versie van figuur 4.1 wordt gegev<strong>en</strong> in figuur 4.2.<br />

1 C for graphics<br />

20


Input Stream<br />

Read-Only<br />

Memory<br />

Kernel<br />

Figuur 4.1: Stream Programming Model schema.<br />

4.2 Voorbeeldtaal: Cg<br />

Output Streams<br />

Er bestaan verscheid<strong>en</strong>e programmeertal<strong>en</strong> die machinetaal code voor de grafische<br />

kaart g<strong>en</strong>erer<strong>en</strong>. Voorbeeld<strong>en</strong> hiervan zijn onder andere Cg [nVi], HLSL,<br />

GLSL [Ope], Brook<strong>GPU</strong> [Bro] <strong>en</strong> Sh [Sh]. De eerste wijdverspreide GP<strong>GPU</strong><br />

taal, namelijk Cg, zal hier besprok<strong>en</strong> word<strong>en</strong>. De implem<strong>en</strong>tatie voor deze<br />

thesis is hierin geprogrammeerd.<br />

In Cg is het mogelijk om GP<strong>GPU</strong> programma’s te schrijv<strong>en</strong>, maar toch di<strong>en</strong>t<br />

m<strong>en</strong> zich nog bezig te houd<strong>en</strong> met grafische details. Zo wordt er doorgaans<br />

e<strong>en</strong> rechthoek <strong>op</strong> het scherm getek<strong>en</strong>d om per pixel de fragm<strong>en</strong>t shader aan<br />

te roep<strong>en</strong>, ook al hebb<strong>en</strong> de resultat<strong>en</strong> (output stream) totaal ge<strong>en</strong> grafische<br />

betek<strong>en</strong>is. Ook het expliciet in textures plaats<strong>en</strong> van data die doorgev<strong>en</strong> di<strong>en</strong><strong>en</strong><br />

te word<strong>en</strong>, is voor vele toepassing<strong>en</strong> iets dat onder de motorkap zou mog<strong>en</strong><br />

gebeur<strong>en</strong>. In Brook<strong>GPU</strong>, dat nog in ontwikkeling is, word<strong>en</strong> deze grafische<br />

details weg geabstraheerd.<br />

4.2.1 Kernels<br />

Met de kernels in Cg bedoel<strong>en</strong> we concreet de programmeerbare vertex <strong>en</strong> fragm<strong>en</strong>t<br />

shaders. Bij het schrijv<strong>en</strong> van e<strong>en</strong> typisch imperatief of objectgeoriënteerd<br />

programma zijn we gewoon dat de hoofdfunctie (bv. main in Java, C <strong>en</strong> C++)<br />

éénmaal doorl<strong>op</strong><strong>en</strong> wordt. In Cg werkt dit anders. De hoofdfunctie (willekeurige<br />

naam) wordt éénmaal aangeroep<strong>en</strong> per input stream record, zijnde e<strong>en</strong> vertex<br />

of fragm<strong>en</strong>t. Typisch kunn<strong>en</strong> er verscheid<strong>en</strong>e records gelijktijdig verwerkt word<strong>en</strong>.<br />

Merk <strong>op</strong> dat de volgorde van records in de stream ongedefiniëerd is, <strong>en</strong> dat<br />

er ge<strong>en</strong> <strong>en</strong>kele vorm van onderlinge communicatie bestaat tuss<strong>en</strong> de in parallel<br />

l<strong>op</strong><strong>en</strong>de vertex of fragm<strong>en</strong>t shaders.<br />

In codefragm<strong>en</strong>t 4.1 is voorbeeldcode gegev<strong>en</strong> die de structuur aangeeft<br />

van Cg programma’s. De inputstream bestaat hier uit records van het type<br />

21


Vertex Shader<br />

Input Stream Output Stream<br />

RECORD {<br />

Vertex (x_1,y_1,z_1)<br />

Color (R,G,B,A)<br />

}<br />

Float Array<br />

3D Vector<br />

RECORD {<br />

Vertex (x_2,y_2,z_2)<br />

TexCoord (u,v)<br />

}<br />

Figuur 4.2: Concreet Stream Programming Model schema voor de <strong>GPU</strong>.<br />

inputRecord. Deze word<strong>en</strong> door de kernel, zijnde de cgMain, verwerkt zodat<br />

e<strong>en</strong> outputstream verkreg<strong>en</strong> wordt. Deze outputstream bestaat uit elem<strong>en</strong>t<strong>en</strong><br />

van het type outputRecord. In volg<strong>en</strong>de sectie zal er besprok<strong>en</strong> word<strong>en</strong> welke<br />

data zich in deze records kunn<strong>en</strong> bevind<strong>en</strong>.<br />

Merk <strong>op</strong> dat deze code ev<strong>en</strong>goed voor e<strong>en</strong> vertex als fragm<strong>en</strong>t shader kan<br />

funger<strong>en</strong>. In de volg<strong>en</strong>de paragraaf zal er wel degelijk e<strong>en</strong> <strong>op</strong>splitsing gemaakt<br />

di<strong>en</strong><strong>en</strong> te word<strong>en</strong>, aangezi<strong>en</strong> de vertex <strong>en</strong> fragm<strong>en</strong>t shaders <strong>op</strong> verschill<strong>en</strong>de<br />

datastream types werk<strong>en</strong>.<br />

4.2.2 Input <strong>en</strong> output stream<br />

De vertex <strong>en</strong> fragm<strong>en</strong>t shaders krijg<strong>en</strong> twee soort<strong>en</strong> input, <strong>en</strong>erzijds variër<strong>en</strong>de,<br />

anderzijds uniforme. De variër<strong>en</strong>de is de input die per vertex (resp. fragm<strong>en</strong>t)<br />

verschill<strong>en</strong>d is, <strong>en</strong> de uniforme is de input die constant is voor e<strong>en</strong> gehele vertex<br />

(resp. fragm<strong>en</strong>t) stream. Merk het verband <strong>op</strong> met het stream programming<br />

model. De variër<strong>en</strong>de input komt overe<strong>en</strong> met de input stream, <strong>en</strong> de uniforme<br />

input is het globaal read-only geheug<strong>en</strong> dat ter beschikking is.<br />

Logischerwijs is het nodig om afsprak<strong>en</strong> te mak<strong>en</strong> voor de communicatie<br />

tuss<strong>en</strong> de applicatie, vertex <strong>en</strong> fragm<strong>en</strong>t shaders. De input van de vertex shader<br />

di<strong>en</strong>t <strong>op</strong> de juiste manier <strong>op</strong>gevang<strong>en</strong> te word<strong>en</strong> van de applicatie, <strong>en</strong> de output<br />

ervan moet ook correct word<strong>en</strong> doorgestuurd van de vertex naar de frag-<br />

22


struct inputRecord {<br />

/∗<br />

. . .<br />

∗/<br />

} ;<br />

struct outputRecord {<br />

/∗<br />

. . .<br />

∗/<br />

} ;<br />

/∗<br />

∗/<br />

Ev<strong>en</strong>tuele e x t r a data− <strong>en</strong> / o f f u n c t i e d e f i n i t i e s<br />

outputRecord cgMain ( inputRecord input ) {<br />

outputRecord output ;<br />

}<br />

/∗<br />

∗/<br />

. . .<br />

return output ;<br />

Codefragm<strong>en</strong>t 4.1: Cg kernel code structuur<br />

23


m<strong>en</strong>t shader. Merk <strong>op</strong> dat er zich tuss<strong>en</strong> de vertex <strong>en</strong> fragm<strong>en</strong>t shader nog de<br />

scanconversiefase bevindt, die doorgegev<strong>en</strong> waard<strong>en</strong> kan aanpass<strong>en</strong>, zoals het<br />

interpoler<strong>en</strong> van de texture coördinat<strong>en</strong>.<br />

Er zijn dus binding semantics voorzi<strong>en</strong> die het mogelijk mak<strong>en</strong> om e<strong>en</strong> variabele<br />

aan e<strong>en</strong> bepaalde unit te k<strong>op</strong>pel<strong>en</strong> (bv. kleur, texture coördinat<strong>en</strong>, e.a.).<br />

Deze zijn verschill<strong>en</strong>d voor de vertex <strong>en</strong> fragm<strong>en</strong>t shaders, dus zull<strong>en</strong> afzonderlijk<br />

behandeld word<strong>en</strong>.<br />

Vertex shader<br />

De volg<strong>en</strong>de input binding semantics voor e<strong>en</strong> vertex shader zull<strong>en</strong> steeds beschikbaar<br />

zijn, hoewel er bij specifieke profiel<strong>en</strong> 2 extra mogelijkhed<strong>en</strong> bestaan (bv.<br />

COLOR):<br />

POSITION BLENDWEIGHT TANGENT BINORMAL<br />

NORMAL TEXCOORD0-TEXCOORD7 PSIZE BLENDINDICES<br />

In Op<strong>en</strong>GL [Ope] kunn<strong>en</strong> variabel<strong>en</strong> door de applicatie doorgegev<strong>en</strong> word<strong>en</strong><br />

door glVertex, glNormal, glTexCoord, . . . aan te roep<strong>en</strong>, die respectievelijk<br />

POSITION, NORMAL, TEXCOORD0, . . . e<strong>en</strong> waarde toek<strong>en</strong>n<strong>en</strong>.<br />

De minimum vereiste output binding semantics zijn de volg<strong>en</strong>de:<br />

POSITION PSIZE FOG<br />

COLOR0-COLOR1 TEXCOORD0-TEXCOORD7<br />

Fragm<strong>en</strong>t shader<br />

De per fragm<strong>en</strong>t variër<strong>en</strong>de input zijn de al dan niet geïnterpoleerde waard<strong>en</strong><br />

geproduceerd door de vertex shader. De output binding semantics zijn COLOR<br />

<strong>en</strong> soms ook DEPTH, afhankelijk van het gebruikte profiel. Sinds het bestaan van<br />

MRT 3 is het mogelijk geword<strong>en</strong> om in één <strong>en</strong>kele fragm<strong>en</strong>t shader, meerdere<br />

resultaatwaard<strong>en</strong> te bepal<strong>en</strong>.<br />

4.2.3 Read-only geheug<strong>en</strong><br />

De constante gegev<strong>en</strong>s voor de hele input stream kunn<strong>en</strong> meegegev<strong>en</strong> word<strong>en</strong><br />

door middel van uniform parameters. Deze moet<strong>en</strong> vooraf in de C/C++ code<br />

gek<strong>op</strong>peld <strong>en</strong> ingevuld word<strong>en</strong> door de gepaste functies aan te roep<strong>en</strong>. Ook de<br />

gebruikte textures zijn read-only geheug<strong>en</strong>. Het is dus onmogelijk om rechtstreeks<br />

verandering<strong>en</strong> aan te br<strong>en</strong>g<strong>en</strong> in e<strong>en</strong> texture. Dit is echter wel mogelijk<br />

door de output van de fragm<strong>en</strong>t shader om te vorm<strong>en</strong> tot e<strong>en</strong> texture, <strong>en</strong> deze<br />

als input mee te gev<strong>en</strong> aan e<strong>en</strong> volg<strong>en</strong>de fragm<strong>en</strong>t shader (CTT 4 /RTT 5 ).<br />

2 Het profiel geeft aan waar de machinetaal, gecompileerd uit de Cg-code, aan moet voldo<strong>en</strong>.<br />

Concreet houdt dit in of de shader data gaat ontvang<strong>en</strong> vanuit Op<strong>en</strong>GL of DirectX, <strong>en</strong> met<br />

welk shader model er gewerkt wordt, bijvoorbeeld Shader Model 3.0. De hardware di<strong>en</strong>t<br />

dan te voldo<strong>en</strong> aan e<strong>en</strong> bepaald shader model. E<strong>en</strong> shader model specifiëert de minumum<br />

te ondersteun<strong>en</strong> shader l<strong>en</strong>gte, of dynamic branching ondersteund wordt, de floating point<br />

precisie, e.a. Voor meer info, zie [nVi, sha]<br />

3 Multiple R<strong>en</strong>der Target<br />

4 C<strong>op</strong>y to texture<br />

5 R<strong>en</strong>der to texture<br />

24


4.2.4 Voorbeeld vertex <strong>en</strong> fragm<strong>en</strong>t shader<br />

Voorbeeldcode van e<strong>en</strong> vertex <strong>en</strong> fragm<strong>en</strong>t shader, geschrev<strong>en</strong> in Cg, zijn te<br />

vind<strong>en</strong> in codefragm<strong>en</strong>t 4.2 <strong>en</strong> 4.3. Het betreft e<strong>en</strong> realtime b<strong>en</strong>adering van per<br />

pixel refractie. Deze code is overg<strong>en</strong>om<strong>en</strong> van “Cg Toolkit” [nVi] <strong>en</strong> wordt hier<br />

gebruikt als voorbeeld van e<strong>en</strong> uitgewerkte vertex <strong>en</strong> fragm<strong>en</strong>t shader.<br />

Het vermeld<strong>en</strong> van deze code heeft als <strong>en</strong>ige doel e<strong>en</strong> concreet voorbeeld te<br />

gev<strong>en</strong> van e<strong>en</strong> shader. Het is dus niet noodzakelijk de code volledig te begrijp<strong>en</strong>,<br />

maar het volstaat om de algem<strong>en</strong>e structuur <strong>en</strong> de in vorige paragraf<strong>en</strong> besprok<strong>en</strong><br />

zak<strong>en</strong>, te herk<strong>en</strong>n<strong>en</strong>. Zo is het duidelijk dat de vertex kernel, main, gegev<strong>en</strong><br />

data elem<strong>en</strong>t<strong>en</strong> van het type inputs, data elem<strong>en</strong>t<strong>en</strong> van het type outputs<br />

<strong>op</strong>levert. Dit gebeurt aan de hand van <strong>en</strong>kele uniforme variabel<strong>en</strong>, <strong>en</strong> e<strong>en</strong> extra<br />

geschrev<strong>en</strong> functie, fast_fresnel. De mapping van de data, die zich bevind<strong>en</strong><br />

in inputs <strong>en</strong> outputs, naar de gebruikte units (POSITION, TEXCOORD0 e.a) is<br />

ook duidelijk zichtbaar in deze code.<br />

De fragm<strong>en</strong>t shader ontvangt dan uiteindelijk drie van de vier waard<strong>en</strong>, uitgevoerd<br />

door de vertex shader, zijnde refractVec, reflectVec <strong>en</strong> fresnelTerm.<br />

Merk dus <strong>op</strong> dat hPosition niet rechtstreeks gebruikt wordt door de fragm<strong>en</strong>t<br />

shader. Deze waarde wordt <strong>en</strong>kel uitgevoerd door de vertex shader, zodat de<br />

texture coördinat<strong>en</strong> kunn<strong>en</strong> geïnterpoleerd word<strong>en</strong> tijd<strong>en</strong>s de rasterisatiefase.<br />

Voor meer details in verband met programmer<strong>en</strong> in Cg, zie [FK03]. E<strong>en</strong><br />

scre<strong>en</strong>shot van e<strong>en</strong> ger<strong>en</strong>derd beeld door middel van deze shadercombinatie is<br />

zichtbaar in figuur 4.3.<br />

Figuur 4.3: Scre<strong>en</strong>shot van refractie b<strong>en</strong>adering in Cg. (Bron: “Cg Toolkit”).<br />

struct inputs {<br />

float4 P o s i t i o n : POSITION ;<br />

float4 Normal : NORMAL;<br />

} ;<br />

25


struct outputs {<br />

float4 h P o s i t i o n : POSITION ;<br />

float4 fresnelTerm : COLOR0;<br />

float4 r e f r a c t V e c : TEXCOORD0;<br />

float4 r e f l e c t V e c : TEXCOORD1;<br />

} ;<br />

// f r e s n e l approximation<br />

fixed f a s t f r e s n e l ( float3 I , float3 N, float3 f r e s n e l V a l u e s ) {<br />

fixed power = f r e s n e l V a l u e s . x ;<br />

fixed s c a l e = f r e s n e l V a l u e s . y ;<br />

fixed b i a s = f r e s n e l V a l u e s . z ;<br />

return b i a s + pow ( 1 . 0 − dot ( I , N) , power ) ∗ s c a l e ;<br />

}<br />

outputs main (<br />

inputs IN ,<br />

uniform float4x4 ModelViewProj ,<br />

uniform float4x4 ModelView ,<br />

uniform float4x4 ModelViewIT ,<br />

uniform float theta ) {<br />

outputs OUT;<br />

OUT. h P o s i t i o n = mul ( ModelViewProj , IN . P o s i t i o n ) ;<br />

// convert p o s i t i o n and normal i n t o a p p r o p r i a t e spaces<br />

float3 eyeToVert = mul ( ModelView , IN . P o s i t i o n ) . xyz ;<br />

eyeToVert = normalize ( eyeToVert ) ;<br />

float3 normal = mul ( ModelViewIT , IN . Normal ) . xyz ;<br />

normal = normalize ( normal ) ;<br />

OUT. r e f r a c t V e c . xyz = r e f r a c t ( eyeToVert , normal , theta ) ;<br />

OUT. r e f r a c t V e c .w = 1 ;<br />

OUT. r e f l e c t V e c . xyz = r e f l e c t ( eyeToVert , normal ) ;<br />

OUT. r e f l e c t V e c .w = 1 ;<br />

// c a l c u l a t e the f r e s n e l r e f l e c t i o n<br />

OUT. fresnelTerm = f a s t f r e s n e l (−eyeToVert , normal ,<br />

float3 ( 5 . 0 , 1 . 0 , 0 . 0 ) ) ;<br />

return OUT;<br />

}<br />

Codefragm<strong>en</strong>t 4.2: Cg vertex shader voor refractie<br />

float4 main ( in float3 r e f r a c t V e c : TEXCOORD0,<br />

in float3 r e f l e c t V e c : TEXCOORD1,<br />

in float3 fresnelTerm : COLOR0,<br />

uniform samplerCUBE <strong>en</strong>vironm<strong>en</strong>tMaps [ 2 ] ,<br />

uniform float e n a b l e R e f r a c t i o n ,<br />

uniform float e n a b l e F r e s n e l ) : COLOR {<br />

float3 r e f r a c t C o l o r = texCUBE( <strong>en</strong>vironm<strong>en</strong>tMaps [ 0 ] ,<br />

r e f r a c t V e c ) . rgb ;<br />

float3 r e f l e c t C o l o r = texCUBE( <strong>en</strong>vironm<strong>en</strong>tMaps [ 1 ] ,<br />

r e f l e c t V e c ) . rgb ;<br />

26


}<br />

float3 r e f l e c t R e f r a c t = l e r p ( r e f r a c t C o l o r , r e f l e c t C o l o r ,<br />

fresnelTerm ) ;<br />

float3 f i n a l C o l o r = e n a b l e R e f r a c t i o n ?<br />

( e n a b l e F r e s n e l ? r e f l e c t R e f r a c t : r e f r a c t C o l o r ) :<br />

( e n a b l e F r e s n e l ? r e f l e c t C o l o r : fresnelTerm ) ;<br />

return float4 ( f i n a l C o l o r , 1 . 0 ) ;<br />

Codefragm<strong>en</strong>t 4.3: Cg fragm<strong>en</strong>t shader voor refractie<br />

4.3 G<strong>en</strong>eral Purpose <strong>GPU</strong> programmer<strong>en</strong><br />

Met de k<strong>en</strong>nis die we tot nu toe <strong>op</strong>gebouwd hebb<strong>en</strong>, is het niet moeilijk om in te<br />

zi<strong>en</strong> dat de <strong>GPU</strong> ook toepassing<strong>en</strong> heeft buit<strong>en</strong> het computer graphics domein.<br />

Ess<strong>en</strong>tiëel komt het er<strong>op</strong> neer dat we de “grafische” informatie (bv textures,<br />

vertices, kleur<strong>en</strong>, . . . ) zull<strong>en</strong> interpreter<strong>en</strong> als iets totaal anders (bv. krachtveld,<br />

matrix, . . . ). Zo word<strong>en</strong> textures typisch gebruikt om datastructur<strong>en</strong> in <strong>op</strong><br />

te slaan, <strong>en</strong> door te gev<strong>en</strong> aan de fragm<strong>en</strong>t shader. Pointers, iets wat niet<br />

beschikbaar is in Cg, kunn<strong>en</strong> dan geëmuleerd word<strong>en</strong> door middel van indices<br />

(bv. int). Merk wel <strong>op</strong> dat het herschrijv<strong>en</strong> van e<strong>en</strong> g<strong>en</strong>eral purpose programma<br />

voor de <strong>GPU</strong> pas nuttig is als het over e<strong>en</strong> groot aantal <strong>op</strong>eraties van beperkte<br />

complexiteit gaat, <strong>op</strong> steeds dezelfde data. Met andere woord<strong>en</strong>, als het <strong>op</strong> e<strong>en</strong><br />

niet artificiële manier herschrijfbaar is zodat het voldoet aan het voorg<strong>en</strong>oemde<br />

stream programming model. Meer over GP<strong>GPU</strong> programmer<strong>en</strong> is te vind<strong>en</strong> <strong>op</strong><br />

[gpg].<br />

4.4 Moeilijkhed<strong>en</strong><br />

In de praktijk is het <strong>GPU</strong> programmer<strong>en</strong> (in Cg) niet zo evid<strong>en</strong>t als dat het<br />

<strong>op</strong> het eerst zicht lijkt. Aangezi<strong>en</strong> het nog allemaal in volle ontwikkeling is,<br />

zijn er nog redelijk wat kinderziekt<strong>en</strong> die <strong>op</strong>duik<strong>en</strong>. Hierbij d<strong>en</strong>k ik aan driver<br />

problem<strong>en</strong> zoals het nog niet ondersteun<strong>en</strong> van bepaalde functionaliteit, of erger<br />

nog, het foutief ondersteun<strong>en</strong> ervan. Ook zijn er voor Cg nog niet bijzonder veel<br />

tools verkrijgbaar, zoals e<strong>en</strong> debugger <strong>en</strong> profiler.<br />

Het <strong>op</strong>slaan <strong>en</strong> doorgev<strong>en</strong> van datastructur<strong>en</strong> in textures zorgt ook voor extra<br />

last. Niet alle<strong>en</strong> is het dikwijls omslachtig om de datastructuur te doorl<strong>op</strong><strong>en</strong>,<br />

maar ook is elke texture gelimiteerd qua grootte <strong>en</strong> zijn deze read-only. Ook is<br />

het aantal van deze textures nog e<strong>en</strong>s beperkt. Gelukkig zijn er teg<strong>en</strong>woordig<br />

wel ext<strong>en</strong>sies beschikbaar zodat er “non power of 2” textures toegelat<strong>en</strong> word<strong>en</strong>,<br />

om de pijn te verzacht<strong>en</strong>.<br />

Recursie is ook iets wat onmogelijk is, <strong>en</strong> di<strong>en</strong>t geëmuleerd te word<strong>en</strong> (wat<br />

<strong>op</strong> zich ge<strong>en</strong> probleem is, maar wat het programmer<strong>en</strong> gewoonlijk minder rechttoe-recht-aan<br />

maakt).<br />

Verder is er de last met de trage overdrachtsnelheid van data van de <strong>GPU</strong><br />

naar de <strong>CPU</strong>, vooral bij e<strong>en</strong> AGP poort. Zie hiervoor hoofdstuk 3.3.<br />

Shaders zijn beperkt in aantal instructies. Enerzijds is er e<strong>en</strong> maximum<br />

<strong>op</strong>gelegd voor het aantal instructies waaruit de assemblercode bestaat, anderszijds<br />

is er ook e<strong>en</strong> maximum voor het aantal instructies dat daadwerkelijk<br />

27


uitgevoerd kan word<strong>en</strong>. Dit wordt respectievelijk het statisch <strong>en</strong> dynamisch aantal<br />

instructies g<strong>en</strong>oemd. Het dynamisch aantal instructies is typisch meerdere<br />

mal<strong>en</strong> hoger dan het statisch aantal. Indi<strong>en</strong> e<strong>en</strong> shaders toch dit aantal instructies<br />

probeert te overschrijd<strong>en</strong>, wordt deze afgebrok<strong>en</strong> <strong>en</strong> sprek<strong>en</strong> we van e<strong>en</strong><br />

time-out. Dit resulteert in pixels met e<strong>en</strong> ongedefiniëerde <strong>en</strong> dus onbruikbare<br />

resultat<strong>en</strong>. Tijd<strong>en</strong>s het programmer<strong>en</strong> di<strong>en</strong>t ook hiermee rek<strong>en</strong>ing gehoud<strong>en</strong> te<br />

word<strong>en</strong>. Meer over deze t<strong>op</strong>ic is te vind<strong>en</strong> in [PF05], de FAQ sectie van [nVi]<br />

<strong>en</strong> <strong>op</strong> het forum van [gpg].<br />

Aangezi<strong>en</strong> de fragm<strong>en</strong>t shader e<strong>en</strong> SIMD processor is, is het ook niet aangewez<strong>en</strong><br />

om deze te beschouw<strong>en</strong> als e<strong>en</strong> MIMD, tijd<strong>en</strong>s het schrijv<strong>en</strong> ervan.<br />

Dit zal in vele gevall<strong>en</strong> leid<strong>en</strong> tot zeer trage shaders, wat vaak ongew<strong>en</strong>st is.<br />

E<strong>en</strong> onschuldige if-th<strong>en</strong>-else constructie moet dus met voorzichtigheid gebruikt<br />

word<strong>en</strong>, om efficiëntie te garander<strong>en</strong>. T<strong>en</strong> eerste neemt if-th<strong>en</strong> constructie 4 klok<br />

cycli in beslag, <strong>en</strong> e<strong>en</strong> if-th<strong>en</strong>-else 6 klok cycli. Dit is relatief veel als we wet<strong>en</strong><br />

dat normaliter meerdere wiskundige <strong>op</strong>eraties tegelijkertijd (<strong>op</strong> 4 tupels) in één<br />

klok cyclus kunn<strong>en</strong> uitgevoerd word<strong>en</strong>. T<strong>en</strong> tweede kunn<strong>en</strong> we best het gebruik<br />

van if-th<strong>en</strong>(-else) structur<strong>en</strong> beperk<strong>en</strong> vanwege het feit dat én de if, én de else<br />

uitgevoerd word<strong>en</strong> indi<strong>en</strong> er slechts 1 parallelle shader de if keuze neemt, <strong>en</strong> e<strong>en</strong><br />

andere de else keuze. Beide keuzemogelijkhed<strong>en</strong> zull<strong>en</strong> uitgevoerd word<strong>en</strong> maar<br />

slechts de werkelijk uitgevoerde zal perman<strong>en</strong>t gemaakt word<strong>en</strong>. Het is dus van<br />

belang om het aantal <strong>en</strong> de omvang van deze if-th<strong>en</strong>(-else) constructies in te<br />

perk<strong>en</strong>. Nauwgezet programmer<strong>en</strong> is dus de boodschap. Meer details over de<br />

grafische hardware architectuur, zie [PF05].<br />

Duidelijk staat het GP<strong>GPU</strong> programmer<strong>en</strong> nog in kinderscho<strong>en</strong><strong>en</strong>, maar<br />

gelukkig is het wel e<strong>en</strong> “hot t<strong>op</strong>ic”. E<strong>en</strong> positief gevolg van de grote belangstelling<br />

hierin is dat er e<strong>en</strong> stuwkracht aanwezig is die de vorige problem<strong>en</strong><br />

zal <strong>op</strong>loss<strong>en</strong>, of minst<strong>en</strong>s verzacht<strong>en</strong>. Verzacht<strong>en</strong>de omstandighed<strong>en</strong> zoud<strong>en</strong> onder<br />

andere meerdere tools, betere programmeertal<strong>en</strong>, <strong>en</strong> de aanwezigheid van<br />

meerdere, grotere textures kunn<strong>en</strong> zijn.<br />

28


Hoofdstuk 5<br />

Implem<strong>en</strong>tatie<br />

In dit hoofdstuk zal de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong> implem<strong>en</strong>tatie besprok<strong>en</strong> word<strong>en</strong>. Eerst<br />

word<strong>en</strong> de gekoz<strong>en</strong> gegev<strong>en</strong>sstructur<strong>en</strong> behandeld, daarna de algoritm<strong>en</strong> die er<strong>op</strong><br />

<strong>op</strong>erer<strong>en</strong>.<br />

5.1 Gegev<strong>en</strong>sstructur<strong>en</strong><br />

Vooraleer we door middel van e<strong>en</strong> fragm<strong>en</strong>t shader (in Cg), e<strong>en</strong> beeld kunn<strong>en</strong><br />

berek<strong>en</strong><strong>en</strong> van e<strong>en</strong> virturele scène, zijn er gegev<strong>en</strong>s nodig die de scène beschrijv<strong>en</strong>.<br />

Voor deze implem<strong>en</strong>tatie komt het er<strong>op</strong> neer dat we e<strong>en</strong> verzameling<br />

driehoek<strong>en</strong> w<strong>en</strong>s<strong>en</strong> (meshes), alsook e<strong>en</strong> lichtbron. De driehoek<strong>en</strong> bezitt<strong>en</strong> per<br />

vertex e<strong>en</strong> normaal (gebruikt voor Gouraud shading), <strong>en</strong> bestaan uit één kleur.<br />

De grotere datastructur<strong>en</strong> di<strong>en</strong><strong>en</strong> we telk<strong>en</strong>s door te gev<strong>en</strong> door middel van<br />

textures, de andere ev<strong>en</strong>tueel door uniforme variabel<strong>en</strong> 1 .<br />

In deze sectie word<strong>en</strong> de gebruikte gegev<strong>en</strong>sstructur<strong>en</strong> besprok<strong>en</strong>, met telk<strong>en</strong>s<br />

de bijbehor<strong>en</strong>de texturelayout.<br />

5.1.1 Mesh<br />

In deze sectie wordt toegelicht <strong>op</strong> welke manier de meshes zull<strong>en</strong> word<strong>en</strong> <strong>op</strong>geslag<strong>en</strong>,<br />

<strong>en</strong> waarom hiervoor ge<strong>op</strong>teerd wordt.<br />

Structuur<br />

Gewoonlijk word<strong>en</strong> driehoek<strong>en</strong> <strong>op</strong>geslag<strong>en</strong> als e<strong>en</strong> lijst van vertices <strong>en</strong> e<strong>en</strong> lijst<br />

van indices. Per driehoek zijn er dan drie indices, die verwijz<strong>en</strong> naar de vertices<br />

uit de vertex lijst. De belangrijkste red<strong>en</strong> waarvoor dit doorgaans zo gedaan<br />

wordt, is beperking van geheug<strong>en</strong>gebruik.<br />

In de <strong>GPU</strong> implem<strong>en</strong>tatie heb ik ge<strong>op</strong>teerd om ge<strong>en</strong> indexering te gebruik<strong>en</strong>.<br />

De <strong>op</strong>geslag<strong>en</strong> driehoek<strong>en</strong> kunn<strong>en</strong> gewoon beschouwd word<strong>en</strong> als e<strong>en</strong> lijst van<br />

vertices, waarbij elke drie <strong>op</strong> elkaar volg<strong>en</strong>de vertices e<strong>en</strong> driehoek vorm<strong>en</strong>. De<br />

red<strong>en</strong> hiervoor is dat we het aantal texture lookups voor het <strong>op</strong>vrag<strong>en</strong> van de<br />

geometrische informatie, met 25% kunn<strong>en</strong> lat<strong>en</strong> dal<strong>en</strong>. Hiervoor betal<strong>en</strong> we dus<br />

1 gebruik best textures voor constante data over de verschill<strong>en</strong>de frames, ipv uniforme<br />

variabel<strong>en</strong><br />

29


4<br />

5<br />

5<br />

6<br />

5<br />

Figuur 5.1: Voorbeeld van e<strong>en</strong> deel van e<strong>en</strong> mesh. De cijfers in de cirkels<br />

gev<strong>en</strong> aan door hoeveel driehoek<strong>en</strong> de betreff<strong>en</strong>de vertex gebruikt wordt.<br />

e<strong>en</strong> tol, die extra texture geheug<strong>en</strong> inhoudt. Voor e<strong>en</strong> gemiddeld model is er<br />

typisch minder dan twee keer zo veel geheug<strong>en</strong>ruimte nodig. Dit wordt verder<br />

in deze paragraaf toegelicht. Deze keuze is gemaakt om de e<strong>en</strong>voudige red<strong>en</strong><br />

dat modell<strong>en</strong> die de helft van de maximale texturegrootte vull<strong>en</strong>, niet meer tot<br />

interactieve resultat<strong>en</strong> zull<strong>en</strong> leid<strong>en</strong>, vanuit interessante camera standpunt<strong>en</strong>.<br />

Onderstel dat er nf driehoek<strong>en</strong> gegev<strong>en</strong> zijn, gedefiniëerd over nv vertices, <strong>en</strong><br />

de <strong>op</strong>slag van één vertex neemt één data elem<strong>en</strong>t in beslag (nl. e<strong>en</strong> drie-tupel<br />

(x, y, z)). De <strong>op</strong>slag van drie indices kunn<strong>en</strong> we duidelijk ook bijhoud<strong>en</strong> in<br />

e<strong>en</strong>zelfde soort data elem<strong>en</strong>t, namelijk als (index1, index2, index3). Het aantal<br />

data elem<strong>en</strong>t<strong>en</strong> dat nodig is indi<strong>en</strong> er met indexering gewerkt wordt, noem<strong>en</strong><br />

we mi <strong>en</strong> is dus gelijk aan nv + nf . Als er ge<strong>en</strong> sprake is van indexering, is er<br />

m = 3nf geheug<strong>en</strong> nodig.<br />

Beschouw de mesh weergegev<strong>en</strong> in figuur 5.1. Elke vertex heeft als label<br />

e<strong>en</strong> getal gekreg<strong>en</strong>, dat het aantal aanligg<strong>en</strong>de driehoek<strong>en</strong> voorstelt, voor de<br />

betreff<strong>en</strong>de vertex. In dit voorbeeld blijkt het dat e<strong>en</strong> vertex gemiddeld door 5<br />

driehoek<strong>en</strong> “gebruikt” wordt. Laat ons het gemiddeld aantal driehoek<strong>en</strong> waartoe<br />

e<strong>en</strong> vertex behoort, noter<strong>en</strong> als a. We kunn<strong>en</strong> <strong>op</strong> basis van a de geheug<strong>en</strong>to<strong>en</strong>ame<br />

van de voorgestelde t.o.v. de typische datastructuur, in kaart br<strong>en</strong>g<strong>en</strong>.<br />

Beschouw volg<strong>en</strong>de afleiding, waarbij we de verhouding van beide geheug<strong>en</strong>behoeft<strong>en</strong><br />

m<br />

mi onderzoek<strong>en</strong>.<br />

m<br />

mi<br />

= 3nf<br />

nv + nf<br />

=<br />

3nf<br />

a<br />

3nf<br />

+ nf<br />

7<br />

= 3nf<br />

3nf +anf<br />

a<br />

5<br />

3<br />

= 3anf<br />

(3 + a)nf<br />

= 3a<br />

3 + a<br />

Als we nu kijk<strong>en</strong> hoeveel geheug<strong>en</strong>to<strong>en</strong>ame er nodig is om de mesh van figuur<br />

5.1 <strong>op</strong> te slaan, kom<strong>en</strong> we <strong>op</strong> 3·5 15<br />

3+5 = 8 = 1, 875. Er is dus 87,5% meer geheug<strong>en</strong><br />

nodig. Het is natuurlijk ook belangrijk om te wet<strong>en</strong> hoeveel geheug<strong>en</strong> er in<br />

de extreemste gevall<strong>en</strong> verlor<strong>en</strong> gaat of gewonn<strong>en</strong> wordt. Stel dat elke vertex<br />

30


2,5<br />

2<br />

1,5<br />

1<br />

0,5<br />

0<br />

1<br />

2<br />

3<br />

4<br />

a<br />

Figuur 5.2: Functieverlo<strong>op</strong> van de functie f(a) = 3a<br />

3+a<br />

gemiddeld maar één keer gebruikt wordt, dan krijg<strong>en</strong> we 3·1<br />

3+1<br />

maw e<strong>en</strong> geheug<strong>en</strong>winst van van 25%.<br />

Beschouw volg<strong>en</strong>de functie:<br />

f : [1, +∞[→ R + : a ↦→ 3a<br />

3 + a<br />

5<br />

6<br />

7<br />

8<br />

= 3<br />

4<br />

= 0, 75, of<br />

Zie figuur 5.2 voor het functie verlo<strong>op</strong> van f. Om de maximale hoeveelheid<br />

verlor<strong>en</strong> ruimte te bepal<strong>en</strong>, zull<strong>en</strong> we eerst aanton<strong>en</strong> dat deze functie strikt<br />

monotoon stijg<strong>en</strong>d is, <strong>en</strong> vervolg<strong>en</strong>s naar het converg<strong>en</strong>tiegedrag kijk<strong>en</strong>. De<br />

9<br />

afgeleide van f is (3+a) 2 , die duidelijk positief is in haar domein. We hebb<strong>en</strong> dus<br />

inderdaad te mak<strong>en</strong> met e<strong>en</strong> strikt monotoon stijg<strong>en</strong>de functie. Het maximum<br />

is dus gewoon de waarde waarnaar deze functie convergeert, zijnde:<br />

lim f(a) = lim<br />

a→+∞ a→+∞<br />

3a<br />

= 3<br />

3 + a<br />

Nu hebb<strong>en</strong> we dus aangetoond dat we maximaal drie keer zoveel geheug<strong>en</strong><br />

nodig hebb<strong>en</strong>. Echter, dit zal in de praktijk niet gauw voor kom<strong>en</strong>. Als bevestiging<br />

van voorgaande afleiding, zijn er ook nog 100 voorbeeld modell<strong>en</strong> bij elkaar<br />

gesprokkeld, <strong>en</strong> de parameters ervan geanalyseerd (tabel A.1). Hieruit blijkt dat<br />

voor e<strong>en</strong> gemiddeld model (uit deze lijst), het gemiddelde aantal driehoek<strong>en</strong> per<br />

vertex, gelijk is aan drie. Dit wil zegg<strong>en</strong> dat er slechts 50% extra geheug<strong>en</strong><br />

vereist is. Wat ook <strong>op</strong>valt is het feit dat er slechts één van de geselecteerde 2<br />

modell<strong>en</strong> meer dan twee keer zoveel geheug<strong>en</strong> vraagt.<br />

2 Deze modell<strong>en</strong> werd<strong>en</strong> willekeurig geselecteerd van http://www.gamasutraexchange.com,<br />

http://www.galiciacad.com <strong>en</strong> http://pascal.leynaud.free.fr/3ds/<br />

31


Eerst driehoek<br />

X1 Y1 Z1 0 X2 Y2 Z2 0 X3 Y3 Z3 0<br />

X1 Y1 Z1 0<br />

Texturelayout<br />

Eerste vextex van laatste driehoek Onb<strong>en</strong>utte ruimte<br />

Figuur 5.3: Texturelayout voor de driehoek<strong>en</strong>.<br />

In vorige paragraaf werd besprok<strong>en</strong> hoe we de meshes zull<strong>en</strong> <strong>op</strong>slaan. Hoe we<br />

deze structuur nu uiteindelijk zull<strong>en</strong> voorstell<strong>en</strong> in e<strong>en</strong> texture is echter nog niet<br />

besprok<strong>en</strong>. Deze sectie is hier dan ook aan gewijd.<br />

Het is inmiddels duidelijk, <strong>en</strong> verantwoord, dat we de driehoek<strong>en</strong> zull<strong>en</strong> <strong>op</strong>slaan<br />

als e<strong>en</strong> soort lijst van vertices. Aangezi<strong>en</strong> we niet zomaar e<strong>en</strong> type lijst<br />

voor hand<strong>en</strong> hebb<strong>en</strong>, maar <strong>en</strong>kel textures om data in <strong>op</strong> te slaan, zull<strong>en</strong> we zo<br />

e<strong>en</strong> vertex lijst omvorm<strong>en</strong> voor <strong>op</strong>slag in e<strong>en</strong> texture. E<strong>en</strong> eerste zaak waar we<br />

rek<strong>en</strong>ing mee di<strong>en</strong><strong>en</strong> te houd<strong>en</strong> is dat er slechts e<strong>en</strong> beperkte ruimte beschikbaar<br />

is per texture. Dit levert voor deze implem<strong>en</strong>tatie ge<strong>en</strong> problematische<br />

beperking<strong>en</strong> <strong>op</strong>. Waar wel omhe<strong>en</strong> gewerkt moet word<strong>en</strong>, is het feit dat het<br />

niet mogelijk is om de gehele beschikbare texture ruimte te adresser<strong>en</strong> als e<strong>en</strong><br />

1D texture. Dit is e<strong>en</strong>voudig <strong>op</strong> te loss<strong>en</strong> door de data te plaats<strong>en</strong> in e<strong>en</strong> 2D<br />

texture [PDC + 03].<br />

De data elem<strong>en</strong>t<strong>en</strong>, waaruit de texture bestaat, zijn RGBA tupels. Eig<strong>en</strong>lijk<br />

zoud<strong>en</strong> RGB tupels volstaan, maar in de praktijk blijk<strong>en</strong> RGBA tupels<br />

efficiënter verwerkt te word<strong>en</strong>. Het gevolg daarvan is dat we de “A”, zijnde<br />

de alpha waarde, neger<strong>en</strong>. De mapping van e<strong>en</strong> vertex (x, y, z) naar RGBA is<br />

gekoz<strong>en</strong> als R ← x, G ← y, B ← z <strong>en</strong> A ← 0. Deze 0 waarde is natuurlijk<br />

facultatief, maar is handig voor ev<strong>en</strong>tuele debugging (t.o.v. e<strong>en</strong> ongedefiniëerde<br />

default waarde). Zie figuur 5.3 voor e<strong>en</strong> grafische weergave.<br />

Laat ons voor de gemakkelijkheid e<strong>en</strong> texture bekijk<strong>en</strong> als e<strong>en</strong> (grote) matrix.<br />

Zij t e<strong>en</strong> m bij n texture (<strong>en</strong> dus ook matrix), dan is ti,j het (in dit geval RGBA)<br />

tupel <strong>op</strong> rij i <strong>en</strong> kolom j, waarbij i ∈ {1, . . . , m} <strong>en</strong> j ∈ {1, . . . , n}. Voor het<br />

omvorm<strong>en</strong> van e<strong>en</strong> 1D array lookup <strong>op</strong> positie p (array[p]), naar e<strong>en</strong> 2D texture<br />

t, kunn<strong>en</strong> we e<strong>en</strong> e<strong>en</strong>voudige conversieformule gebruik<strong>en</strong>, namelijk i = p mod n<br />

<strong>en</strong> j = ⌊ p<br />

n⌋. Vervolg<strong>en</strong>s kan er verder gewerkt word<strong>en</strong> met ti,j in plaats van<br />

array[p]. Onb<strong>en</strong>utte tupels zull<strong>en</strong> nooit gelez<strong>en</strong> word<strong>en</strong> door de bijbehor<strong>en</strong>de<br />

algoritm<strong>en</strong>, dus kunn<strong>en</strong> ook e<strong>en</strong> waarde naar keuze krijg<strong>en</strong>, bv (0, 0, 0, 0). Deze<br />

paragraaf geldt analoog voor tupels van andere typ<strong>en</strong> (RGB, R, G, . . . ).<br />

Dit gezegd zijnde, is het vrij evid<strong>en</strong>t om e<strong>en</strong> mapping te vind<strong>en</strong> van de vertex<br />

lijst, naar e<strong>en</strong> texture. In de implem<strong>en</strong>tatie is dit gebeurd door driehoek 1 <strong>op</strong><br />

32


X1 Y1 Z1 0 X2 Y2 Z2 0 X3 Y3 Z3 0<br />

X1 Y1 Z1 0<br />

3 normal<strong>en</strong> + kleur van eerste driehoek<br />

R G B 0<br />

X2 Y2 Z2 0 X3 Y3 Z3 0 R G B 0<br />

Normaal vertex 1<br />

Normaal vertex 2<br />

Laastste driehoek<br />

Normaal vertex 3<br />

Kleur<br />

Figuur 5.4: Texturelayout voor de normal<strong>en</strong> <strong>en</strong> kleur<strong>en</strong>.<br />

Onb<strong>en</strong>utte ruimte<br />

slaan in t1,1, driehoek 2 in t1,2, . . . . Indi<strong>en</strong> j > n, dan verhog<strong>en</strong> we i met 1, <strong>en</strong><br />

stell<strong>en</strong> j gelijk aan 1, dit rij per rij.<br />

Let <strong>op</strong>, door e<strong>en</strong> kleine extra moeite is het mogelijk de rechstreekste implem<strong>en</strong>tatie<br />

van deze uite<strong>en</strong>zetting te <strong>op</strong>timaliser<strong>en</strong>. Als we zonder meer de breedte<br />

(n) kiez<strong>en</strong>, di<strong>en</strong><strong>en</strong> we per texture lookup te controler<strong>en</strong> in welke rij <strong>en</strong> kolom<br />

deze valt, gegev<strong>en</strong> e<strong>en</strong> volgnummer in de lijst. Indi<strong>en</strong> we er nu voor zorg<strong>en</strong> dat<br />

n deelbaar is door 3, moet dit slechts e<strong>en</strong>malig per driehoek gebeur<strong>en</strong>, ipv per<br />

vertex. Inderdaad, als we de plaats in de texture van de eerste vertex van e<strong>en</strong><br />

specifieke driehoek gevond<strong>en</strong> hebb<strong>en</strong>, wet<strong>en</strong> we met zekerheid dat de volg<strong>en</strong>de<br />

twee vertices zich <strong>op</strong> dezelfde rij bevind<strong>en</strong>, vlak achter deze vertex.<br />

5.1.2 Normal<strong>en</strong> <strong>en</strong> kleur<strong>en</strong><br />

De normal<strong>en</strong> (één per vertex) <strong>en</strong> de kleur (één per driehoek), word<strong>en</strong> sam<strong>en</strong><br />

in één texture ondergebracht. Dit gebeurd <strong>op</strong> totaal analoge wijze als in sectie<br />

5.1.1. Voor de volledigheid is er e<strong>en</strong> grafische voorstelling gegev<strong>en</strong> van de<br />

texturelayout, in figuur 5.4.<br />

5.1.3 Regular grid<br />

De gegev<strong>en</strong>sstructuur die we in deze sectie besprek<strong>en</strong> heeft als <strong>en</strong>ige doel het<br />

ray trac<strong>en</strong> van e<strong>en</strong> scène te versnell<strong>en</strong>. Hoewel het zeker niet de meest <strong>op</strong>timale<br />

structuur is voor e<strong>en</strong> doorsnee scène, is de gekoz<strong>en</strong> acceleratiestructuur e<strong>en</strong><br />

regular grid. Deze spatiale subdivisie is makkelijker te debugg<strong>en</strong> dan bv. e<strong>en</strong> kd<br />

tree, <strong>en</strong> volstaat voor in aantal driehoek<strong>en</strong> beperkte modell<strong>en</strong>. Voor complexe<br />

modell<strong>en</strong> is e<strong>en</strong> k-d tree zeker te overweg<strong>en</strong>, aangezi<strong>en</strong> deze in O(log n) doorl<strong>op</strong><strong>en</strong><br />

33


1 2<br />

4 5<br />

Figuur 5.5: Regular grid bestaande uit 6 voxels. Elke driehoek bevindt zich in<br />

één of meerdere voxels.Voxel 1 bevat ge<strong>en</strong> driehoek<strong>en</strong>, voxel 2 <strong>en</strong> 4 bevatt<strong>en</strong> 1<br />

driehoek, voxel 5 <strong>en</strong> 6 bevatt<strong>en</strong> 2 driehoek<strong>en</strong> <strong>en</strong> voxel 3 bevat 3 driehoek<strong>en</strong>.<br />

kan word<strong>en</strong>, t.o.v. O(n), waarbij n het aantal driehoek<strong>en</strong> is. Indi<strong>en</strong> n voldo<strong>en</strong>de<br />

klein is, zorgt e<strong>en</strong> regular grid niet voor e<strong>en</strong> bottl<strong>en</strong>eck. Aangezi<strong>en</strong> de focus van<br />

deze thesis eerder ligt <strong>op</strong> het vergelijk<strong>en</strong> van de r<strong>en</strong>dertijd<strong>en</strong> tuss<strong>en</strong> e<strong>en</strong> zeer<br />

analoge <strong>CPU</strong> <strong>en</strong> <strong>GPU</strong> implem<strong>en</strong>tatie, lijkt e<strong>en</strong> regular grid mij e<strong>en</strong> adequate<br />

keuze.<br />

Voor de <strong>op</strong>slag van het grid mak<strong>en</strong> we gebruik van twee textures. Eén texture<br />

zull<strong>en</strong> we gebruik<strong>en</strong> om per gridcel de lijst van driehoek<strong>en</strong> die hierin bevat zijn,<br />

bij te houd<strong>en</strong>. De tweede texture houdt dan per grid cel e<strong>en</strong> index bij waar de<br />

bijbehor<strong>en</strong>de driehoek lijst zich in de eerste texture bevindt. We zull<strong>en</strong> naar<br />

deze textures verwijz<strong>en</strong> door ze respectievelijk tdata <strong>en</strong> tindex te noem<strong>en</strong>.<br />

Laat tdata e<strong>en</strong> matrix zijn van RGBA tupels, waarvan we <strong>en</strong>kel de R nuttig<br />

zull<strong>en</strong> gebruik<strong>en</strong>. Ook dit is e<strong>en</strong> beslissing die g<strong>en</strong>om<strong>en</strong> is uit effeciëntie overweging<strong>en</strong>.<br />

De gegev<strong>en</strong>s die we in tdata w<strong>en</strong>s<strong>en</strong> te st<strong>op</strong>p<strong>en</strong>, zull<strong>en</strong> verzameling<strong>en</strong><br />

van driehoek<strong>en</strong> zijn, of maw e<strong>en</strong> lijst van verzameling<strong>en</strong> van driehoek. We<br />

beschouw<strong>en</strong> e<strong>en</strong> e<strong>en</strong>voudig voorbeeld, ter ondersteuning van de verdere uite<strong>en</strong>zetting.<br />

Figuur 5.5 geeft e<strong>en</strong> virtuele scène weer, waarbij de primitiev<strong>en</strong> (in dit<br />

geval driehoek<strong>en</strong>), ondergebracht zijn in e<strong>en</strong> gridstructuur. De voxels, ook wel<br />

cell<strong>en</strong> g<strong>en</strong>oemd, zijn g<strong>en</strong>ummerd van 1 tot 6. Hieruit wordt dan de lijst van<br />

driehoekverzameling<strong>en</strong> geg<strong>en</strong>ereerd. In figuur 5.6 is dit schematisch weergegev<strong>en</strong>.<br />

Nu zijn we aangekom<strong>en</strong> <strong>op</strong> het punt dat we deze symbolische lijst gaan<br />

omzett<strong>en</strong> naar texture data. Dit kunn<strong>en</strong> we e<strong>en</strong>voudig door verzameling per<br />

verzameling om te zett<strong>en</strong>, <strong>en</strong> die achter elkaar te plaats<strong>en</strong>. Merk <strong>op</strong> dat we<br />

met achter elkaar plaats<strong>en</strong> bedoel<strong>en</strong> dat de texture kolom per kolom, rij per<br />

rij gevuld wordt. We moet<strong>en</strong> eerst nog wel definiër<strong>en</strong> hoe we e<strong>en</strong> verzameling<br />

driehoek<strong>en</strong> gaan voorstell<strong>en</strong>. Dit do<strong>en</strong> we door de volgnummers van de betreff<strong>en</strong>de<br />

driehoek<strong>en</strong> achter elkaar te plaats<strong>en</strong>, beëindigt door e<strong>en</strong> -1. Wanneer we<br />

alle verzameling<strong>en</strong> achter elkaar plaats<strong>en</strong>, krijg<strong>en</strong> iets van de vorm 3 6 7 8 -1 2<br />

9 11 -1 2 -1 -1 10 13 . . . (voor e<strong>en</strong> willekeurige scène). Plaats nu elk van deze<br />

getall<strong>en</strong> in de R compon<strong>en</strong>t van de texture, <strong>en</strong> tdata is klaar.<br />

34<br />

6<br />

3


1 2 3<br />

4 5 6<br />

Figuur 5.6: Regular grid voorgesteld door e<strong>en</strong> lijst van driehoek<strong>en</strong>verzameling<strong>en</strong>.<br />

Nu rest er ons nog tindex te construer<strong>en</strong>, hoewel het strikt g<strong>en</strong>om<strong>en</strong> volstaat<br />

om <strong>en</strong>kel te beschikk<strong>en</strong> over tdata. De <strong>en</strong>ige red<strong>en</strong> waarvoor we tindex zull<strong>en</strong><br />

construer<strong>en</strong>, is het beperk<strong>en</strong> van de tijd nodig om de driehoek<strong>en</strong> van e<strong>en</strong> gegev<strong>en</strong><br />

voxel te vind<strong>en</strong>. Indi<strong>en</strong> tindex niet zou bestaan, di<strong>en</strong><strong>en</strong> we gemiddeld ongeveer de<br />

helft van de tdatatexture te lez<strong>en</strong>, alvor<strong>en</strong>s we de juiste voxel gevond<strong>en</strong> hebb<strong>en</strong>.<br />

tindex biedt hier dus e<strong>en</strong> <strong>op</strong>lossing voor. Voor elke voxel staat er in de texture<br />

e<strong>en</strong> index, die aangeeft waar de corresponder<strong>en</strong>de verzameling van driehoek<strong>en</strong><br />

zich bevindt in tdata. Deze verzameling is dan beëindigt door e<strong>en</strong> -1, zoals<br />

vroeger aangegev<strong>en</strong>. Zie figuur 5.7 voor e<strong>en</strong> grafische voorstelling van tdata in<br />

combinatie met tindex.<br />

De indices di<strong>en</strong><strong>en</strong> ook in e<strong>en</strong> gek<strong>en</strong>de volgorde <strong>op</strong>geslag<strong>en</strong> te zijn in e<strong>en</strong><br />

texture. Dit do<strong>en</strong> we <strong>op</strong> de gebruikelijke manier, kolom per kolom <strong>en</strong> rij per<br />

rij. Vooraleer we daartoe in staat zijn, moet<strong>en</strong> we kunn<strong>en</strong> beschikk<strong>en</strong> over e<strong>en</strong><br />

volgnummer per voxel (x, y, z) in het grid met breedte sx, hoogte sy <strong>en</strong> diepte<br />

sz. Dit volgnummer, noem het p, kunn<strong>en</strong> we bepal<strong>en</strong> door volg<strong>en</strong>de formule:<br />

p = x + y.sx + z.sx.sy. De indices word<strong>en</strong> weerom <strong>op</strong>geslag<strong>en</strong> in RGBA tupels,<br />

waarvan <strong>en</strong>kel de R compon<strong>en</strong>t gebruikt wordt.<br />

Merk <strong>op</strong> dat er in tdata dikwijls verscheid<strong>en</strong>e <strong>op</strong>e<strong>en</strong>volg<strong>en</strong>de getall<strong>en</strong> -1 zull<strong>en</strong><br />

zijn, indi<strong>en</strong> er meerdere aanelkaar geslot<strong>en</strong> lege voxels zijn. Deze kunn<strong>en</strong> telk<strong>en</strong>s<br />

vervang<strong>en</strong> word<strong>en</strong> door slechts één -1, mits de nodige aanpassing<strong>en</strong> in tindex.<br />

Voor de lege cell<strong>en</strong> lat<strong>en</strong> we deze gewoon steeds verwijz<strong>en</strong> naar dezelfde -1 in<br />

tdata, die altijd aanwezig zal zijn.<br />

5.2 Algoritm<strong>en</strong><br />

In deze sectie word<strong>en</strong> de gebruikte algoritm<strong>en</strong> in de <strong>GPU</strong>/<strong>CPU</strong> implem<strong>en</strong>tatie<br />

besprok<strong>en</strong>. Deze algoritm<strong>en</strong> mak<strong>en</strong> gebruik van de gegev<strong>en</strong>sstructur<strong>en</strong><br />

beschrev<strong>en</strong> in sectie 5.1.<br />

5.2.1 <strong>CPU</strong><br />

De algoritm<strong>en</strong> die uitgevoerd word<strong>en</strong> <strong>op</strong> de <strong>CPU</strong> zijn geschrev<strong>en</strong> in de programmeertaal<br />

C++. Vergelek<strong>en</strong> met de hoeveelheid Cg-code, betreft dit het<br />

overwicht van de code. Doch, dit zijn hoofdzakelijk oninteressante algoritm<strong>en</strong><br />

35


-1<br />

Verzameling driehoek<strong>en</strong><br />

3 5 -1 0 -1 1 4 5 -1 2 7 8 9 -1 8 9 11<br />

12 -1 8 13 -1 ...<br />

0 0 1 4 0 6 10<br />

...<br />

Index Onb<strong>en</strong>utte ruimte<br />

Figuur 5.7: Regular grid voorgesteld aan de hand van twee textures, tdata<br />

(bov<strong>en</strong>aan) <strong>en</strong> tindex (onderaan). tdata bevat de driehoek<strong>en</strong>verzameling<strong>en</strong>, <strong>en</strong><br />

tindex verwijzing<strong>en</strong> naar de startplaats<strong>en</strong> van de driehoek<strong>en</strong>verzameling<strong>en</strong>. Het<br />

einde van e<strong>en</strong> driehoek<strong>en</strong>verzameling<strong>en</strong> in tdata wordt aangegev<strong>en</strong> met e<strong>en</strong> -1.<br />

36


om te besprek<strong>en</strong>. Enkel het <strong>op</strong>bouw<strong>en</strong> van de gridstructuur zal in meer detail<br />

uit de doek<strong>en</strong> gedaan word<strong>en</strong>.<br />

Om de camera <strong>op</strong> e<strong>en</strong> intuïtieve manier in de scène te kunn<strong>en</strong> positioner<strong>en</strong>, is<br />

er e<strong>en</strong> navigatiesysteem gebouwd. Dit systeem geeft interactief beeld<strong>en</strong> van de<br />

scène weer, vanuit het huidige standpunt <strong>en</strong> kijkrichting. Er is de mogelijkheid<br />

voorzi<strong>en</strong> om dit beeld te bepal<strong>en</strong> door middel van e<strong>en</strong> standaard geometrie <strong>en</strong>gine,<br />

of door middel van ray tracing. De ger<strong>en</strong>derde beeld<strong>en</strong> word<strong>en</strong> weergegev<strong>en</strong><br />

via Op<strong>en</strong>GL [Ope], in e<strong>en</strong> Qt [Tro] v<strong>en</strong>ster.<br />

De modell<strong>en</strong> die gelad<strong>en</strong> word<strong>en</strong> om vervolg<strong>en</strong>s 2D beeld<strong>en</strong> van te g<strong>en</strong>erer<strong>en</strong>,<br />

zijn van het type 3DS [3DS]. Deze word<strong>en</strong> ingelez<strong>en</strong> met behulp van de<br />

bibliotheek lib3ds [lib]. Vervolg<strong>en</strong>s word<strong>en</strong> de ingelez<strong>en</strong> data <strong>op</strong>geslag<strong>en</strong> in de<br />

textures, zoals in meer detail besprok<strong>en</strong> in hoofdstuk 5.1.<br />

Het <strong>op</strong>bouw<strong>en</strong> van de regular grid structuur bestaat ess<strong>en</strong>tiëel uit twee stapp<strong>en</strong>,<br />

zijnde het bepal<strong>en</strong> van het aantal voxels, <strong>en</strong> het vull<strong>en</strong> van de voxels.<br />

Laat ons het aantal voxels noter<strong>en</strong> als nx, ny <strong>en</strong> nz, waarbij de index bij de n<br />

telk<strong>en</strong>s de betreff<strong>en</strong>de as aangeeft. Het aantal voxels die “nodig” zijn, hangt<br />

sterk sam<strong>en</strong> met het totaal aantal driehoek<strong>en</strong>, <strong>en</strong> de l<strong>en</strong>gte (wx), breedte (wy)<br />

<strong>en</strong> diepte (wz) van het grid. In de praktijk blijk<strong>en</strong> min of meer kubische voxels,<br />

in e<strong>en</strong> grid waarbij het aantal voxels in de grootte-orde ligt van het aantal<br />

driehoek<strong>en</strong>, <strong>op</strong>timaal te zijn. [Shi00]<br />

E<strong>en</strong> formule die voldoet aan bov<strong>en</strong>vermelde eis<strong>en</strong>, ziet er als volgt uit [Shi00]:<br />

s = 3<br />

nx = ⌊ wx<br />

s<br />

ny = ⌊ wy<br />

s<br />

nz = ⌊ wz<br />

s<br />

wxwywz<br />

n<br />

+ 1<br />

2 ⌋<br />

+ 1<br />

2 ⌋<br />

+ 1<br />

2 ⌋<br />

Nu het aantal voxels in de drie dim<strong>en</strong>sie gek<strong>en</strong>d zijn, kunn<strong>en</strong> de voxels gevuld<br />

word<strong>en</strong> met driehoek<strong>en</strong>. Aangezi<strong>en</strong> dit zeer recht-toe-recht-aan kan gebeur<strong>en</strong>,<br />

zal dit hier niet volledig uitgeschrev<strong>en</strong> word<strong>en</strong>. Er is echter wel één belangrijke<br />

zaak die minder triviaal is, namelijk het bepal<strong>en</strong> van welke voxels er<br />

geïntersecteerd word<strong>en</strong> door e<strong>en</strong> gegev<strong>en</strong> driehoek. Dit kan gebeur<strong>en</strong> door het<br />

schrijv<strong>en</strong> van e<strong>en</strong> 3D scanconversie algoritme voor driehoek<strong>en</strong>.<br />

Aangezi<strong>en</strong> voor deze thesis de focus niet ligt <strong>op</strong> het <strong>op</strong>stell<strong>en</strong> van e<strong>en</strong> “perfecte”<br />

gridstructuur, wordt er ge<strong>op</strong>teerd voor e<strong>en</strong> heuristiek, die makkelijker<br />

te implem<strong>en</strong>ter<strong>en</strong> is. In plaats van e<strong>en</strong> 3D scanconversie van de driehoek zelf,<br />

verkiez<strong>en</strong> we e<strong>en</strong> scanconversie van de kleinst mogelijke bounding box rond deze<br />

driehoek. Merk <strong>op</strong> dat er zich bijgevolg soms overbodige driehoek<strong>en</strong> in bepaalde<br />

voxels bevind<strong>en</strong>, maar er zal ge<strong>en</strong> <strong>en</strong>kele driehoek ontbrek<strong>en</strong>. Figuur 5.8 geeft<br />

e<strong>en</strong> 2D grafische voorstelling van de resultat<strong>en</strong> van beide scanconversie algoritm<strong>en</strong>.<br />

5.2.2 <strong>GPU</strong><br />

In deze sectie zull<strong>en</strong> de algoritm<strong>en</strong> die uitgevoerd word<strong>en</strong> <strong>op</strong> grafische kaart,<br />

besprok<strong>en</strong> word<strong>en</strong>. Er zal uitgelegd word<strong>en</strong> hoe de eerste g<strong>en</strong>eratie stral<strong>en</strong><br />

37


Figuur 5.8: 3D scanconversie. Links: driehoek<strong>en</strong>, rechts: bounding boxes<br />

word<strong>en</strong> geg<strong>en</strong>ereerd, hoe deze de gridstructuur doorl<strong>op</strong><strong>en</strong>, <strong>en</strong> <strong>op</strong> welke manier<br />

intersecties ontdekt word<strong>en</strong> met de driehoek<strong>en</strong> die zich in de voxels bevind<strong>en</strong>.<br />

Oogstral<strong>en</strong> g<strong>en</strong>erer<strong>en</strong><br />

Het g<strong>en</strong>erer<strong>en</strong> van de oogstral<strong>en</strong>, ook wel primaire of eerste g<strong>en</strong>eratie stral<strong>en</strong><br />

g<strong>en</strong>oemd, kan met behulp van de grafische kaart voorzi<strong>en</strong> word<strong>en</strong> met e<strong>en</strong> minimum<br />

aan programmeerwerk. In de literatuur [Pur, Chr05, KL04] word<strong>en</strong> deze<br />

stral<strong>en</strong> telk<strong>en</strong>s in e<strong>en</strong> texture meegegev<strong>en</strong>, die al dan niet berek<strong>en</strong>d wordt door<br />

e<strong>en</strong> shader. Met de manier die in deze thesis voorzi<strong>en</strong> wordt, is het niet nodig om<br />

al deze oogstral<strong>en</strong> via e<strong>en</strong> texture door te gev<strong>en</strong>, <strong>en</strong> uit te lez<strong>en</strong> met de fragm<strong>en</strong>t<br />

shader. Hierdoor wordt er e<strong>en</strong> aanzi<strong>en</strong>lijke hoeveelheid geheug<strong>en</strong> bespaard, <strong>en</strong><br />

zal ook de texture cache minder belast word<strong>en</strong>.<br />

Eerst wordt er in Op<strong>en</strong>GL e<strong>en</strong> rechthoek getek<strong>en</strong>d met als grootte de v<strong>en</strong>stergrootte.<br />

Aan elk van 4 vertices k<strong>en</strong>n<strong>en</strong> we e<strong>en</strong> 3D texture coördinaat toe.<br />

Deze vier 3-tupels hebb<strong>en</strong> telk<strong>en</strong>s als waarde de positie van de corresponder<strong>en</strong>de<br />

vertex van het virtuele scherm in de 3D scène. Indi<strong>en</strong> we in Op<strong>en</strong>GL texture<br />

mapping aangezet hebb<strong>en</strong>, zal er per pixel in de fragm<strong>en</strong>t shader e<strong>en</strong><br />

3D geïnterpoleerde texture coördinaat ter beschikking zijn. Deze waarde geeft<br />

dan de 3D positie aan waar<strong>op</strong> de betreff<strong>en</strong>de pixel zich bevindt in de scène<br />

coördinat<strong>en</strong>. Het <strong>en</strong>ige wat er nu nog ontbreekt is één 3-tupel dat het camerastandpunt<br />

aangeeft. Dit kan makkelijk via e<strong>en</strong> uniforme variabele doorgegev<strong>en</strong><br />

word<strong>en</strong>, of mee in e<strong>en</strong> andere data texture geplaatst word<strong>en</strong>.<br />

Alle data nodig om e<strong>en</strong> straal te construer<strong>en</strong> zijn dus verworv<strong>en</strong>. Duidelijk<br />

is er ge<strong>en</strong> nood aan het schrijv<strong>en</strong> van e<strong>en</strong> extra shader, of e<strong>en</strong> C++ routine, die<br />

zich bezig houd<strong>en</strong> met het g<strong>en</strong>erer<strong>en</strong> <strong>en</strong> doorgev<strong>en</strong> van de oogstral<strong>en</strong>.<br />

Grid doorl<strong>op</strong><strong>en</strong><br />

Om zinvol gebruik te mak<strong>en</strong> van het <strong>op</strong>gebouwde regular grid, di<strong>en</strong><strong>en</strong> we dit<br />

correct <strong>en</strong> <strong>op</strong> e<strong>en</strong> efficiënte wijze te doorl<strong>op</strong><strong>en</strong>. Hiervoor gebruik<strong>en</strong> we het<br />

38


B C D<br />

A<br />

E F G<br />

H I<br />

J K<br />

Figuur 5.9: Doorl<strong>op</strong><strong>en</strong> van het regular grid. De geïntersecteerde voxels zijn<br />

aangegev<strong>en</strong> door e<strong>en</strong> letter <strong>op</strong> e<strong>en</strong> grijze achtergrond. Ze word<strong>en</strong> doorl<strong>op</strong><strong>en</strong> in<br />

alfabetische volgorde, tot de intersectie gevond<strong>en</strong> is.<br />

voorgestelde algoritme door Amanatides <strong>en</strong> Woo [AW87]. Het is e<strong>en</strong> snel <strong>en</strong><br />

e<strong>en</strong>voudig algoritme <strong>en</strong> het le<strong>en</strong>t zich goed om geconverteerd te word<strong>en</strong> naar de<br />

<strong>GPU</strong>. We zull<strong>en</strong> stap voor stap het uiteindelijke <strong>GPU</strong> algoritme <strong>op</strong>bouw<strong>en</strong>.<br />

Voor de duidelijkheid mak<strong>en</strong> we gebruik van e<strong>en</strong> situatieschets in twee dim<strong>en</strong>sies,<br />

zie hiervoor figuur 5.9. Lat<strong>en</strong> we e<strong>en</strong> straal r beschouw<strong>en</strong>, gegev<strong>en</strong><br />

door r(t) = o + td, waarbij o de oorsprong is, d de richtingsvector <strong>en</strong> t e<strong>en</strong> getal<br />

groter of gelijk aan 0. Uit figuur 5.9 blijkt dat o zich in voxel A bevindt. Om<br />

de intersectie met de juiste driehoek te ontdekk<strong>en</strong>, di<strong>en</strong><strong>en</strong> de voxels in de juiste<br />

volgorde doorl<strong>op</strong><strong>en</strong> te word<strong>en</strong>. In het geval van figuur 5.9 is dit de alfabetische<br />

lijst van voxels A, B, C, D, E, F, G, H, I, J, K, L. Dit algoritme zal telk<strong>en</strong>s de<br />

waarde van t verhog<strong>en</strong> zodat er naar de volg<strong>en</strong>de voxel wordt overgegaan.<br />

Het algoritme om de voxels te doorl<strong>op</strong><strong>en</strong> splits<strong>en</strong> we in twee belangrijke<br />

del<strong>en</strong>, zijnde de initialisatie <strong>en</strong> het increm<strong>en</strong>teel doorl<strong>op</strong><strong>en</strong> van het grid. In de<br />

initialisatiefase wordt er bepaald in welke voxel de straal start. Lat<strong>en</strong> we deze<br />

voxel (x, y, z) noem<strong>en</strong>. Indi<strong>en</strong> de oorsprong o zich binn<strong>en</strong> het grid bevindt, di<strong>en</strong>t<br />

er <strong>en</strong>kel <strong>op</strong>gezocht te word<strong>en</strong> in welke voxel dit punt zich bevindt. Het is echter<br />

ook mogelijk dat o buit<strong>en</strong> het grid geplaatst is, in dit geval moet<strong>en</strong> we bepal<strong>en</strong><br />

in welke voxel de straal het grid binn<strong>en</strong>komt. In beide gevall<strong>en</strong> ligt (x, y, z) dus<br />

vast. Ook tot deze fase behoort de invulling van de variabel<strong>en</strong> stepX, stepY<br />

<strong>en</strong> stepZ, waarbij stepX, stepY, stepZ ∈ {−1, 1}. stepX geeft aan of bij het<br />

doorkruis<strong>en</strong> van de straal <strong>en</strong> e<strong>en</strong> X-vlak van de huidige voxel, x di<strong>en</strong>t verhoogd<br />

of verlaagd te word<strong>en</strong>. Analoog geldt dit voor stepY <strong>en</strong> stepZ. Dit wil zegg<strong>en</strong><br />

dat we de waard<strong>en</strong> van stepX, stepY <strong>en</strong> stepZ kunn<strong>en</strong> bepal<strong>en</strong> door te kijk<strong>en</strong><br />

naar de tek<strong>en</strong>s van x, y <strong>en</strong> z. Concreet geeft dit:<br />

x > 0 ⇒ stepX = 1, anders stepX = −1<br />

y > 0 ⇒ stepY = 1, anders stepY = −1<br />

39


A B<br />

Figuur 5.10: Driehoekintersectie buit<strong>en</strong> de voxel. In voxel A wordt er e<strong>en</strong><br />

intersectiepunt gevond<strong>en</strong> met de grote driehoek. Dit punt bevindt zich buit<strong>en</strong><br />

voxel A. Het algoritme st<strong>op</strong>t, <strong>en</strong> bekomt bijgevolg e<strong>en</strong> fout intersectiepunt.<br />

z > 0 ⇒ stepZ = 1, anders stepZ = −1<br />

Vervolg<strong>en</strong>s zull<strong>en</strong> we de t-waard<strong>en</strong> bepal<strong>en</strong> die aangev<strong>en</strong> <strong>op</strong> welke plaats <strong>op</strong><br />

de straal we het volg<strong>en</strong>de x, y <strong>en</strong> z vlak intersecter<strong>en</strong>. Naar deze t-waard<strong>en</strong><br />

zull<strong>en</strong> we respectievelijk verwijz<strong>en</strong> als tMaxX, tMaxY <strong>en</strong> tMaxZ. Het mininum<br />

van deze drie waard<strong>en</strong> geeft dus aan hoever we ons maximaal <strong>op</strong> de straal<br />

kunn<strong>en</strong> begev<strong>en</strong>, alvor<strong>en</strong>s e<strong>en</strong> nieuwe voxel binn<strong>en</strong> te gaan.<br />

De initialisatiefase kunn<strong>en</strong> we besluit<strong>en</strong> na het bepal<strong>en</strong> van de waard<strong>en</strong><br />

tDeltaX, tDeltaY <strong>en</strong> tDeltaZ. tDeltaX geeft aan hoever we ons, in e<strong>en</strong>hed<strong>en</strong><br />

van t, moet<strong>en</strong> voortbeweg<strong>en</strong> <strong>op</strong> de straal om e<strong>en</strong> voxelbreedte te overbrugg<strong>en</strong>.<br />

Analoog geldt dit voor tDeltaY die zorgt voor e<strong>en</strong> overbrugging van de voxelhoogte,<br />

<strong>en</strong> tDeltaZ die zorgt voor e<strong>en</strong> overbrugging van de voxeldiepte.<br />

Nu de initialisatiefase volbracht is, kunn<strong>en</strong> we start<strong>en</strong> met het doorl<strong>op</strong><strong>en</strong> van<br />

het grid. Om te bepal<strong>en</strong> welk de volg<strong>en</strong>de voxel zal zijn, zull<strong>en</strong> we controler<strong>en</strong><br />

welke van de variabel<strong>en</strong> tMaxX, tMaxY <strong>en</strong> tMaxZ de kleinste waarde heeft.<br />

Stel tMaxX heeft de kleinste waarde, dan krijgt x de waarde x + stepX <strong>en</strong><br />

pass<strong>en</strong> we tMaxX aan door deze de waarde tMaxX + tDeltaX te gev<strong>en</strong>. Dit<br />

gebeurt analoog voor tMaxY <strong>en</strong> tMaxZ, indi<strong>en</strong> één van beid<strong>en</strong> de kleinste<br />

waarde bezit.<br />

Het algoritme zal blijv<strong>en</strong> naar de volg<strong>en</strong>de voxel over te gaan zolang we<br />

ons nog binn<strong>en</strong> het grid zull<strong>en</strong> bevind<strong>en</strong>, <strong>en</strong> zolang er nog ge<strong>en</strong> intersectie met<br />

e<strong>en</strong> driehoek gevond<strong>en</strong> is. Merk <strong>op</strong> dat het niet volstaat e<strong>en</strong> intersectie te<br />

vind<strong>en</strong>, maar deze intersectie moet zich wel degelijk binn<strong>en</strong> de betreff<strong>en</strong>de voxel<br />

bevind<strong>en</strong> om geldig te zijn. In figuur 5.10 wordt er e<strong>en</strong> situatie weergegev<strong>en</strong> waar<br />

het zonder deze maatregel fout zou l<strong>op</strong><strong>en</strong>. In voxel A bevindt zich namelijk e<strong>en</strong><br />

driehoek die de straal zou intersecter<strong>en</strong> buit<strong>en</strong> deze voxel, namelijk in voxel B.<br />

Indi<strong>en</strong> deze intersectie als geldig beschouwd zou word<strong>en</strong>, geeft dit duidelijk e<strong>en</strong><br />

ongew<strong>en</strong>st resultaat. We di<strong>en</strong><strong>en</strong> deze dus neger<strong>en</strong>, zodat in voxel B de juiste<br />

intersectie met de kleine driehoek gevond<strong>en</strong> wordt.<br />

Op het eerste zicht lijkt het controler<strong>en</strong> of e<strong>en</strong> intersectiepunt zich binn<strong>en</strong><br />

de voxel bevindt, zes floating point vergelijking<strong>en</strong> in te houd<strong>en</strong>, namelijk één<br />

per zijvlak. Die zes floating point vergelijking<strong>en</strong> kunn<strong>en</strong> makkelijk gereduceerd<br />

word<strong>en</strong> naar één floating point vergelijking. We bezitt<strong>en</strong> namelijk de maximale<br />

t-waarde die de straal kan hebb<strong>en</strong> <strong>op</strong>dat deze zich nog binn<strong>en</strong> de betreff<strong>en</strong>de<br />

voxel zal bevind<strong>en</strong>. Deze waarde kunn<strong>en</strong> we vergelijk<strong>en</strong> met de t-waarde van<br />

het bekom<strong>en</strong> intersectiepunt. Indi<strong>en</strong> deze waarde groter is dan de maximale<br />

40


t-waarde, dan hebb<strong>en</strong> we mogelijk te mak<strong>en</strong> met e<strong>en</strong> incorrecte intersectie, <strong>en</strong><br />

zull<strong>en</strong> we deze neger<strong>en</strong>.<br />

Aangezi<strong>en</strong> het mogelijk is dat e<strong>en</strong> driehoek zich in meerdere voxels tegelijkertijd<br />

bevindt, kan het gebeur<strong>en</strong> dat e<strong>en</strong> straal meerdere ker<strong>en</strong> e<strong>en</strong> intersectietest<br />

uitvoert met dezelfde driehoek. In het algoritme van Amanatides <strong>en</strong> Woo is<br />

er e<strong>en</strong> <strong>op</strong>lossing voorzi<strong>en</strong> zodat deze meervoudige intersectietests geëlimineerd<br />

word<strong>en</strong>. Hiervoor di<strong>en</strong>t er per driehoek e<strong>en</strong> ID bijgehoud<strong>en</strong> te word<strong>en</strong>, maar<br />

dit behoort niet tot de mogelijkhed<strong>en</strong> van Cg, aangezi<strong>en</strong> deze data read-only<br />

zijn. Daarom is de meervoudige intersectietest eliminatie niet <strong>op</strong>g<strong>en</strong>om<strong>en</strong> in de<br />

bijbehor<strong>en</strong>de implem<strong>en</strong>tatie.<br />

De implem<strong>en</strong>tatie van het beschrev<strong>en</strong> algoritme is recht-toe-recht-aan. Het<br />

<strong>en</strong>ige relevante waar rek<strong>en</strong>ing mee di<strong>en</strong>t gehoud<strong>en</strong> te word<strong>en</strong> is feit dat if-th<strong>en</strong>(else)<br />

constructies traag zijn, zoals in sectie 4.4 besprok<strong>en</strong> wordt. Amanatides<br />

<strong>en</strong> Woo gebruik<strong>en</strong> e<strong>en</strong> constructie waarin zev<strong>en</strong> conditionele <strong>op</strong>eraties, zijnde<br />

if-th<strong>en</strong>(-else) constructies, voorkom<strong>en</strong>. De herwerkte versie voor uitvoering <strong>op</strong><br />

de <strong>GPU</strong>, beschrev<strong>en</strong> in [Chr05], bevat er slechts zes. Het algoritme voorgesteld<br />

in deze thesis, bevat ge<strong>en</strong> <strong>en</strong>kele conditionele <strong>op</strong>eratie meer. In hoofdstuk 6<br />

zull<strong>en</strong> de kost<strong>en</strong> van deze drie algoritm<strong>en</strong> bepaald <strong>en</strong> vergelek<strong>en</strong> word<strong>en</strong>.<br />

Driehoek<strong>en</strong> intersecter<strong>en</strong><br />

Het bepal<strong>en</strong> of e<strong>en</strong> straal e<strong>en</strong> gegev<strong>en</strong> driehoek intersecteert, gebeurt door middel<br />

van het Möller Trumbore algoritme [MT97]. Dit algoritme vereist <strong>en</strong>kel de<br />

drie vertices die de driehoek beschrijv<strong>en</strong> <strong>en</strong> e<strong>en</strong> beschrijving van de straal. Er<br />

zijn dus ge<strong>en</strong> voorberek<strong>en</strong>de waard<strong>en</strong> nodig, zoals e<strong>en</strong> vergelijking van het vlak<br />

waarin de driehoek zich bevindt.<br />

Typische algoritm<strong>en</strong> zoek<strong>en</strong> eerst het intersectiepunt met het vlak waarin<br />

de driehoek zich bevindt, <strong>en</strong> controler<strong>en</strong> vervolg<strong>en</strong>s of dit punt zich binn<strong>en</strong> de<br />

driehoek bevindt. Indi<strong>en</strong> er ge<strong>en</strong> intersectie is met dit vlak, zal er bijgevolg ook<br />

ge<strong>en</strong> intersectie met de betreff<strong>en</strong>de driehoek zijn. Dit algoritme werkt namelijk<br />

<strong>op</strong> e<strong>en</strong> manier zodat er ge<strong>en</strong> vlakvergelijking nodig is. Het transformeert de<br />

straal door de oorsprong te verplaats<strong>en</strong>, <strong>en</strong> de richtingsvector van basis te verander<strong>en</strong>.<br />

Hierdoor wordt er e<strong>en</strong> vector (t, u, v) bekom<strong>en</strong>, waarbij t de afstand<br />

tot de intersectie is, <strong>en</strong> (u, v) de coördinat<strong>en</strong> van het intersectiepunt <strong>op</strong> driehoek<br />

zijn.<br />

Voor de implem<strong>en</strong>tatie is er voor dit algoritme ge<strong>op</strong>teerd vanwege het feit<br />

dat dit e<strong>en</strong> minimale hoeveelheid geheug<strong>en</strong> in beslag neemt, snel is, <strong>en</strong> zich<br />

zeer goed le<strong>en</strong>t tot e<strong>en</strong> conversie naar de <strong>GPU</strong>. Het algoritme is zeer recht-toerecht-aan<br />

te programmer<strong>en</strong>, als e<strong>en</strong>maal de wiskundige achtergrond gek<strong>en</strong>d is.<br />

Daarom zal in deze sectie de wiskundige afleiding gegev<strong>en</strong> word<strong>en</strong>.<br />

Beschouw e<strong>en</strong> driehoek met vertices v0, v1 <strong>en</strong> v2 <strong>en</strong> e<strong>en</strong> straal r(t) = o + td,<br />

waarbij o de oorspong is, <strong>en</strong> d de g<strong>en</strong>ormaliseerde richtingsvector. We w<strong>en</strong>s<strong>en</strong><br />

nu te wet<strong>en</strong> te kom<strong>en</strong> of de straal r <strong>en</strong> driehoek v0, v1, v2 elkaar snijd<strong>en</strong>.<br />

E<strong>en</strong> punt p <strong>op</strong> de driehoek kan door middel van baryc<strong>en</strong>trische coördinat<strong>en</strong><br />

geschrev<strong>en</strong> word<strong>en</strong> als p(u, v) = (1 − u − v)v0 + uv1 + vv2, waarbij u ≥ 0, v ≥ 0<br />

<strong>en</strong> u + v ≤ 1. Merk <strong>op</strong> dat deze (u, v) coördinaat gebruikt kan word<strong>en</strong> voor<br />

het interpoler<strong>en</strong> van normal<strong>en</strong>, kleur<strong>en</strong> <strong>en</strong> texture coördinat<strong>en</strong>. Het snijpunt,<br />

indi<strong>en</strong> aanwezig, kunn<strong>en</strong> we vind<strong>en</strong> door r(t) gelijk te stell<strong>en</strong> aan p(u, v), <strong>en</strong><br />

hiervoor de juiste t, u <strong>en</strong> v waarde voor te zoek<strong>en</strong>. Indi<strong>en</strong> deze niet bestaan,<br />

is er ge<strong>en</strong> sprake van e<strong>en</strong> intersectiepunt. De vergelijking r(t) = p(u, v) wordt<br />

41


verder uitgewerkt <strong>en</strong> herschrev<strong>en</strong> als volgt:<br />

r(t) = p(u, v)<br />

⇒ o + td = (1 − u − v)v0 + uv1 + vv2<br />

⇒ o + td = v0 − uv0 − vv0 + uv1 + vv2<br />

⇒ o − v0<br />

⇒ o − v0<br />

=<br />

=<br />

−td + uv1 − uv0 + vv2 − vv0<br />

⎡<br />

<br />

−d v1 − v0 v2 − v0 ⎣ t<br />

⎤<br />

u⎦<br />

v<br />

Laat ons uit drie hulp variabel<strong>en</strong> invoer<strong>en</strong>, om de notaties <strong>en</strong>igszins te verkort<strong>en</strong>,<br />

namelijk e1 = v1 − v0, e2 = v2 − v0 <strong>en</strong> s = o − v0. Dit levert volg<strong>en</strong>de verkorte<br />

versie van de vergelijking <strong>op</strong>:<br />

s = −d e1<br />

⎡<br />

<br />

e2 ⎣ t<br />

⎤<br />

u⎦<br />

v<br />

Door gebruik van de regel van Cramer, kunn<strong>en</strong> we deze vergelijking <strong>op</strong>loss<strong>en</strong><br />

naar (t, u, v):<br />

⎡ ⎤<br />

⎡<br />

⎤<br />

⎣ t<br />

u⎦<br />

=<br />

v<br />

1<br />

det(−d e1 e2)<br />

det(−d<br />

⎣ det(−d<br />

e1<br />

t<br />

e2)<br />

e2) ⎦<br />

det(−d e1 t)<br />

Uit de lineaire algebra wet<strong>en</strong> we dat det(a b c) = −(a × c) · b = −(c × b) · a,<br />

waarmee we volg<strong>en</strong>de vorm kunn<strong>en</strong> verkrijg<strong>en</strong>:<br />

⎡<br />

⎣ t<br />

⎤<br />

u⎦<br />

v<br />

=<br />

⎡<br />

1<br />

⎣<br />

(d × e2) · e1<br />

(t × e1)<br />

=<br />

⎤<br />

· e2<br />

(d × e2) · t ⎦<br />

(t × e1) · d<br />

⎡ ⎤<br />

q · e2 1<br />

⎣ p · t ⎦<br />

p · e1 q · d<br />

Merk <strong>op</strong> dat er hulpvariabel<strong>en</strong> p = d × e2 <strong>en</strong> q = t × e1 zijn ingevoerd met<br />

als doel aan te duid<strong>en</strong> dat in de implem<strong>en</strong>tatie deze waard<strong>en</strong> slechts e<strong>en</strong>malig<br />

di<strong>en</strong><strong>en</strong> bepaald te word<strong>en</strong>. Hiermee is het doel bereikt, we kunn<strong>en</strong> e<strong>en</strong>voudig<br />

e<strong>en</strong> formule evaluer<strong>en</strong> die ons e<strong>en</strong> waarde voor t, u <strong>en</strong> v <strong>op</strong>levert.<br />

5.2.3 Converter<strong>en</strong> <strong>GPU</strong> naar <strong>CPU</strong><br />

In deze sectie zal behandeld word<strong>en</strong> welke aanpassing<strong>en</strong> er gemaakt zijn om<br />

de Cg code te converter<strong>en</strong> in C++ code. Er zal blijk<strong>en</strong> dat er slechts weinig<br />

fundam<strong>en</strong>tele aanpassing<strong>en</strong> di<strong>en</strong><strong>en</strong> doorgevoerd te word<strong>en</strong>. Het herschrijv<strong>en</strong><br />

van het oogstral<strong>en</strong> g<strong>en</strong>erator, het schrijv<strong>en</strong> van e<strong>en</strong> Cg emulator bibliotheek <strong>en</strong><br />

<strong>en</strong>kele syntactische aanpassing<strong>en</strong> volstaan om te kunn<strong>en</strong> beschikk<strong>en</strong> over e<strong>en</strong><br />

werk<strong>en</strong>de C++ versie, vertrekk<strong>en</strong>de van e<strong>en</strong> Cg versie.<br />

42


Oogstral<strong>en</strong> g<strong>en</strong>erer<strong>en</strong><br />

Het g<strong>en</strong>erer<strong>en</strong> van de oogstral<strong>en</strong> zal niet meer door de grafische kaart kunn<strong>en</strong><br />

gebeur<strong>en</strong>, waardoor we dit zelf volledig di<strong>en</strong><strong>en</strong> te schrijv<strong>en</strong>. Dit zal gebeur<strong>en</strong><br />

aan de hand van de formule die besprok<strong>en</strong> wordt in paragraaf 2.2.1.<br />

Voor alle pixels die ingekleurd moet<strong>en</strong> word<strong>en</strong>, bepal<strong>en</strong> we gegev<strong>en</strong> de pixel<br />

coördinat<strong>en</strong> (i, j), de bijbehor<strong>en</strong>de oogstraal. Deze wordt vervolg<strong>en</strong>s meegegev<strong>en</strong><br />

aan de oorsponkelijke Cg shader, die nu herschrev<strong>en</strong> is als e<strong>en</strong> C++ functie.<br />

Meer over de syntactische aanpassing<strong>en</strong> staat verder in deze sectie beschrev<strong>en</strong>.<br />

Cg emulator<br />

Cg bevat e<strong>en</strong> gamma aan ingebouwde datatypes <strong>en</strong> functionaliteit, die in C++<br />

onbestaand zijn. In de Cg implem<strong>en</strong>tatie word<strong>en</strong> er bijgevolg verscheid<strong>en</strong>e zak<strong>en</strong><br />

gebruikt die in C++ niet zonder meer voor hand<strong>en</strong> zijn.<br />

De ontbrek<strong>en</strong>de zak<strong>en</strong>, die bijgevolg nog geschrev<strong>en</strong> di<strong>en</strong>d<strong>en</strong> te word<strong>en</strong>, zijn<br />

types zoals float3, int2 <strong>en</strong> samplerRECT, alsook <strong>op</strong>eraties zoals reflect, dot<br />

<strong>en</strong> cross.<br />

Syntactische aanpassing<strong>en</strong><br />

Het is spijtig g<strong>en</strong>oeg niet voldo<strong>en</strong>de om <strong>en</strong>kel de oogstral<strong>en</strong> g<strong>en</strong>erator <strong>en</strong> Cg<br />

emulator bibliotheek te schrijv<strong>en</strong>. Het is onvermijdelijk om toch bepaalde syntactische<br />

verandering<strong>en</strong> aan te br<strong>en</strong>g<strong>en</strong>. De aanpassing<strong>en</strong> die van toepassing<br />

zijn <strong>op</strong> de ray tracer conversie, word<strong>en</strong> hieronder toegelicht.<br />

uniform Het keyword uniform is in C++ ongek<strong>en</strong>d, maar kan gewoon overal<br />

weggelat<strong>en</strong> word<strong>en</strong>.<br />

texRECT Deze functie krijgt normaliter e<strong>en</strong> samplerRECT <strong>en</strong> e<strong>en</strong> int2 mee<br />

als argum<strong>en</strong>t<strong>en</strong>, <strong>en</strong> voert e<strong>en</strong> texture lookup uit <strong>op</strong> de gegev<strong>en</strong> positie<br />

(int2) in de texture (samplerRECT). In de C++ code is samplerRECT<br />

gedefiniëerd als e<strong>en</strong> float *. Deze heeft bijgevolg ge<strong>en</strong> notie meer van<br />

het aantal floats waarnaar verwez<strong>en</strong> wordt, zijnde 4 in het geval van<br />

RGBA, <strong>en</strong> 3 in het geval van RGB. Dit is <strong>op</strong>gelost door het doorgev<strong>en</strong><br />

van e<strong>en</strong> extra paramater, zijnde het aantal floats.<br />

: COLOR, : TEXCOORD0 Deze zog<strong>en</strong>aamde binding semantics bestaan<br />

niet in C++, maar kunn<strong>en</strong> zonder meer verwijderd word<strong>en</strong>. Meer hierover<br />

is te vind<strong>en</strong> in sectie 4.2.2.<br />

main De naam van de shader, die doorgaans main wordt g<strong>en</strong>oemd, di<strong>en</strong>t e<strong>en</strong><br />

andere naam te krijg<strong>en</strong>. Zo word<strong>en</strong> er naamconflict<strong>en</strong> vermed<strong>en</strong> tuss<strong>en</strong> de<br />

hoofdfunctie main <strong>en</strong> de naam van de geëmuleerde shader.<br />

xyz() In Cg kunn<strong>en</strong> groep<strong>en</strong> van member variabel<strong>en</strong> geselecteerd word<strong>en</strong> via<br />

e<strong>en</strong> syntax die lijkt <strong>op</strong> die van member selectie in C++. Zo levert<br />

float4(1.0, 2.0, 3.0, 4.0).xyz<br />

de waarde<br />

float3(1.0, 2.0, 3.0)<br />

43


<strong>op</strong>. In de C++ code is de xyz member voorzi<strong>en</strong> door e<strong>en</strong> member functie<br />

xyz(). In de oorspronkelijke Cg code di<strong>en</strong><strong>en</strong> dus telk<strong>en</strong>s haakjes<br />

toegevoegd te word<strong>en</strong> waar er .xyz gebruikt wordt.<br />

44


Hoofdstuk 6<br />

Resultat<strong>en</strong><br />

Dit hoofdstuk bevat e<strong>en</strong> beschrijving van de bekom<strong>en</strong> resultat<strong>en</strong> van de <strong>GPU</strong> <strong>en</strong><br />

<strong>CPU</strong> implem<strong>en</strong>tatie, met mogelijke verklaring<strong>en</strong> hiervoor. Aangezi<strong>en</strong> veel van<br />

de bekom<strong>en</strong> resultat<strong>en</strong> systeemspecifiek zijn, zull<strong>en</strong> eerst de systeemparamaters<br />

gegev<strong>en</strong> word<strong>en</strong>. E<strong>en</strong> belangrijk deel van de verklaring<strong>en</strong> heeft betrekking tot<br />

de coher<strong>en</strong>tie tuss<strong>en</strong> de geschot<strong>en</strong> stral<strong>en</strong> doorhe<strong>en</strong> de acceleratiestructuur. E<strong>en</strong><br />

onderzoek van de pad<strong>en</strong>coher<strong>en</strong>tie zal bijgevolg e<strong>en</strong> belangrijk aandeel vorm<strong>en</strong><br />

van dit hoofdstuk. Verder zal er nog e<strong>en</strong> model geconstrueerd word<strong>en</strong> voor<br />

het evaluer<strong>en</strong> van de kost van verschill<strong>en</strong>de if-structur<strong>en</strong>. Dit zal gebruikt word<strong>en</strong><br />

voor e<strong>en</strong> vergelijk<strong>en</strong>de studie tuss<strong>en</strong> algoritm<strong>en</strong> uit de literatuur, <strong>en</strong> het<br />

algoritme dat voor deze thesis geïmplem<strong>en</strong>teerd werd.<br />

6.1 Systeemspecificatie<br />

De systeemspecifieke factor<strong>en</strong>, die bepal<strong>en</strong>d kunn<strong>en</strong> zijn voor de besprok<strong>en</strong> resultat<strong>en</strong>,<br />

word<strong>en</strong> sam<strong>en</strong>gevat in tabel 6.1<br />

Grafische Hardware<br />

Grafische kaart nVidia GeForce 6800LE<br />

Geheug<strong>en</strong> 128 MB<br />

Aantal pixel pipelines 8<br />

Aantal vertex pipelines 4<br />

<strong>GPU</strong> kloksnelheid 300 Mhz<br />

Meest geavanceerde shader model 3.0<br />

Overige hardware<br />

<strong>CPU</strong> AMD Athlon XP 2400+<br />

AGP poort 4×<br />

Software<br />

Driverversie 6.14.10.7650<br />

Besturingssysteem Windows XP (Service Pack 2)<br />

Cg versie 1.3<br />

C++ Microsoft Visual Studio .NET 2003<br />

Gebruikte bibliothek<strong>en</strong> Qt, Op<strong>en</strong>GL, GLEW, lib3ds<br />

Tabel 6.1: Systeemspecificatie.<br />

45


axe bed gnome<br />

aantal driehoek<strong>en</strong> 19392 838 49552<br />

aantal vertices 77568 3352 198208<br />

aantal voxels (67, 252, 17) (37, 25, 12) (157, 37, 135)<br />

perc<strong>en</strong>tage lege voxels 92.3561 78.5766 95.6404<br />

gemiddeld aantal<br />

driehoek<strong>en</strong> per voxel 0.547037 1.26757 0.26434<br />

maximum aantal<br />

driehoek<strong>en</strong> per voxel 229 156 77<br />

Tabel 6.2: Modelinformatie.<br />

6.2 Model beschrijving<strong>en</strong><br />

De gegev<strong>en</strong>s waar<strong>op</strong> we ons in deze sectie zull<strong>en</strong> baser<strong>en</strong> zijn geg<strong>en</strong>ereerd uit<br />

drie verschill<strong>en</strong>de 3DS modell<strong>en</strong>, telk<strong>en</strong>s uit e<strong>en</strong> bepaald interessant standpunt<br />

bekek<strong>en</strong>. We zull<strong>en</strong> er naar referer<strong>en</strong> met de bestandsnaam die ze gekreg<strong>en</strong><br />

hebb<strong>en</strong>, namelijk “axe”, “bed” <strong>en</strong> “gnome”. E<strong>en</strong> scre<strong>en</strong>shot van elk, geg<strong>en</strong>ereerd<br />

<strong>op</strong> de <strong>GPU</strong>, is te vind<strong>en</strong> in figuur 6.7, 6.9 <strong>en</strong> 6.8.<br />

Om de complexitieit van e<strong>en</strong> model te modeller<strong>en</strong>, gebruik<strong>en</strong> we e<strong>en</strong> aantal<br />

parameters van de driehoek<strong>en</strong>- <strong>en</strong> gridstructuur die hierin bepal<strong>en</strong>d zijn.<br />

Concreet zal dit volg<strong>en</strong>de zak<strong>en</strong> betreff<strong>en</strong>:<br />

• aantal driehoek<strong>en</strong><br />

• aantal vertices<br />

• aantal voxels<br />

• perc<strong>en</strong>tage lege voxels<br />

• gemiddeld aantal driehoek<strong>en</strong> per voxel<br />

• maximum aantal driehoek<strong>en</strong> per voxel<br />

Voor de gebruikte modell<strong>en</strong> in deze sectie, levert de invulling van deze parameters<br />

waard<strong>en</strong> <strong>op</strong> van tabel 6.2<br />

6.3 R<strong>en</strong>dertijd<strong>en</strong><br />

De tijd nodig om e<strong>en</strong> beeld te vorm<strong>en</strong> van e<strong>en</strong> scène is afhankelijk van verscheid<strong>en</strong>e<br />

factor<strong>en</strong>. E<strong>en</strong> belangrijke factor is het feit of we gebruik mak<strong>en</strong> van<br />

de <strong>GPU</strong>, of <strong>CPU</strong>. Het model, aanzicht, reflectiediepte, regular grid <strong>op</strong>bouw <strong>en</strong><br />

de volgorde waarin de pixels ingekleurd word<strong>en</strong>, hebb<strong>en</strong> ook e<strong>en</strong> grote invloed<br />

<strong>op</strong> de r<strong>en</strong>dertijd<strong>en</strong>. De hoeveelheid dat e<strong>en</strong> bepaalde factor bijdraagt hierin,<br />

zal duidelijk duidelijk word<strong>en</strong> uit het vergelijk<strong>en</strong>de materiaal dat zal besprok<strong>en</strong><br />

word<strong>en</strong>.<br />

46


320 × 200 640 × 480 800 × 600 1024 × 768<br />

axe r0 148 975 1227 2010<br />

gnome r0 420 1929 2906 4609<br />

bed r0 217 1075 1679 2734<br />

bed r1 547 2782 4344 7115<br />

bed r2 901 4617 7218 11840<br />

bed r3 1262 6484 10125 16578<br />

Tabel 6.3: R<strong>en</strong>dertijd<strong>en</strong> <strong>op</strong> de <strong>CPU</strong>, gemet<strong>en</strong> in ms. De x van rx geeft de<br />

maximale reflectiediepte aan.<br />

320 × 200 640 × 480 800 × 600 1024 × 768<br />

axe r0 266 649 818 1133<br />

gnome r0 367 930 1267 1766<br />

bed r0 102 300 435 602<br />

bed r1 383 1086 1555 2219<br />

bed r2 718 2125 2977 4328<br />

bed r3 968 3063 4297 6141<br />

Tabel 6.4: R<strong>en</strong>dertijd<strong>en</strong> <strong>op</strong> de <strong>GPU</strong>, gemet<strong>en</strong> in ms. De x van rx geeft de<br />

maximale reflectiediepte aan.<br />

6.3.1 Verschill<strong>en</strong>de configuraties<br />

Tabell<strong>en</strong> 6.3 <strong>en</strong> 6.4 gev<strong>en</strong> per model, per resolutie <strong>en</strong> per reflectiediepte, de<br />

r<strong>en</strong>dertijd<strong>en</strong> aan <strong>op</strong> de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong>. De reflectiediepte is telk<strong>en</strong>s aangegev<strong>en</strong><br />

door rdiepte. De r<strong>en</strong>dertijd<strong>en</strong> zijn voorgesteld in millisecond<strong>en</strong> (ms).<br />

Om e<strong>en</strong> betere feeling te krijg<strong>en</strong> met deze data, is deze gevisualiseerd in e<strong>en</strong><br />

grafiek (figuur 6.2). Elk elem<strong>en</strong>t <strong>op</strong> de x-as stelt e<strong>en</strong> configuratie van e<strong>en</strong> model.<br />

In volgorde (1 tot 14) zijn deze: axe <strong>CPU</strong>, axe <strong>GPU</strong>, gnome <strong>CPU</strong>, gnome <strong>GPU</strong>,<br />

bed <strong>CPU</strong>, bed <strong>GPU</strong>, . . . , bed r3 <strong>CPU</strong>, bed r3 <strong>GPU</strong>. De onev<strong>en</strong> data elem<strong>en</strong>t<strong>en</strong><br />

zijn dus steeds <strong>CPU</strong> resultat<strong>en</strong>, <strong>en</strong> de ev<strong>en</strong> die van de <strong>GPU</strong>. Elk elem<strong>en</strong>t <strong>op</strong><br />

de x-as heeft vier corresponder<strong>en</strong>de waard<strong>en</strong>, zijnde de r<strong>en</strong>dertijd<strong>en</strong> voor de 4<br />

resoluties.<br />

Duidelijk zijn de r<strong>en</strong>dertijd<strong>en</strong> <strong>op</strong> de <strong>GPU</strong> beduid<strong>en</strong>d lager dan die <strong>op</strong> de<br />

<strong>CPU</strong>. Merk <strong>op</strong> dat zeker voor grotere resoluties, de <strong>GPU</strong> 3 tot 4 maal sneller<br />

is. In de grafiek weergegev<strong>en</strong> in figuur 6.1 zi<strong>en</strong> we dat hoe groter de resolutie is,<br />

hoe lager de gemiddelde tijd is, nodig om e<strong>en</strong> pixel in te kleur<strong>en</strong>. Op de <strong>CPU</strong><br />

doet dit f<strong>en</strong>ome<strong>en</strong> zich niet voor.<br />

Ook uit de reflectiediepte merk<strong>en</strong> we belangrijke zak<strong>en</strong> <strong>op</strong>. Hoewel deze <strong>op</strong><br />

de <strong>GPU</strong> nog steeds <strong>en</strong>kele mal<strong>en</strong> sneller uitgevoerd kunn<strong>en</strong> word<strong>en</strong>, is het wel<br />

<strong>op</strong>vall<strong>en</strong>d dat er per diepte verhoging (van r0 naar r1, r1 naar r2, . . . ) <strong>op</strong> de<br />

<strong>GPU</strong> e<strong>en</strong> groter perc<strong>en</strong>tage extra tijd nodig is, t.o.v. <strong>op</strong> de <strong>CPU</strong>. Op de <strong>CPU</strong><br />

hebb<strong>en</strong> we volg<strong>en</strong>de lijst van r<strong>en</strong>dertijd<strong>en</strong> per reflectiediepte voor de bed scène:<br />

2734, 7115, 11840, 16578. Dit wil zegg<strong>en</strong>, e<strong>en</strong> to<strong>en</strong>ame van 160%, 66% <strong>en</strong> 40%.<br />

Op de <strong>GPU</strong> zijn de tijd<strong>en</strong> voor deze scène 602, 2219, 4328, 6141. Dit levert e<strong>en</strong><br />

to<strong>en</strong>ame van 287%, 95% <strong>en</strong> 42%. In sectie 6.4 word<strong>en</strong> mogelijke verklaring<strong>en</strong><br />

voor deze f<strong>en</strong>om<strong>en</strong><strong>en</strong> besprok<strong>en</strong>.<br />

47


Figuur 6.1: R<strong>en</strong>dertijd<strong>en</strong> per pixel in ms.<br />

Figuur 6.2: R<strong>en</strong>dertijd<strong>en</strong> per frame in ms.<br />

48


Figuur 6.3: Volgorde waarin de pixels ingekleurd word<strong>en</strong>. Links: scanlijn na<br />

scanlijn, rechts: vierkant na vierkant.<br />

6.3.2 Tiled r<strong>en</strong>dering<br />

In de bijbehor<strong>en</strong>de implem<strong>en</strong>tatie kiest de <strong>GPU</strong> zelf de volgorde waarin de pixels<br />

van de ger<strong>en</strong>derde driehoek ingekleurd word<strong>en</strong>. In de praktijk is het echter<br />

wel mogelijk om deze volgorde te verander<strong>en</strong> door de betreff<strong>en</strong>de rechthoek te<br />

splits<strong>en</strong> in kleinere primitiev<strong>en</strong>, <strong>en</strong> deze in de gew<strong>en</strong>ste volgorde door te stur<strong>en</strong><br />

naar de grafische kaart. Op de <strong>CPU</strong> daar<strong>en</strong>teg<strong>en</strong> di<strong>en</strong>t de pixelvolgorde expliciet<br />

door de programmeur gekoz<strong>en</strong> te word<strong>en</strong>.<br />

Twee interessante pixelvolgordes die hier vergelek<strong>en</strong> word<strong>en</strong> <strong>op</strong> de <strong>GPU</strong> <strong>en</strong><br />

<strong>CPU</strong>, zijn voorgesteld in figuur 6.3. Bij de linkse afbeelding wordt er van links<br />

naar rechts, van bov<strong>en</strong> naar onder scanlijn per scanlijn ger<strong>en</strong>derd. Bij de rechtse<br />

afbeelding wordt het doelbeeld gesplitst in vierkant<strong>en</strong> van gelijke grootte, <strong>en</strong><br />

deze deelbeeld<strong>en</strong> word<strong>en</strong> vervolg<strong>en</strong>s van links naar rechts <strong>en</strong> van bov<strong>en</strong> naar<br />

onder ger<strong>en</strong>derd <strong>op</strong> dezelfde manier als in de rechtse afbeelding.<br />

Voor zowel <strong>CPU</strong> <strong>en</strong> <strong>GPU</strong> is deze tiled r<strong>en</strong>dering techniek geïmplem<strong>en</strong>teerd.<br />

Op de <strong>GPU</strong> levert dit, zoals verwacht, ge<strong>en</strong> snelheidswinst <strong>op</strong>. Integ<strong>en</strong>deel<br />

zelfs, de <strong>GPU</strong> implem<strong>en</strong>tatie werkt daardoor minder efficiënt. Op de <strong>CPU</strong> zijn<br />

er wel voordel<strong>en</strong> aan verbond<strong>en</strong>, zoals uit tabel 6.5 blijkt. In deze tabel word<strong>en</strong><br />

de drie gebruikte scènes ger<strong>en</strong>derd <strong>op</strong> de <strong>GPU</strong> met verschill<strong>en</strong>de groottes voor<br />

het vierkant, <strong>en</strong> <strong>op</strong> de verschill<strong>en</strong>de standaard resoluties. Telk<strong>en</strong>s wordt het<br />

perc<strong>en</strong>tage snelheidswinst aangegev<strong>en</strong> t<strong>en</strong> <strong>op</strong> zichte van de normale r<strong>en</strong>dering,<br />

scanlijn per scanlijn. Merk <strong>op</strong> dat er dikwijls e<strong>en</strong> aanzi<strong>en</strong>lijke snelheidswinst<br />

merkbaar is, maar in bepaalde gevall<strong>en</strong> is er sprake van e<strong>en</strong> klein snelheidsverlies.<br />

6.4 Mogelijke verklaring<strong>en</strong><br />

In deze sectie zull<strong>en</strong> er mogelijke verklaring<strong>en</strong> gegev<strong>en</strong> word<strong>en</strong> van de bekom<strong>en</strong><br />

meting<strong>en</strong> uit sectie 6.3.<br />

6.4.1 Configuraties<br />

De <strong>GPU</strong> implem<strong>en</strong>tatie blijkt beduid<strong>en</strong>d sneller beeld<strong>en</strong> te kunn<strong>en</strong> g<strong>en</strong>erer<strong>en</strong>.<br />

Waarom zou dit zo zijn? Het betreft t<strong>en</strong>slotte, <strong>op</strong> kleine irrelevante details<br />

49


model resolutie 4×4 8×8 16×16 32×32 48×48 64×64<br />

axe 320 × 200 -5 0 -2 -2 -2 -2<br />

640 × 480 0 0 0 0 0 0<br />

800 × 600 1 1 1 1 0 -1<br />

1024 × 768 -1 0 0 0 0 0<br />

gnome 320 × 200 22 27 28 28 28 28<br />

640 × 480 14 14 18 18 17 8<br />

800 × 600 12 14 15 15 13 11<br />

1024 × 768 9 12 12 13 12 13<br />

bed 320 × 200 1 0 5 5 16 5<br />

640 × 480 0 0 0 0 3 -3<br />

800 × 600 0 -2 2 5 9 6<br />

1024 × 768 -1 -1 -3 -2 1 0<br />

Tabel 6.5: Snelheidswinst <strong>op</strong> de <strong>CPU</strong> door het gebruik van tiled r<strong>en</strong>dering t<strong>en</strong><br />

<strong>op</strong>zichte van scanlijn r<strong>en</strong>dering. De resultat<strong>en</strong> zijn aangegev<strong>en</strong> in proc<strong>en</strong>t<strong>en</strong>.<br />

Negatieve proc<strong>en</strong>t<strong>en</strong> stell<strong>en</strong> dus e<strong>en</strong> snelheidsverlies voor.<br />

na, dezelfde code. Uit <strong>en</strong>kele case studies, <strong>en</strong> ervaring<strong>en</strong>, d<strong>en</strong>k ik dat er twee<br />

belangrijke red<strong>en</strong><strong>en</strong> voor zijn.<br />

De eerste belangrijke red<strong>en</strong> is het feit dat de code ge<strong>op</strong>timaliseerd is voor<br />

Cg, <strong>en</strong> dan pas omgezet naar C++. Deze code zou dus nog bijgewerkt kunn<strong>en</strong><br />

word<strong>en</strong> met als resultaat e<strong>en</strong> performantiewinst. We kunn<strong>en</strong> dan echter niet<br />

meer sprek<strong>en</strong> van “dezelfde” code in Cg <strong>en</strong> C++, dus de C++ is met <strong>op</strong>zet<br />

onaangepast gelat<strong>en</strong>.<br />

De tweede belangrijke red<strong>en</strong> is de coher<strong>en</strong>tie tuss<strong>en</strong> de pad<strong>en</strong> van de geschot<strong>en</strong><br />

stral<strong>en</strong>. De <strong>CPU</strong> put hier <strong>en</strong>kel voordeel uit doordat er dan vrij veel cache hits<br />

zijn. De <strong>GPU</strong> daar<strong>en</strong>teg<strong>en</strong> is e<strong>en</strong> SIMD processor, <strong>en</strong> kan dus meerdere stral<strong>en</strong><br />

tegelijkertijd trac<strong>en</strong>. Hoe meer de pad<strong>en</strong> <strong>op</strong> elkaar gelijk<strong>en</strong>, hoe meer de program<br />

flow van de verschill<strong>en</strong>de pixels <strong>op</strong> elkaar zal gelijk<strong>en</strong>. Dit zal dan leid<strong>en</strong><br />

tot e<strong>en</strong> efficiëntere uitvoer van de l<strong>op</strong><strong>en</strong>de shaders.<br />

Intuïtief spreekt het voor zich dat er voor e<strong>en</strong>zelfde model, in e<strong>en</strong>zelfde grid,<br />

bekek<strong>en</strong> vanuit hetzelfde standpunt, meer coher<strong>en</strong>tie is tuss<strong>en</strong> de pad<strong>en</strong> van de<br />

stral<strong>en</strong> indi<strong>en</strong> de beeldresolutie groter wordt. Dit leidt dan weer tot e<strong>en</strong> <strong>GPU</strong><br />

voordeel, wat daardwerkelijk te zi<strong>en</strong> is in grafiek 6.1. De coher<strong>en</strong>tie tuss<strong>en</strong> de<br />

pad<strong>en</strong> van de stral<strong>en</strong> zull<strong>en</strong> we illustrer<strong>en</strong> aan de hand van <strong>en</strong>kele voorbeeld<strong>en</strong>.<br />

E<strong>en</strong> pad stell<strong>en</strong> we voor als e<strong>en</strong> lijst van getall<strong>en</strong>, die telk<strong>en</strong>s e<strong>en</strong> doorkruiste<br />

voxel aanduid<strong>en</strong>. Aan e<strong>en</strong> voxel (x, y, z) k<strong>en</strong>n<strong>en</strong> we e<strong>en</strong> getal toe zoals beschrev<strong>en</strong><br />

in sectie 5.1.3. E<strong>en</strong> voorbeeld pad kan er als volgt uitzi<strong>en</strong>:<br />

[ 3167 3179 3178 2878 2877 2889 2589 2588 2288<br />

2300 2299 1999 1998 1698 1710 1709 1409 ]<br />

Eerst wordt dus voxel 3167 gecheckt <strong>op</strong> intersecties, vervolg<strong>en</strong>s 3179, . . . <strong>en</strong><br />

uiteindelijk voxel 1409. Laat ons nu aan elke verschill<strong>en</strong>de lijst, e<strong>en</strong> uniek getal<br />

k<strong>op</strong>pel<strong>en</strong>. Zo krijg<strong>en</strong> we bijvoorbeeld:<br />

0 : [ 3179 3191 2891 2890 2902 2901 2601 2613 2612<br />

50


2312 2311 2011 2023 2022 1722 1734 1733 1433 ]<br />

1 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2011 2023 2022 1722 1721 1733 1433 ]<br />

2 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600 2612<br />

2312 2311 2011 2023 2022 1722 1721 1733 1433 ]<br />

1 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2011 2023 2022 1722 1721 1733 1433 ]<br />

3 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2011 2023 2022 1722 1721 1733 1433 1432 ]<br />

3 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2011 2023 2022 1722 1721 1733 1433 1432 ]<br />

3 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2011 2023 2022 1722 1721 1733 1433 1432 ]<br />

4 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2323 2023 2022 1722 1721 1733 1732 1432 ]<br />

5 : [ 3479 3491 3191 3190 2890 2902 2901 2601 2600<br />

2612 2312 2311 2323 2322 2022 2021 1721 1733 1732 1432 ]<br />

...<br />

De unieke getall<strong>en</strong> die toegek<strong>en</strong>d werd<strong>en</strong> aan de pad<strong>en</strong> doorhe<strong>en</strong> gridstructuur,<br />

kunn<strong>en</strong> nu gebruikt word<strong>en</strong> om per pixel het gevolgde pad aan te duid<strong>en</strong>.<br />

Indi<strong>en</strong> meerdere pixels hetzelfde pad volgd<strong>en</strong>, kan dit e<strong>en</strong>voudig <strong>op</strong>gemerkt word<strong>en</strong><br />

aangezi<strong>en</strong> deze hetzelfde nummer bevatt<strong>en</strong>.<br />

Merk <strong>op</strong> dat twee pad<strong>en</strong> niet noodzakelijk totaal verschill<strong>en</strong>d di<strong>en</strong><strong>en</strong> te zijn,<br />

om e<strong>en</strong> totaal verschill<strong>en</strong>d padnummer te krijg<strong>en</strong>. Zo zijn pad 4 <strong>en</strong> 5 verschill<strong>en</strong>d,<br />

hoewel deze slechts één verschill<strong>en</strong>de voxel doorkruis<strong>en</strong>. Pad 4 gaat namelijk <strong>op</strong><br />

e<strong>en</strong> gegev<strong>en</strong> mom<strong>en</strong>t door voxel 1722, terwijl pad 5 door voxel 2021 gaat. De<br />

overige 19 voxeldoorkruising<strong>en</strong> zijn id<strong>en</strong>tiek.<br />

Beschouw de scène van scre<strong>en</strong>shot 6.9. In het midd<strong>en</strong> ervan snijd<strong>en</strong> we e<strong>en</strong><br />

vierkantje van 16 bij 16 pixels uit dit beeld, <strong>en</strong> hiervan bekijk<strong>en</strong> we de gevolgde<br />

pad<strong>en</strong>. We do<strong>en</strong> dit voor de vier resoluties, zijnde 320 × 200, 640 × 480, 800<br />

× 600 <strong>en</strong> 1024 × 768, weergegev<strong>en</strong> in tabel 6.6. Op elke pixelpositie wordt in<br />

plaats van de kleur, het padnummer getoond.<br />

De maximum waarde per figuur, met één verhoogd, geeft aan hoeveel verschill<strong>en</strong>de<br />

pad<strong>en</strong> er gevolgd werd<strong>en</strong> om het 16 × 16 vierkant in te kleur<strong>en</strong>. Dit is<br />

respectievelijk 233, 131, 86 <strong>en</strong> 66 voor de gebruikte scénes. Het is duidelijk dat<br />

er steeds meer pad<strong>en</strong> gelijk zijn, als de resoluties hoger word<strong>en</strong>. In de situatie<br />

van figuur 6.6(a) kunn<strong>en</strong> we bij b<strong>en</strong>adering stell<strong>en</strong> dat elk pad slechts één keer<br />

gebruikt wordt, dus er word<strong>en</strong>“ge<strong>en</strong>” pad<strong>en</strong> herbruikt. Als we dit vergelijk<strong>en</strong><br />

met 6.6(d) zi<strong>en</strong> we dat elk pad gemiddeld ongeveer vier keer gebruikt wordt,<br />

wat e<strong>en</strong> <strong>op</strong>merkelijke to<strong>en</strong>ame is.<br />

Wanneer we e<strong>en</strong> volledig beeld g<strong>en</strong>erer<strong>en</strong> van de drie gebruikte scènes, in<br />

plaats van <strong>en</strong>kel e<strong>en</strong> 16 × 16 vierkant, <strong>en</strong> telk<strong>en</strong>s het aantal verschill<strong>en</strong>de stral<strong>en</strong><br />

weergev<strong>en</strong>, verkrijg<strong>en</strong> we tabel 6.7. Merk <strong>op</strong> dat de combinatie gnome <strong>en</strong> 1024<br />

× 768 niets bevat. Dit is te wijt<strong>en</strong> aan e<strong>en</strong> geheug<strong>en</strong>tekort van het systeem<br />

waar<strong>op</strong> deze resultat<strong>en</strong> werd<strong>en</strong> bepaald.<br />

Stel dat de grafische kaart e<strong>en</strong> groep van, in dit geval 8, pixels selecteert<br />

om in te kleur<strong>en</strong>. Indi<strong>en</strong> elk van de geg<strong>en</strong>ereerde stral<strong>en</strong> hetzelfde pad volgt<br />

doorhe<strong>en</strong> de gridstructuur, wil dit zegg<strong>en</strong> dat de program flow in de 8 fragm<strong>en</strong>t<br />

51


0 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14<br />

15 16 17 2 18 19 20 21 22 23 24 25 26 27 28 29<br />

30 31 32 33 34 19 35 36 37 38 39 40 41 42 43 44<br />

45 46 32 47 48 49 50 51 51 52 53 54 55 56 57 58<br />

45 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73<br />

74 75 75 61 76 77 78 79 79 80 81 82 83 84 85 86<br />

87 88 89 90 91 92 93 94 95 96 97 98 99 100 85 101<br />

102 103 103 104 105 106 107 108 109 110 111 98 112 113 114 115<br />

(a) 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131<br />

132 133 133 134 135 136 122 137 137 138 139 140 141 142 143 144<br />

145 146 146 147 148 149 150 151 152 153 154 155 156 157 158 159<br />

160 161 161 162 163 164 165 166 166 167 168 169 170 171 172 173<br />

174 175 175 176 177 178 179 180 180 181 182 183 184 185 186 187<br />

188 189 189 190 191 192 193 194 194 195 196 197 198 199 200 201<br />

202 203 203 204 205 206 207 208 209 210 211 212 213 214 215 216<br />

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232<br />

0 1 2 3 4 5 5 6 6 7 8 9 9 10 11 12<br />

13 14 2 3 15 16 16 6 6 6 17 18 19 20 21 22<br />

13 23 24 25 15 16 16 6 6 26 27 28 29 30 31 22<br />

32 33 24 25 34 35 16 26 26 26 36 29 29 37 38 38<br />

32 33 24 25 39 40 40 41 42 43 36 29 29 37 38 38<br />

32 44 45 46 47 48 48 41 41 41 49 29 29 50 51 51<br />

52 53 54 55 47 48 48 41 41 41 56 57 58 50 51 51<br />

59 60 61 55 47 48 48 62 62 62 56 57 57 63 64 65<br />

(b) 59 60 66 67 68 69 69 62 62 62 56 57 70 71 72 72<br />

59 73 74 75 76 77 78 79 62 62 56 80 80 81 72 72<br />

82 83 74 75 76 77 77 84 85 85 86 80 80 81 72 72<br />

87 88 74 75 76 89 89 90 90 90 91 92 80 81 93 93<br />

94 88 95 96 97 89 89 90 90 90 98 99 99 100 93 101<br />

102 103 104 105 106 107 107 90 108 108 109 99 99 110 111 112<br />

113 114 104 105 115 116 117 118 118 108 119 120 121 122 123 123<br />

113 114 124 125 126 116 116 127 128 128 129 121 121 122 123 130<br />

0 1 2 3 3 4 5 5 5 5 5 6 7 7 8 9<br />

10 10 11 12 3 4 5 5 5 13 13 14 15 15 16 16<br />

10 10 11 17 17 18 19 13 13 13 20 21 15 15 16 16<br />

10 10 11 22 22 23 24 25 26 20 20 21 15 15 16 16<br />

27 27 28 22 29 30 25 25 25 25 26 21 15 15 16 31<br />

27 32 33 29 29 30 25 25 25 25 25 34 35 36 31 31<br />

32 32 33 29 29 30 25 25 25 37 38 39 40 40 41 31<br />

42 42 33 29 29 30 25 38 38 38 38 39 40 40 43 43<br />

(c) 44 44 45 46 47 48 38 38 38 38 38 39 40 40 49 49<br />

44 50 51 52 52 53 54 38 38 38 38 39 55 56 57 57<br />

50 50 51 52 52 58 59 54 54 38 60 61 56 56 57 57<br />

50 50 51 52 52 58 59 62 62 63 63 61 56 56 57 57<br />

64 50 51 52 65 66 62 62 62 62 62 67 68 56 57 69<br />

64 64 70 65 65 66 62 62 62 62 62 71 72 72 73 69<br />

74 74 70 75 75 66 62 62 62 76 76 77 72 72 78 79<br />

74 74 80 81 75 82 83 83 76 76 76 77 84 84 79 85<br />

0 0 1 1 2 2 3 4 4 4 4 5 5 6 6 7<br />

0 0 1 1 8 8 9 4 4 10 10 5 5 6 6 7<br />

0 11 12 12 8 8 13 13 14 10 10 5 5 6 6 7<br />

11 11 12 15 16 16 13 13 13 13 14 17 5 6 6 7<br />

18 18 15 15 16 16 13 13 13 13 13 19 20 21 22 23<br />

18 18 15 15 16 16 13 13 13 13 13 24 25 26 27 28<br />

18 18 15 15 16 16 13 13 13 29 29 25 25 26 26 30<br />

31 18 15 15 16 16 29 29 29 29 29 25 25 26 26 30<br />

(d) 32 31 33 34 35 35 29 29 29 29 29 25 25 26 26 30<br />

36 36 37 38 39 35 29 29 29 29 29 25 25 40 40 41<br />

36 36 37 37 42 39 43 29 29 29 29 25 25 44 44 45<br />

36 36 37 37 42 42 46 43 43 43 47 48 48 44 44 45<br />

36 36 37 37 42 42 46 49 49 50 50 51 48 44 44 45<br />

36 36 37 37 52 52 49 49 49 49 49 53 51 54 44 45<br />

55 56 57 57 52 52 49 49 49 49 49 53 53 58 59 60<br />

61 61 62 57 52 52 49 49 49 49 49 63 63 64 64 65<br />

Tabel 6.6: Pad<strong>en</strong>coher<strong>en</strong>tie. (a)-(d) gev<strong>en</strong> blokk<strong>en</strong> van 16 × 16 pixels weer,<br />

bekom<strong>en</strong> uit het midd<strong>en</strong> van e<strong>en</strong> ger<strong>en</strong>derd beeld van de scène “bed”, <strong>op</strong> vier<br />

verschill<strong>en</strong>de resoluties. Elk van de 256 getall<strong>en</strong> stelt e<strong>en</strong> unieke pad voor. De<br />

resoluties zijn: (a) 320 × 200, (b) 640 × 480, (c) 800 × 600, (d) 1024 × 768.<br />

52


esolutie axe bed gnome aantal mogelijke pad<strong>en</strong><br />

320 × 200 15502 25967 34566 64000<br />

640 × 480 87440 52084 183989 307200<br />

800 × 600 134365 58390 280858 480000<br />

1024 × 768 213440 64331 786432<br />

Tabel 6.7: Aantal verschill<strong>en</strong>de pad<strong>en</strong> voor raycasting, per scène, per resolutie.<br />

programma’s gelijk is. Dit is duidelijk het ideale geval voor de fragm<strong>en</strong>t shader,<br />

die t<strong>en</strong>slotte e<strong>en</strong> SIMD processor is.<br />

Gelukkig zijn er voor e<strong>en</strong> gelijke program flow van twee shaders, ge<strong>en</strong> twee<br />

volledig id<strong>en</strong>tieke pad<strong>en</strong> vereist. Het is niet belangrijk dat de voxels zelf gelijk<br />

zijn, maar dat het aantal driehoek<strong>en</strong> in de overe<strong>en</strong>stemm<strong>en</strong>de voxels telk<strong>en</strong>s<br />

gelijk zijn. Dit kan <strong>op</strong> analoge wijze gemodelleerd word<strong>en</strong> als bij de pad<strong>en</strong>,<br />

<strong>en</strong>kel de unieke nummers toegek<strong>en</strong>d aan de voxels, di<strong>en</strong><strong>en</strong> vervang<strong>en</strong> te word<strong>en</strong><br />

door het aantal driehoek<strong>en</strong> dat zich in de desbetreff<strong>en</strong>de voxel bevindt. Pad<strong>en</strong><br />

van dit soort zull<strong>en</strong> we n-pad<strong>en</strong> noem<strong>en</strong>. Enkele voorbeeld<strong>en</strong> van typische npad<strong>en</strong><br />

zijn:<br />

[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 ]<br />

[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 ]<br />

[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 8 ]<br />

Meestal word<strong>en</strong> er namelijk eerst e<strong>en</strong> aantal lege cell<strong>en</strong> doorkruist. Vervolg<strong>en</strong>s<br />

zijn er in het “gemiddelde” geval slechts e<strong>en</strong> beperkt aantal voxels waarin zich<br />

driehoek<strong>en</strong> bevind<strong>en</strong>, tot er zich e<strong>en</strong> intersectie voordoet. Indi<strong>en</strong> we <strong>op</strong> dezelfde<br />

manier als in tabel 6.6 nummers toek<strong>en</strong>n<strong>en</strong> aan de pad<strong>en</strong>, bekom<strong>en</strong> we als resultaat<br />

tabel 6.8. Als we deze tabell<strong>en</strong> met elkaar vergelijk<strong>en</strong>, is het <strong>op</strong>merkelijk<br />

hoe het aantal verschill<strong>en</strong>de stral<strong>en</strong> in tabel 6.8 daadwerkelijk afg<strong>en</strong>om<strong>en</strong> is t<strong>en</strong><br />

<strong>op</strong>zichte van het aantal in tabel 6.6.<br />

Indi<strong>en</strong> de volledige beeld<strong>en</strong> ger<strong>en</strong>derd word<strong>en</strong> van de drie scènes, <strong>en</strong> telk<strong>en</strong>s<br />

het aantal verschill<strong>en</strong>de n-pad<strong>en</strong> weergegev<strong>en</strong> word<strong>en</strong>, verkijg<strong>en</strong> we tabel 6.9.<br />

Let <strong>op</strong>, deze cijfers di<strong>en</strong><strong>en</strong> met voorzichtigheid geïnterpreteerd te word<strong>en</strong>. Uit<br />

de voorbeeld<strong>en</strong> blijkt duidelijk dat er voor e<strong>en</strong> groot aantal pixels, slechts zeer<br />

weinig verschill<strong>en</strong>de n-pad<strong>en</strong> gevolgd di<strong>en</strong><strong>en</strong> te word<strong>en</strong>, maar <strong>en</strong>kel dit volstaat<br />

niet. Elke pixel uit de groep van pixels, die gelijktijdig ingekleurd word<strong>en</strong> door<br />

de grafische kaart, di<strong>en</strong>t hetzelfde n-pad te volg<strong>en</strong> voor e<strong>en</strong> <strong>op</strong>timale performantie.<br />

Wet<strong>en</strong>de dat zo e<strong>en</strong> groep teg<strong>en</strong>woordig gemiddeld uit 8 tot 16 pixels<br />

bestaat, is dit niet vanzelfsprek<strong>en</strong>d het geval. Hierover meer in de sectie 6.4.2.<br />

6.4.2 Tiled r<strong>en</strong>dering<br />

De resulat<strong>en</strong> van tiled r<strong>en</strong>dering, weergegev<strong>en</strong> in sectie 6.3.2, blijk<strong>en</strong> <strong>op</strong> de <strong>CPU</strong><br />

meestal e<strong>en</strong> snelheidswinst <strong>op</strong> te lever<strong>en</strong>, wat niet het geval is <strong>op</strong> de <strong>GPU</strong>. In<br />

deze sectie wordt besprok<strong>en</strong> waaraan dit te wijt<strong>en</strong> is. De <strong>CPU</strong> <strong>en</strong> <strong>GPU</strong> word<strong>en</strong><br />

hier afzonderlijk onder de loep g<strong>en</strong>om<strong>en</strong>.<br />

53


0 1 1 2 3 3 3 4 4 5 5 5 5 6 3 4<br />

7 1 1 2 3 3 3 4 4 5 5 5 5 6 3 4<br />

7 0 0 2 3 3 3 4 4 5 8 8 8 6 3 4<br />

7 0 0 9 10 10 3 4 4 8 8 8 8 11 10 4<br />

7 0 0 9 10 10 10 3 4 8 12 12 5 6 3 4<br />

7 0 0 9 10 10 10 3 3 5 5 5 5 6 3 4<br />

7 0 0 9 10 10 3 4 4 5 5 5 5 6 3 4<br />

13 0 0 9 3 3 3 4 4 5 5 5 8 6 3 4<br />

(a) 13 0 0 2 3 3 3 4 4 8 8 8 8 6 3 4<br />

7 0 0 9 10 10 3 4 4 8 8 8 8 11 10 3<br />

7 0 0 9 10 10 10 3 4 8 12 12 12 11 10 3<br />

7 0 0 9 10 10 10 3 3 12 12 12 12 11 10 3<br />

7 0 0 9 10 10 10 3 3 12 12 12 12 11 3 4<br />

14 0 0 9 10 10 10 3 3 12 12 8 8 6 3 4<br />

14 15 15 9 10 10 10 3 4 8 8 8 8 6 3 4<br />

15 15 15 16 17 3 3 4 4 8 8 8 8 11 10 3<br />

0 0 0 0 0 0 0 1 1 2 3 4 4 4 4 5<br />

0 0 0 0 0 0 0 1 1 1 6 4 5 5 5 5<br />

0 0 0 0 0 0 0 1 1 2 3 5 5 5 5 5<br />

0 0 0 0 0 0 0 2 2 2 3 5 5 5 5 5<br />

0 0 0 0 1 1 1 2 2 2 3 5 5 5 5 5<br />

0 1 1 1 1 1 1 2 2 2 3 5 5 5 5 5<br />

1 1 1 1 1 1 1 2 2 2 3 5 5 5 5 5<br />

1 1 1 1 1 1 1 2 2 2 3 5 5 5 5 7<br />

(b) 1 1 1 1 1 1 1 2 2 2 3 5 7 7 7 7<br />

1 1 1 1 1 1 1 2 2 2 3 7 7 7 7 7<br />

1 1 1 1 1 1 1 2 2 2 3 7 7 7 7 7<br />

0 0 1 1 1 1 1 2 2 2 3 7 7 7 7 7<br />

0 0 0 0 1 1 1 2 2 2 3 7 7 7 7 7<br />

0 0 0 0 0 0 0 2 2 2 3 7 7 7 7 4<br />

0 0 0 0 0 0 0 1 1 2 3 7 4 4 4 4<br />

0 0 0 0 0 0 0 1 1 1 6 4 4 4 4 4<br />

0 0 0 0 0 0 1 1 1 1 1 2 3 3 3 3<br />

0 0 0 0 0 0 1 1 1 4 4 5 3 3 3 3<br />

0 0 0 0 0 0 4 4 4 4 4 5 3 3 3 3<br />

0 0 0 1 1 1 4 4 4 4 4 5 3 3 3 3<br />

1 1 1 1 1 1 4 4 4 4 4 5 3 3 3 3<br />

1 1 1 1 1 1 4 4 4 4 4 5 3 3 3 3<br />

1 1 1 1 1 1 4 4 4 4 4 5 3 3 3 3<br />

1 1 1 1 1 1 4 4 4 4 4 5 3 3 3 3<br />

(c) 1 1 1 1 1 1 4 4 4 4 4 5 3 3 6 6<br />

1 1 1 1 1 1 4 4 4 4 4 5 6 6 6 6<br />

1 1 1 1 1 1 4 4 4 4 4 5 6 6 6 6<br />

1 1 1 1 1 1 4 4 4 4 4 5 6 6 6 6<br />

0 1 1 1 1 1 4 4 4 4 4 5 6 6 6 6<br />

0 0 0 1 1 1 4 4 4 4 4 5 6 6 6 6<br />

0 0 0 0 0 1 4 4 4 4 4 5 6 6 6 6<br />

0 0 0 0 0 0 1 1 4 4 4 5 6 6 6 7<br />

0 0 0 0 0 0 1 2 2 2 2 3 3 4 4 4<br />

0 0 0 0 1 1 2 2 2 2 2 3 3 4 4 4<br />

0 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

(d) 1 1 1 1 1 1 2 2 2 2 2 3 3 4 4 4<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

1 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

0 1 1 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

0 0 0 1 1 1 2 2 2 2 2 3 3 5 5 5<br />

Tabel 6.8: N-pad<strong>en</strong>coher<strong>en</strong>tie. (a)-(d) gev<strong>en</strong> blokk<strong>en</strong> van 16 × 16 pixels weer,<br />

bekom<strong>en</strong> uit het midd<strong>en</strong> van e<strong>en</strong> ger<strong>en</strong>derd beeld van de scène “bed”, <strong>op</strong> vier<br />

verschill<strong>en</strong>de resoluties. Elk van de 256 getall<strong>en</strong> stelt e<strong>en</strong> uniek n-pad voor. De<br />

resoluties zijn: (a) 320 × 200, (b) 640 × 480, (c) 800 × 600, (d) 1024 × 768.<br />

54


esolutie axe bed gnome aantal mogelijke n-pad<strong>en</strong><br />

320 × 200 2496 1837 3691 64000<br />

640 × 480 9062 2384 13705 307200<br />

800 × 600 12033 2481 18451 480000<br />

1024 × 768 16158 2591 25418 786432<br />

Tabel 6.9: Aantal verschill<strong>en</strong>de n-pad<strong>en</strong> voor raycasting, per scène, per resolutie.<br />

<strong>CPU</strong><br />

Het implem<strong>en</strong>ter<strong>en</strong> van tiled r<strong>en</strong>dering kan zeer recht-toe-recht-aan gebeur<strong>en</strong> <strong>op</strong><br />

de <strong>CPU</strong>. Doch, de code wordt iets uitgebreider <strong>en</strong> levert naar alle waarschijnlijkheid<br />

e<strong>en</strong> groter aantal dynamisch uitgevoerde instructies <strong>op</strong>. Sam<strong>en</strong> met de<br />

de wijzig<strong>en</strong>de belasting van het systeem waar<strong>op</strong> de meting<strong>en</strong> bekom<strong>en</strong> zijn, kan<br />

dit in e<strong>en</strong> ongunstig geval tot e<strong>en</strong> klein snelheidsverlies leid<strong>en</strong>.<br />

Het is zo dat in de meeste gevall<strong>en</strong> vrij tot veel performantiewinst vastgesteld<br />

kan word<strong>en</strong>, hoewel de code complexer geword<strong>en</strong> is. Dit is het gevolg van e<strong>en</strong><br />

beter geheug<strong>en</strong>cache gebruik. Uit de coher<strong>en</strong>tie van de pad<strong>en</strong>, zie tabel 6.6,<br />

is het duidelijk dat pixels binn<strong>en</strong> e<strong>en</strong> beperkte omgeving in het beeld, gelijke<br />

of bijna gelijke pad<strong>en</strong> <strong>op</strong>lever<strong>en</strong> doorhe<strong>en</strong> de scène. Met andere woord<strong>en</strong>, het<br />

programma bezoekt in die omgeving dikwijls dezelfde gridcell<strong>en</strong> <strong>en</strong> driehoek<strong>en</strong>.<br />

Nog anders geformuleerd, het programma leest dikwijls hetzelfde geheug<strong>en</strong>, of<br />

geheug<strong>en</strong> dat zich regelmatig bevindt in de buurt van geheug<strong>en</strong> dat net gelez<strong>en</strong><br />

werd. Dit wil zegg<strong>en</strong> dat dit geheug<strong>en</strong> zich hoogstwaarschijnlijk in de <strong>CPU</strong>cache<br />

bevindt, waardoor er e<strong>en</strong> veel snellere geheug<strong>en</strong>toegang ter beschikking<br />

is.<br />

Bij tiled r<strong>en</strong>dering wordt het geforceerd dat de pixels ingekleurd word<strong>en</strong><br />

binn<strong>en</strong> e<strong>en</strong>zelfde omgeving, namelijk e<strong>en</strong> vierkante omgeving. Indi<strong>en</strong> er scanlijn<br />

per scanlijn ger<strong>en</strong>derd wordt, wordt er meestal sneller in ander geheug<strong>en</strong><br />

gelez<strong>en</strong>, waardoor er zich meer cache misses zull<strong>en</strong> voordo<strong>en</strong>. Scanlijn na scanlijn<br />

wordt er <strong>op</strong>nieuw min of meer gewerkt in hetzelfde geheug<strong>en</strong> als de vorige<br />

scanlijn, maar vanwege de beperkte cachegrootte wordt deze telk<strong>en</strong>s <strong>op</strong>nieuw<br />

overschrev<strong>en</strong> met andere data. Aangezi<strong>en</strong> de geheug<strong>en</strong>toegangstijd<strong>en</strong> voor de<br />

cache <strong>en</strong>orm veel lager zijn dan voor het systeemgeheug<strong>en</strong>, kan dit e<strong>en</strong> behoorlijke<br />

snelheidswinst <strong>op</strong>lever<strong>en</strong>.<br />

<strong>GPU</strong><br />

Op de <strong>GPU</strong> blijkt het gebruik van tiled r<strong>en</strong>dering <strong>en</strong>kel tot e<strong>en</strong> performantieverlies<br />

te leid<strong>en</strong>. Dit is naar alle waarschijnlijkheid te wijt<strong>en</strong> aan de extra overhead<br />

nodig om expliciet aan te gev<strong>en</strong> in welke volgorde de pixels ingekleurd di<strong>en</strong><strong>en</strong><br />

te word<strong>en</strong>.<br />

Normaal gezi<strong>en</strong> word<strong>en</strong> de oogstral<strong>en</strong> per pixel bepaald, door de grafische<br />

hardware. Nu het beeld handmatig <strong>op</strong>gesplitst wordt in vierkante tegels, di<strong>en</strong><strong>en</strong><br />

er voor de vier hoekpunt<strong>en</strong> van elke vierkant 3D texture coördinat<strong>en</strong> bepaald te<br />

word<strong>en</strong>. Aangezi<strong>en</strong> deze coördinat<strong>en</strong> per beeld kunn<strong>en</strong> verschill<strong>en</strong>, word<strong>en</strong> ze<br />

telk<strong>en</strong>s verstuurd naar de <strong>GPU</strong>. Voor e<strong>en</strong> resolutie van 1024 × 768 <strong>en</strong> tegels van<br />

32 × 32, levert dit bijna 10 Mb extra data <strong>op</strong>, bij e<strong>en</strong> nauwkeurige implem<strong>en</strong>-<br />

55


tatie. Zo kunn<strong>en</strong> de hoekpunt<strong>en</strong> van de tegels <strong>op</strong> de grafische kaart gehoud<strong>en</strong><br />

word<strong>en</strong>, door ze <strong>op</strong> te slaan in e<strong>en</strong> vertex-array.<br />

Hoewel het niet gespecifiëerd wordt in welke volgorde de pixels ingekleurd<br />

word<strong>en</strong> door de grafische kaart, is het zeker niet verwonderlijk dat deze volgorde<br />

ook voor ray tracing gunstig is. D<strong>en</strong>k hierbij aan hardwarematige texturemapping,<br />

waarbij het ook nadelig is qua cachegebruik indi<strong>en</strong> er scanlijn per scanlijn<br />

ger<strong>en</strong>derd word<strong>en</strong>. Doch, hierover wordt blijkbaar niets vrijgegev<strong>en</strong> [gpg].<br />

Wet<strong>en</strong>de dat er per beeld al snel 10 Mb extra data di<strong>en</strong>t verstuurd te word<strong>en</strong><br />

over de AGP poort, <strong>en</strong>kel voor het forcer<strong>en</strong> van tiled r<strong>en</strong>dering, is het niet verwonderlijk<br />

dat er ge<strong>en</strong> snelheidsvoordeel uit tiled r<strong>en</strong>dering geput kan word<strong>en</strong>,<br />

binn<strong>en</strong> deze implem<strong>en</strong>tatie.<br />

6.5 Vergelijking van conditionele structur<strong>en</strong><br />

Zoals in sectie 5.2.2 besprok<strong>en</strong>, gebruikt het algoritme van Amanatides <strong>en</strong> Woo<br />

[AW87] zev<strong>en</strong> conditionele <strong>op</strong>eraties. In [Chr05] wordt dit algoritme herschrev<strong>en</strong><br />

in e<strong>en</strong> andere vorm, zodat het slechts bestaat uit zes conditionele <strong>op</strong>eraties. In<br />

deze thesis wordt dit nog verder aangepast, zodat er ge<strong>en</strong> conditionele <strong>op</strong>eraties<br />

meer van toepassing zijn.<br />

Doch, het is niet zonder meer duidelijk welke van de drie structur<strong>en</strong> de<br />

meest efficiënte is. Daarom wordt er e<strong>en</strong> model <strong>op</strong>gesteld dat per if-structuur<br />

e<strong>en</strong> verwachte kost kan bepal<strong>en</strong>, voor het doorl<strong>op</strong><strong>en</strong> van e<strong>en</strong> gridstructuur, met<br />

n SIMD fragm<strong>en</strong>t shaders.<br />

In figuur 6.4 word<strong>en</strong> de drie beschouwde codefragm<strong>en</strong>t<strong>en</strong> uitgeschrev<strong>en</strong> in<br />

e<strong>en</strong> boomstructuur, in pseudocode. Elke kno<strong>op</strong> bevat code die sequ<strong>en</strong>tiëel van<br />

bov<strong>en</strong> naar onder kan uitgevoerd word<strong>en</strong>. E<strong>en</strong> if-th<strong>en</strong>-else constructie binn<strong>en</strong><br />

e<strong>en</strong> kno<strong>op</strong> wordt voorgesteld door twee uitgaande pijl<strong>en</strong>, die elk verwijz<strong>en</strong> naar<br />

e<strong>en</strong> andere kno<strong>op</strong>. Indi<strong>en</strong> de conditie naar true evalueert, wordt de linkse pijl<br />

gevolgd, anders de rechtse. Indi<strong>en</strong> er ge<strong>en</strong> else aanwezig is, is de rechtse pijl met<br />

bijbehor<strong>en</strong>de kno<strong>op</strong>, onbestaand. Voor de drie beschouwde gevall<strong>en</strong> in figuur<br />

6.4, levert dit telk<strong>en</strong>s e<strong>en</strong> boomstructuur <strong>op</strong>.<br />

Aangezi<strong>en</strong> we <strong>en</strong>kel geïnteresseerd zijn in de structuur van de bom<strong>en</strong>, <strong>en</strong><br />

het aantal uit te voer<strong>en</strong> instructies per kno<strong>op</strong>, herschijv<strong>en</strong> we deze bom<strong>en</strong> in<br />

e<strong>en</strong> meer adequate vorm. Per kno<strong>op</strong> beschouw<strong>en</strong> we <strong>en</strong>kel het aantal instructies,<br />

in plaats van de instructies zelf. Deze aantall<strong>en</strong> word<strong>en</strong> bekom<strong>en</strong> door<br />

de uitgevoerde assemblercode te analyser<strong>en</strong>, <strong>en</strong> per kno<strong>op</strong> de overe<strong>en</strong>komstige<br />

assemblerinstructies te tell<strong>en</strong>. Dit levert ons figuur 6.5 <strong>op</strong>.<br />

Voor de e<strong>en</strong>voud zull<strong>en</strong> we eerst veronderstell<strong>en</strong> dat we beschikk<strong>en</strong> over e<strong>en</strong><br />

SISD 1 processor. Vervolg<strong>en</strong>s zal deze discussie verder uitgebreid word<strong>en</strong> zodat<br />

deze van toepassing is voor e<strong>en</strong> SIMD processor.<br />

6.5.1 SISD<br />

E<strong>en</strong> uitvoering van de beschouwde codefragm<strong>en</strong>t<strong>en</strong> levert e<strong>en</strong> pad <strong>op</strong> doorhe<strong>en</strong><br />

de boomstructur<strong>en</strong> van figuur 6.5. Zo e<strong>en</strong> pad kunn<strong>en</strong> we voorstell<strong>en</strong> als e<strong>en</strong><br />

verzameling van kn<strong>op</strong><strong>en</strong>. De kn<strong>op</strong><strong>en</strong> van e<strong>en</strong> boom stell<strong>en</strong> we voor als e<strong>en</strong><br />

3-tupel (id, ifs, <strong>op</strong>s), waarbij:<br />

1 Single Instruction Single Data<br />

56


vx += sx<br />

tx += dx<br />

outOG = true<br />

if (vx == ox)<br />

if (tx < tz)<br />

(c)<br />

vz += sz<br />

tz += dz<br />

outOG = true<br />

vx += sx<br />

tx += dx<br />

(a)<br />

if (vz == oz)<br />

(b)<br />

if (vx == ox)<br />

if (tx < ty)<br />

vz += sz<br />

tz += dz<br />

outOG = true<br />

c1 = tx < ty<br />

c2 = tx < tz<br />

c3 = ty < tz<br />

if (c1 && c2)<br />

outOG = true vz += sz<br />

tz += dz<br />

c1 = tx < ty<br />

c2 = tx < tz<br />

c3 = ty < tz<br />

outOG = true<br />

if (vz == oz)<br />

if (ty < tz)<br />

if ((c1 && !c2) || (!c1 && !c3))<br />

if (vz == oz)<br />

mx = c1 && c2<br />

my = !c1 && c3<br />

mz = (c1 && !c2) || (!c1 && !c3)<br />

v += m * s<br />

t += m * d<br />

outOG = (vx == ox) || (vy == oy) || (vz == oz)<br />

vy += sy<br />

ty += dy<br />

outOG = true<br />

if (vy == oy)<br />

vy += sy<br />

ty += dy<br />

outOG = true<br />

if (!c1 && c3)<br />

if (vy == oy)<br />

Figuur 6.4: If-structur<strong>en</strong> voor de gridtraversie. (a) Amanatides <strong>en</strong> Woo<br />

[AW87], (b) Christ<strong>en</strong> [Chr05], (c) Amanatides <strong>en</strong> Woo zonder conditionele <strong>op</strong>eraties<br />

57


(a) 2<br />

(b) 6<br />

(c)<br />

1<br />

9<br />

1<br />

1<br />

4<br />

1<br />

9<br />

1<br />

1<br />

9<br />

9<br />

1 9<br />

Figuur 6.5: De kost<strong>en</strong> van de if-structur<strong>en</strong> voor de gridtraversie. In elke kno<strong>op</strong><br />

wordt er aangegev<strong>en</strong> hoeveel machinetaalinstructies er uitgevoerd word<strong>en</strong> in deze<br />

kno<strong>op</strong> (a) Amanatides <strong>en</strong> Woo [AW87], (b) Christ<strong>en</strong> [Chr05], (c) Amanatides<br />

<strong>en</strong> Woo zonder conditionele <strong>op</strong>eraties<br />

id: e<strong>en</strong> uniek label voor de kno<strong>op</strong><br />

ifs: het aantal if-structur<strong>en</strong> binn<strong>en</strong> de kno<strong>op</strong>, zijnde 0 of 1<br />

<strong>op</strong>s: het aantal instructies (<strong>op</strong>eraties) dat uitgevoerd wordt binn<strong>en</strong> de kno<strong>op</strong><br />

E<strong>en</strong> volledige boom kunn<strong>en</strong> we dan voorstell<strong>en</strong> als de verzameling van alle<br />

mogelijke pad<strong>en</strong> waarin de boom kan doorl<strong>op</strong><strong>en</strong> word<strong>en</strong>. E<strong>en</strong> boom wordt doorl<strong>op</strong><strong>en</strong><br />

door te vertrekk<strong>en</strong> vanuit de wortel, <strong>en</strong> telk<strong>en</strong>s de corresponder<strong>en</strong>de pijl<br />

te volg<strong>en</strong> afhankelijk van de conditie, tot er ge<strong>en</strong> pijl meer voorhand<strong>en</strong> is. Laat<br />

ons nu de boomstructur<strong>en</strong> (a) (b) <strong>en</strong> (c) uit figuur 6.5 respectievelijk T1, T2 <strong>en</strong><br />

T3 noem<strong>en</strong>. Deze bom<strong>en</strong> kunn<strong>en</strong> we nu schrijv<strong>en</strong> als volgt:<br />

T1 = {P1, P2, P3, P4, P5, P6, P7, P8}<br />

T2 = {Q1, Q2, Q3, Q4, Q5, Q6, Q7}<br />

T3 = {R1}<br />

waarbij de pad<strong>en</strong> Pi, Qi <strong>en</strong> Ri gelijk zijn aan:<br />

P1 = {(1, 1, 2), (2, 1, 1), (3, 1, 9)}<br />

P2 = {(1, 1, 2), (2, 1, 1), (5, 1, 4)}<br />

P3 = {(1, 1, 2), (7, 1, 1), (8, 1, 9)}<br />

P4 = {(1, 1, 2), (7, 1, 1), (10, 1, 9)}<br />

P5 = {(1, 1, 2), (2, 1, 1), (3, 1, 9), (4, 0, 1)}<br />

P6 = {(1, 1, 2), (2, 1, 1), (5, 1, 4), (6, 0, 1)}<br />

P7 = {(1, 1, 2), (7, 1, 1), (8, 1, 9), (9, 0, 1)}<br />

P8 = {(1, 1, 2), (7, 1, 1), (10, 1, 9), (11, 0, 1)}<br />

58<br />

1<br />

5<br />

1<br />

9<br />

2<br />

25


Q1 = {(1, 1, 6), (2, 1, 9)}<br />

Q2 = {(1, 1, 6), (4, 1, 5), (5, 1, 9)}<br />

Q3 = {(1, 1, 6), (4, 1, 5), (7, 1, 2), (8, 1, 9)}<br />

Q4 = {(1, 1, 6), (4, 1, 5), (7, 1, 2)}<br />

Q5 = {(1, 1, 6), (2, 1, 9), (3, 0, 1)}<br />

Q6 = {(1, 1, 6), (4, 1, 5), (5, 1, 9), (6, 0, 1)}<br />

Q7 = {(1, 1, 6), (4, 1, 5), (7, 1, 2), (8, 1, 9), (9, 0, 1)}<br />

R1 = {(1, 0, 25)}<br />

Duidelijk bevat T1 acht mogelijke pad<strong>en</strong>, T2 zev<strong>en</strong> <strong>en</strong> T3 slechts één. Hoewel<br />

de labels vrij te kiez<strong>en</strong> zijn, merk<strong>en</strong> we ev<strong>en</strong> <strong>op</strong> dat ze in deze tekst word<strong>en</strong><br />

toegek<strong>en</strong>d door de boom in preorde te doorl<strong>op</strong><strong>en</strong>, <strong>en</strong> elke teg<strong>en</strong>gekom<strong>en</strong> kno<strong>op</strong><br />

e<strong>en</strong> waarde toe te k<strong>en</strong>n<strong>en</strong> die één hoger is dan de vorige toegek<strong>en</strong>de waarde. De<br />

wortel krijgt als label e<strong>en</strong> 1 toegewez<strong>en</strong>.<br />

Om de verwachte kost voor het doorl<strong>op</strong><strong>en</strong> van e<strong>en</strong> boom T te bepal<strong>en</strong>, di<strong>en</strong>t<br />

de kans <strong>op</strong> elk afzonderlijk pad P , gek<strong>en</strong>d te zijn. Aangezi<strong>en</strong> de condities in<br />

de kn<strong>op</strong><strong>en</strong> telk<strong>en</strong>s gebaseerd zijn <strong>op</strong> de invoerdata, zijn deze kans<strong>en</strong> <strong>en</strong>kel te<br />

bepal<strong>en</strong> indi<strong>en</strong> we iets over de aard van de data wet<strong>en</strong>. In dit geval betreft het<br />

e<strong>en</strong> straal, e<strong>en</strong> gridstructuur <strong>en</strong> e<strong>en</strong> bepaalde voxel binn<strong>en</strong> het grid. Op basis<br />

daarvan di<strong>en</strong>t er beslist te word<strong>en</strong> welk de volg<strong>en</strong>de voxel is die de straal zal<br />

doorkruis<strong>en</strong>.<br />

De blader<strong>en</strong> van de bom<strong>en</strong> T1 <strong>en</strong> T2 gev<strong>en</strong> telk<strong>en</strong>s aan dat het grid verlat<strong>en</strong><br />

wordt. Voor e<strong>en</strong> willekeurige straal-voxel-combinatie, <strong>en</strong> voor e<strong>en</strong> voldo<strong>en</strong>de<br />

groot grid, is deze kans zeer klein. Daarom dat deze pad<strong>en</strong> telk<strong>en</strong>s e<strong>en</strong> kans<br />

gelijk aan 0 toegewez<strong>en</strong> krijg<strong>en</strong>. Ook pad Q4 krijgt e<strong>en</strong> kans van 0 toegewez<strong>en</strong>,<br />

maar dit is te wijt<strong>en</strong> aan het feit dat de conditie binn<strong>en</strong> deze kno<strong>op</strong> steeds<br />

naar true zal evaluer<strong>en</strong>. Het kan dus aangetoond word<strong>en</strong>, aan de hand van e<strong>en</strong><br />

waarheidstabel, dat deze conditie gerust weggelat<strong>en</strong> kan word<strong>en</strong>.<br />

Voor e<strong>en</strong> willekeurige straal-voxel-combinatie, is de kans dat de volg<strong>en</strong>de<br />

voxel zich in de x-, y- of z-richting zal begev<strong>en</strong>, gelijk. Bij b<strong>en</strong>adering kunn<strong>en</strong><br />

we dus telk<strong>en</strong>s e<strong>en</strong> kans van 1/3 toek<strong>en</strong>n<strong>en</strong> aan de kn<strong>op</strong><strong>en</strong> die de voxelpositie<br />

aanpass<strong>en</strong>, in de x-, y- of z-richting. Merk <strong>op</strong> dat er zich in T1 twee kn<strong>op</strong><strong>en</strong><br />

bevind<strong>en</strong>, namelijk (5, 1, 4) <strong>en</strong> (8, 1, 9), die de <strong>op</strong> dezelfde manier de z-richting<br />

aanpass<strong>en</strong>. Beide bijbehor<strong>en</strong>de pad<strong>en</strong>, P2 <strong>en</strong> P3, krijg<strong>en</strong> bijgevolg e<strong>en</strong> kans van<br />

1/6 toegewez<strong>en</strong>. Deze kans<strong>en</strong> houd<strong>en</strong> duidelijk ge<strong>en</strong> rek<strong>en</strong>ing met de coher<strong>en</strong>tie<br />

tuss<strong>en</strong> de verschill<strong>en</strong>de stral<strong>en</strong>.<br />

Laat ons de kans dat e<strong>en</strong> pad P gevolgd wordt, noter<strong>en</strong> als p(P ). Sam<strong>en</strong>vatt<strong>en</strong>d<br />

krijg<strong>en</strong> we dan volg<strong>en</strong>de kans<strong>en</strong>:<br />

T1<br />

T2<br />

⎧<br />

⎨<br />

⎩<br />

<br />

p(P1) = p(P4) = 1<br />

3<br />

p(P2) = p(P3) = 1<br />

6<br />

p(P5) = p(P6) = p(P7) = p(P8) = 0<br />

p(Q1) = p(Q2) = p(Q3) = 1<br />

3<br />

p(Q4) = p(Q5) = p(Q6) = p(Q7) = 0<br />

<br />

T3 p(R1) = 1<br />

59


Nu de kans<strong>en</strong> <strong>op</strong> elk pad ingevoerd zijn, rest er ons nog e<strong>en</strong> kost<strong>en</strong>functie te<br />

definiër<strong>en</strong>, alvor<strong>en</strong>s we de verwachte waard<strong>en</strong> van de boomstructur<strong>en</strong> kunn<strong>en</strong><br />

bepal<strong>en</strong>. Laat ons de kost c van e<strong>en</strong> kno<strong>op</strong> (id, ifs, <strong>op</strong>s) bepal<strong>en</strong> als volgt:<br />

c((id, ifs, <strong>op</strong>s)) = (ifs, <strong>op</strong>s)<br />

De kost<strong>en</strong>functie voor het doorl<strong>op</strong><strong>en</strong> van e<strong>en</strong> pad P kunn<strong>en</strong> we nu vastlegg<strong>en</strong><br />

aan de hand van de voorgaande definitie, als volgt:<br />

c(P ) = <br />

c(n)<br />

n∈P<br />

De verwachte kost E voor e<strong>en</strong> boom T met als kansfunctie p, kan nu bepaald<br />

word<strong>en</strong>:<br />

E(T ) = <br />

p(P )c(P )<br />

P ∈T<br />

Concreet levert dit volg<strong>en</strong>de verwachte kost<strong>en</strong> <strong>op</strong> voor T1, T2 <strong>en</strong> T3:<br />

E(T1) = <br />

p(P )c(P )<br />

P ∈T1<br />

= p(P1)c(P1) + p(P2)c(P2) + p(P3)c(P3) + p(P4)c(P4) +<br />

p(P5)c(P5) + p(P6)c(P6) + p(P7)c(P7) + p(P8)c(P8)<br />

= 1<br />

3 c(P1) + 1<br />

6 c(P2) + 1<br />

6 c(P3) + 1<br />

3 c(P4)<br />

= 1<br />

3<br />

(3, 12) + 1<br />

6<br />

= (3, 67<br />

6 )<br />

≈ (3, 11)<br />

(3, 7) + 1<br />

6<br />

E(T2) = 1 1 1<br />

(2, 15) + (3, 20) + (4, 22)<br />

3 3 3<br />

= (3, 19)<br />

E(T3) = 1(0, 25)<br />

= (0, 25)<br />

1<br />

(3, 12) + (3, 12)<br />

3<br />

Er vanuitgaande dat alle instructies, behalve conditionele, <strong>op</strong> e<strong>en</strong> SISD processor<br />

ev<strong>en</strong>veel klok cycli in beslag nem<strong>en</strong>, is het duidelijk dat T1 gemiddeld<br />

beter zal prester<strong>en</strong> dan T2. T3 is moeilijker om te vergelijk<strong>en</strong>, aangezi<strong>en</strong> deze<br />

meer instructies zal uitvoer<strong>en</strong> dan T1 <strong>en</strong> T2, maar <strong>en</strong>kel niet-conditionele. Dit<br />

is dus afhankelijk van de onderligg<strong>en</strong>de processor.<br />

6.5.2 SIMD<br />

Het SISD model, beschrev<strong>en</strong> in sectie 6.5.1, wordt in deze sectie verder uitgebreid<br />

naar e<strong>en</strong> SIMD model. Laat ons e<strong>en</strong> SIMD processor beschouw<strong>en</strong> die<br />

n dataelem<strong>en</strong>t<strong>en</strong> in parallel kan verwerk<strong>en</strong>. We sprek<strong>en</strong> in dit geval over n<br />

fragm<strong>en</strong>t shaders. Processor<strong>en</strong> van deze soort bevatt<strong>en</strong> slechts één instructiewijzer,<br />

wat wil zegg<strong>en</strong> dat de program flow van de n shaders id<strong>en</strong>tiek di<strong>en</strong>t te<br />

60


zijn. Dynamic branching <strong>op</strong> basis van de invoerdata behoort dus niet tot de<br />

mogelijkhed<strong>en</strong>.<br />

Toch is het in Cg ge<strong>en</strong> probleem om dynamic branching, <strong>op</strong> basis van de<br />

invoerdata, te voorzi<strong>en</strong>. Dit is het gevolg van e<strong>en</strong> interessante eig<strong>en</strong>schap van<br />

de <strong>GPU</strong>. Het is namelijk mogelijk om instructies uit te lat<strong>en</strong> voer<strong>en</strong>, zonder<br />

dat de resultat<strong>en</strong> ervan perman<strong>en</strong>t gemaakt word<strong>en</strong>. Het al dan niet perman<strong>en</strong>t<br />

mak<strong>en</strong> van de resulat<strong>en</strong> van e<strong>en</strong> instructie, wordt beslist aan hand van e<strong>en</strong><br />

meegegev<strong>en</strong> conditie.<br />

Hoe kan deze eig<strong>en</strong>schap nu gebruikt word<strong>en</strong> voor het voorzi<strong>en</strong> van dynamic<br />

branching? Indi<strong>en</strong> de instructiewijzer beland is bij e<strong>en</strong> conditionele <strong>op</strong>eratie,<br />

wordt er voor elk van de n shaders bepaald welk subpad deze di<strong>en</strong>t uit te voer<strong>en</strong>.<br />

Met andere woord<strong>en</strong>, <strong>op</strong> basis van de conditie di<strong>en</strong>t er beslist te word<strong>en</strong><br />

of de linkse of de rechtse pijl gevolgd zal word<strong>en</strong>. Indi<strong>en</strong> alle n shaders hetzelfde<br />

subpad kiez<strong>en</strong>, wordt <strong>en</strong>kel dit pad verder doorl<strong>op</strong><strong>en</strong>. Indi<strong>en</strong> bepaalde<br />

shaders het linkse, <strong>en</strong> andere het rechtse subpad kiez<strong>en</strong>, zull<strong>en</strong> beide subpad<strong>en</strong><br />

achtere<strong>en</strong>volg<strong>en</strong>s doorl<strong>op</strong><strong>en</strong> word<strong>en</strong>. Elke afzonderlijke shader maakt dan <strong>en</strong>kel<br />

de resultat<strong>en</strong> die van toepassing zijn, perman<strong>en</strong>t. Op die manier wordt schijnbaar<br />

<strong>en</strong>kel het daadwerkelijk gevolgde pad uitgevoerd, hoewel het best mogelijk<br />

is dat er meerdere pad<strong>en</strong> word<strong>en</strong> doorl<strong>op</strong><strong>en</strong>, waarvan de resultat<strong>en</strong> dan<br />

g<strong>en</strong>egeerd word<strong>en</strong>.<br />

Wanneer er kn<strong>op</strong><strong>en</strong> aanwezig zijn die zich in meerdere pad<strong>en</strong> bevind<strong>en</strong>, di<strong>en</strong><strong>en</strong><br />

die door de SIMD processor maar één keer uitgevoerd te word<strong>en</strong>. Dit kunn<strong>en</strong><br />

we concluder<strong>en</strong> uit de werking van dynamic branching, <strong>en</strong> het feit dat we te<br />

mak<strong>en</strong> hebb<strong>en</strong> met e<strong>en</strong> boomstructuur. In e<strong>en</strong> boomstructuur kan er namelijk<br />

telk<strong>en</strong>s maar <strong>op</strong> één <strong>en</strong>kele wijze in e<strong>en</strong> bepaalde kno<strong>op</strong> terecht gekom<strong>en</strong> word<strong>en</strong>.<br />

Dit leidt ons tot de volg<strong>en</strong>de kost<strong>en</strong>functie c, die de kost weergeeft voor<br />

het doorl<strong>op</strong><strong>en</strong> van n al dan niet verschill<strong>en</strong>de pad<strong>en</strong>:<br />

c(P1, . . . , Pn) = c(P1 ∪ · · · ∪ Pn)<br />

De kans <strong>op</strong> het volg<strong>en</strong> van n gegev<strong>en</strong> pad<strong>en</strong>, g<strong>en</strong>oteerd als p(P1, . . . , Pn), is<br />

gelijk aan het product van de kans<strong>en</strong> <strong>op</strong> elk afzonderlijk pad:<br />

p(P1, . . . , Pn) = p(P1) . . . p(Pn)<br />

Nu zijn we in staat om de verwachte kost E te bepal<strong>en</strong>, voor e<strong>en</strong> boomstructuur<br />

T , die doorl<strong>op</strong><strong>en</strong> wordt door n shaders. Volg<strong>en</strong>de formule geeft dit<br />

weer:<br />

E(T, n) =<br />

<br />

p(P1, . . . , Pn)c(P1, . . . , Pn)<br />

P1,...,Pn∈T<br />

Concreet levert dit voor deze boomstructur<strong>en</strong> <strong>en</strong> deze <strong>GPU</strong>, volg<strong>en</strong>de waard<strong>en</strong><br />

<strong>op</strong>:<br />

E(T1, 8) = (6, 45; 33, 72)<br />

E(T2, 8) = (5, 84; 39, 75)<br />

E(T3, 8) = (0; 25)<br />

Merk <strong>op</strong> dat n = 8 aangezi<strong>en</strong> de gebruikte grafische kaart 8 parallelle pixel<br />

pipelines bevat. Voor meer systeemeig<strong>en</strong>schapp<strong>en</strong>, zie sectie 6.1.<br />

61


(a) 2<br />

(b) 54 (c) 25<br />

24<br />

28<br />

Figuur 6.6: De kost<strong>en</strong> van de ge<strong>op</strong>timaliseerde if-structur<strong>en</strong> voor de gridtraversie.<br />

In elke kno<strong>op</strong> wordt er aangegev<strong>en</strong> hoeveel machinetaalinstructies er uitgevoerd<br />

word<strong>en</strong> in deze kno<strong>op</strong> (a) Amanatides <strong>en</strong> Woo [AW87], (b) Christ<strong>en</strong><br />

[Chr05], (c) Amanatides <strong>en</strong> Woo zonder conditionele <strong>op</strong>eraties<br />

Duidelijk is de laatste methode de meest efficiënte. Voor T1 <strong>en</strong> T2 is het<br />

<strong>op</strong>nieuw niet zonder meer duidelijk, aangezi<strong>en</strong> de kost afhankelijk is van de<br />

onderlinge kost tuss<strong>en</strong> conditionele <strong>en</strong> niet-conditionele <strong>op</strong>eraties.<br />

Het is echter wel belangrijk om <strong>op</strong> te merk<strong>en</strong> dat Cg, indi<strong>en</strong> niet nader<br />

gespecifiëerd, veel van deze if-structur<strong>en</strong> weg-<strong>op</strong>timaliseert. Om het aantal instructies<br />

in elke kno<strong>op</strong> te bepal<strong>en</strong>, werd in dit geval tijd<strong>en</strong>s het compiler<strong>en</strong><br />

expliciet geforceerd om de if-structur<strong>en</strong> te behoud<strong>en</strong>. Conditionele sprong<strong>en</strong> <strong>op</strong><br />

de <strong>GPU</strong> zijn namelijk duur, waardoor het soms efficiënter is om telk<strong>en</strong>s elk pad<br />

te doorl<strong>op</strong><strong>en</strong>, <strong>en</strong> <strong>en</strong>kel te werk<strong>en</strong> met het conditioneel perman<strong>en</strong>t mak<strong>en</strong> van<br />

bepaalde instructies. De kost<strong>en</strong> van de ge<strong>op</strong>timaliseerde boomstructur<strong>en</strong> zijn<br />

weergegev<strong>en</strong> in figuur 6.6. Laat ons deze bom<strong>en</strong> respectievelijk T ′ 1, T ′ 2 <strong>en</strong> T ′ 3<br />

noem<strong>en</strong>. De verwachte kost<strong>en</strong> hiervoor zijn:<br />

E(T ′ 1, 8) = (1; 56, 80)<br />

E(T ′ 2, 8) = (0; 54)<br />

E(T ′ 3, 8) = (0; 25)<br />

Vanaf dit punt is het duidelijk dat T1 <strong>op</strong> de <strong>GPU</strong> minder effiï<strong>en</strong>t is dan T2, <strong>en</strong><br />

dat T2 dan weer minder efficiënt is dan T3. Dit wordt ook empirisch bevestigd<br />

door e<strong>en</strong> implem<strong>en</strong>tatie van deze drie verschill<strong>en</strong>de structur<strong>en</strong>. Gemiddeld vergt<br />

T1 ongeveer 13% extra tijd om e<strong>en</strong> beeld te g<strong>en</strong>erer<strong>en</strong>, t<strong>en</strong> <strong>op</strong>zicht van T3. T2<br />

vergt gemiddeld slechts 5% extra rek<strong>en</strong>tijd. De cijfers waar<strong>op</strong> deze resultat<strong>en</strong><br />

gebaseerd zijn, word<strong>en</strong> weergegev<strong>en</strong> in tabel 6.10.<br />

In deze paragraaf is er e<strong>en</strong> duidelijke indicatie gegev<strong>en</strong> dat er e<strong>en</strong> aanzi<strong>en</strong>lijke<br />

snelheidswinst kan geboekt word<strong>en</strong>, door het herschrijv<strong>en</strong> van het Amanatides<br />

<strong>en</strong> Woo algoritme, zodat het ge<strong>en</strong> gebruik meer maakt van conditionele <strong>op</strong>eraties.<br />

Het model dat hier beschrev<strong>en</strong> wordt, kan makkelijk veralgeme<strong>en</strong>d <strong>en</strong><br />

toegepast word<strong>en</strong> <strong>op</strong> andere if-structur<strong>en</strong>.<br />

62


Boom Scène axe gnome bed<br />

T1 320 × 200 305 410 133<br />

640 × 480 734 1096 367<br />

800 × 600 1005 1516 516<br />

1024 × 768 1305 1985 700<br />

T2 320 × 200 305 399 107<br />

640 × 480 718 1020 336<br />

800 × 600 968 1399 484<br />

1024 × 768 1211 1816 637<br />

T3 320 × 200 283 386 114<br />

640 × 480 672 953 326<br />

800 × 600 880 1312 450<br />

1024 × 768 1156 1703 605<br />

Tabel 6.10: R<strong>en</strong>dertijd<strong>en</strong> gebruikmak<strong>en</strong>de van de boomstructur<strong>en</strong> T1, T2 <strong>en</strong><br />

T3, gemet<strong>en</strong> in ms.<br />

6.6 Scre<strong>en</strong>shots<br />

In deze sectie word<strong>en</strong> <strong>en</strong>kele scre<strong>en</strong>shots getoond van verscheid<strong>en</strong>e scènes. Deze<br />

beeld<strong>en</strong> zijn geg<strong>en</strong>ereerd door de voorzi<strong>en</strong>e <strong>GPU</strong>-implem<strong>en</strong>tatie. Telk<strong>en</strong>s wordt<br />

de r<strong>en</strong>dertijd, de beeldresolutie, <strong>en</strong> de hoeveelheid driehoek<strong>en</strong> waaruit de betreff<strong>en</strong>de<br />

scène bestaat, vermeld.<br />

63


Figuur 6.7: Axe (800 × 600). 19392 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 818 ms.<br />

Figuur 6.8: Gnome (800 × 600). 49552 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 1267 ms.<br />

64


Figuur 6.9: Bed (800 × 600). 838 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 435 ms.<br />

Figuur 6.10: Bed (1024 × 768). 838 driehoek<strong>en</strong>. Reflectiediepte: 2. R<strong>en</strong>dertijd:<br />

4328 ms.<br />

65


Figuur 6.11: Truck (1024 × 768). 61169 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 1968 ms.<br />

Figuur 6.12: Tafel (1024 × 768). 53046 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 2782 ms.<br />

66


Figuur 6.13: Kerk (1024 × 768). 80479 driehoek<strong>en</strong>. R<strong>en</strong>dertijd: 4812 ms.<br />

Figuur 6.14: Bugatti met time-outs (1024 × 768). 201036 driehoek<strong>en</strong>. R<strong>en</strong>dertijd:<br />

4385 ms.<br />

67


Hoofdstuk 7<br />

Toekomstig werk<br />

Zoals is aangehaald in sectie 4.4, is het aantal instructies, die uitgevoerd kunn<strong>en</strong><br />

word<strong>en</strong> binn<strong>en</strong> e<strong>en</strong> fragm<strong>en</strong>t shader, beperkt. Indi<strong>en</strong> dit aantal overschred<strong>en</strong><br />

wordt, doet er zich e<strong>en</strong> time-out voor, <strong>en</strong> is de kleurwaarde van de betreff<strong>en</strong>de<br />

pixel ongeldig. Binn<strong>en</strong> deze implem<strong>en</strong>tatie wordt er niet gegarandeerd of er<br />

zich al dan niet time-outs zull<strong>en</strong> voordo<strong>en</strong>. Dit zou wel kunn<strong>en</strong> gebeur<strong>en</strong> door<br />

beperking<strong>en</strong> <strong>op</strong> de scène te legg<strong>en</strong>, zoals e<strong>en</strong> maximale gridgrootte, <strong>en</strong> e<strong>en</strong> maximaal<br />

aantal driehoek<strong>en</strong> binn<strong>en</strong> e<strong>en</strong> voxel. Door de assemblercode van de shader<br />

te analyser<strong>en</strong>, kan er bijgevolg aangetoond word<strong>en</strong> hoeveel instructies er in het<br />

extreemste geval nodig zijn. De beperking<strong>en</strong> <strong>op</strong> de scène <strong>en</strong> / of de shadercode,<br />

kunn<strong>en</strong> dan aangepast word<strong>en</strong> tot er voldaan wordt aan het voor<strong>op</strong>gestelde maximale<br />

aantal instructies. E<strong>en</strong> geautomatiseerde manier om onder e<strong>en</strong> bepaald<br />

maximaal aantal instructies te blijv<strong>en</strong>, is dus gew<strong>en</strong>st.<br />

In de voorzi<strong>en</strong>e <strong>GPU</strong> implem<strong>en</strong>tatie is de <strong>CPU</strong> onb<strong>en</strong>ut tijd<strong>en</strong>s het r<strong>en</strong>der<strong>en</strong><br />

van e<strong>en</strong> beeld. Dit <strong>op</strong><strong>en</strong>t perspectiev<strong>en</strong>, waar er sprake is van e<strong>en</strong> sam<strong>en</strong>werking<br />

tuss<strong>en</strong> de <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong>. Op e<strong>en</strong> naïeve manier zou dit kunn<strong>en</strong> gebeur<strong>en</strong> door e<strong>en</strong><br />

deel van de pixels aan de <strong>CPU</strong> toe te vertrouw<strong>en</strong>, <strong>en</strong> het andere deel aan de <strong>GPU</strong>.<br />

E<strong>en</strong> taakverdeler kan dan bepal<strong>en</strong> welke pixels aan welke hardware toegewez<strong>en</strong><br />

word<strong>en</strong>. Dit zou dan <strong>op</strong> basis van informatie van voorgaande beeld<strong>en</strong> kunn<strong>en</strong><br />

word<strong>en</strong> beslist. Techniek<strong>en</strong> die gek<strong>en</strong>d zijn uit gedistribuëerde r<strong>en</strong>dering, zoals<br />

beschrev<strong>en</strong> in [WSB01], kunn<strong>en</strong> hierbij zeker e<strong>en</strong> bijdrage lever<strong>en</strong>.<br />

Als acceleratiestructuur zou er e<strong>en</strong> kd-tree gebruikt kunn<strong>en</strong> word<strong>en</strong>, in plaats<br />

van e<strong>en</strong> regular grid. Ondertuss<strong>en</strong> is er e<strong>en</strong> paper versch<strong>en</strong><strong>en</strong> waarin e<strong>en</strong> vergelijk<strong>en</strong>de<br />

studie gemaakt is tuss<strong>en</strong> ge<strong>en</strong> acceleratiestructuur, e<strong>en</strong> regular grid, <strong>en</strong><br />

e<strong>en</strong> kd-tree. Ook <strong>op</strong> de <strong>GPU</strong> blijkt de kd-tree de meest effiënt te doorl<strong>op</strong><strong>en</strong><br />

spatiale subdivisie te zijn. Voor meer details, zie [FS05].<br />

68


Hoofdstuk 8<br />

Conclusie<br />

In deze thesis zijn we vertrokk<strong>en</strong> van e<strong>en</strong> algem<strong>en</strong>e beschrijving van globale<br />

illuminatie, aan de hand van de r<strong>en</strong>dering vergelijking. Vanuit snelheidsoverweging<strong>en</strong><br />

wordt dit algem<strong>en</strong>e model vere<strong>en</strong>voudigd tot ray tracing, dat niet<br />

voldoet aan de r<strong>en</strong>dering vergelijking. Doch, de fundam<strong>en</strong>tele concept<strong>en</strong>, zijnde<br />

stral<strong>en</strong> schiet<strong>en</strong> doorhe<strong>en</strong> e<strong>en</strong> scène, blijv<strong>en</strong> bestaan binn<strong>en</strong> ray tracing.<br />

E<strong>en</strong> implem<strong>en</strong>tatie van ray tracing <strong>op</strong> <strong>GPU</strong> <strong>en</strong> <strong>CPU</strong> zijn voorzi<strong>en</strong>, respectievelijk<br />

geschrev<strong>en</strong> in Cg <strong>en</strong> C++. De originele versie is geschrev<strong>en</strong> <strong>en</strong> ge<strong>op</strong>timaliseerd<br />

voor Cg, <strong>en</strong> vervolg<strong>en</strong>s geconverteerd naar C++. De <strong>GPU</strong> versie<br />

is beduid<strong>en</strong>d sneller, zelfs drie tot vier maal voor scènes ger<strong>en</strong>derd <strong>op</strong> hoge<br />

resoluties. Hoe hoger de maximale toegelat<strong>en</strong> reflectiediepte was, hoe minder<br />

voordeel de <strong>GPU</strong> vertoonde. Beide f<strong>en</strong>om<strong>en</strong><strong>en</strong> word<strong>en</strong> verklaard aan de hand<br />

van de coher<strong>en</strong>tie tuss<strong>en</strong> de pad<strong>en</strong> die de stral<strong>en</strong> volg<strong>en</strong> doorhe<strong>en</strong> de gridstructuur.<br />

Hieruit blijkt duidelijk dat de <strong>GPU</strong> zich goed le<strong>en</strong>t voor ray tracing.<br />

Het schrijv<strong>en</strong> van de ray tracer implem<strong>en</strong>tatie <strong>op</strong> <strong>GPU</strong> is e<strong>en</strong> delicate zaak.<br />

Er di<strong>en</strong>t uiterst voorzichtig geprogrammeerd te word<strong>en</strong>, bij gebrek aan tools<br />

zoals e<strong>en</strong> debugger <strong>en</strong> profiler. Het gebruik van dynamic branching is wel mogelijk,<br />

maar ondermijnt het voordeel van het parallellisme, aangezi<strong>en</strong> er <strong>op</strong> e<strong>en</strong><br />

SIMD processor gewerkt wordt. Ook de mogelijkhed<strong>en</strong> <strong>op</strong> zich, zijn vrij beperkt.<br />

Alle iets of wat uitgebreide datastructur<strong>en</strong> di<strong>en</strong><strong>en</strong> geconstrueerd te word<strong>en</strong> uit<br />

één of meerdere textures. Recursieve functies <strong>en</strong> pointers behor<strong>en</strong> ook niet tot<br />

de mogelijkhed<strong>en</strong>. Het beperkt aantal instructies die uitgevoerd kunn<strong>en</strong> word<strong>en</strong><br />

binn<strong>en</strong> e<strong>en</strong> shader, zorgt ook voor e<strong>en</strong> hele last. Tijd<strong>en</strong>s het programmer<strong>en</strong><br />

zou er dus rek<strong>en</strong>ing gehoud<strong>en</strong> moet<strong>en</strong> word<strong>en</strong> met het aantal uitgevoerde instructies<br />

<strong>op</strong> elk mom<strong>en</strong>t, om <strong>op</strong> het juiste tijdstip de shader zichzelf te lat<strong>en</strong><br />

beëindig<strong>en</strong>. Dit is echter e<strong>en</strong> zeer omslachtige manier van werk<strong>en</strong>. De <strong>GPU</strong><br />

heeft duidelijk veel pot<strong>en</strong>tiëel, maar het is mom<strong>en</strong>teel nog niet evid<strong>en</strong>t om dit<br />

t<strong>en</strong>volle te b<strong>en</strong>utt<strong>en</strong>.<br />

Het <strong>GPU</strong> programmer<strong>en</strong> zal naar alle waarschijnlijkheid zodanig evoluer<strong>en</strong>,<br />

dat de besprok<strong>en</strong> moeilijkhed<strong>en</strong> verdwijn<strong>en</strong> t<strong>en</strong> gevolge van betere hardware <strong>en</strong><br />

de aanwezigheid handige van tools. Steeds meer system<strong>en</strong> zull<strong>en</strong> in de toekomst<br />

e<strong>en</strong> krachtige grafische kaart bezitt<strong>en</strong>, zodat de <strong>GPU</strong> zal uitgroei<strong>en</strong> tot e<strong>en</strong><br />

parallelle c<strong>op</strong>rocessor, die <strong>op</strong> haast elk systeem aanwezig zal zijn.<br />

69


Bijlage A<br />

Vertex-driehoek coher<strong>en</strong>tie<br />

Tabel A.1: Vertex-driehoek coher<strong>en</strong>tie, waarbij nv het aantal vertices<br />

is, nf het aantal driehoek<strong>en</strong>, mi het vereiste geheug<strong>en</strong> met indexering,<br />

m het vereiste geheug<strong>en</strong> zonder indexering, a het gemiddeld<br />

aantal keer dat e<strong>en</strong> vertex gebruikt wordt, f(a) de verhouding<br />

m/mi.<br />

nv nf mi m a f(a)<br />

56 48 104 144 2,571428571 1,384615385<br />

160 152 312 456 2,85 1,461538462<br />

270 354 624 1062 3,933333333 1,701923077<br />

291 514 805 1542 5,298969072 1,91552795<br />

304 564 868 1692 5,565789474 1,949308756<br />

347 136 483 408 1,175792507 0,844720497<br />

412 580 992 1740 4,223300971 1,754032258<br />

432 804 1236 2412 5,583333333 1,951456311<br />

438 602 1040 1806 4,123287671 1,736538462<br />

488 806 1294 2418 4,954918033 1,86862442<br />

491 644 1135 1932 3,934826884 1,702202643<br />

492 204 696 612 1,243902439 0,879310345<br />

541 846 1387 2538 4,691312384 1,829848594<br />

546 974 1520 2922 5,351648352 1,922368421<br />

560 1048 1608 3144 5,614285714 1,955223881<br />

594 1160 1754 3480 5,858585859 1,984036488<br />

595 592 1187 1776 2,98487395 1,49620893<br />

688 1160 1848 3480 5,058139535 1,883116883<br />

706 1408 2114 4224 5,983002833 1,998107852<br />

716 1138 1854 3414 4,768156425 1,841423948<br />

772 756 1528 2268 2,937823834 1,484293194<br />

835 1376 2211 4128 4,943712575 1,867028494<br />

850 1668 2518 5004 5,887058824 1,987291501<br />

881 1690 2571 5070 5,754824064 1,971995333<br />

888 1772 2660 5316 5,986486486 1,998496241<br />

904 1724 2628 5172 5,721238938 1,96803653<br />

950 864 1814 2592 2,728421053 1,428886439<br />

976 968 1944 2904 2,975409836 1,49382716<br />

1080 1012 2092 3036 2,811111111 1,45124283<br />

1184 1372 2556 4116 3,476351351 1,610328638<br />

1200 1979 3179 5937 4,9475 1,867568418<br />

1220 2406 3626 7218 5,916393443 1,990623276<br />

1243 1070 2313 3210 2,582461786 1,387808042<br />

1254 1208 2462 3624 2,889952153 1,471974005<br />

1413 1654 3067 4962 3,511677282 1,617867623<br />

1464 1366 2830 4098 2,799180328 1,448056537<br />

1540 2247 3787 6741 4,377272727 1,780036969<br />

1598 3136 4734 9408 5,887359199 1,987325729<br />

1599 1535 3134 4605 2,879924953 1,46936822<br />

1606 3150 4756 9450 5,884184309 1,986963835<br />

1614 3216 4830 9648 5,977695167 1,997515528<br />

1681 2254 3935 6762 4,022605592 1,718424396<br />

70


1786 3564 5350 10692 5,98656215 1,998504673<br />

1941 2638 4579 7914 4,077279753 1,728324962<br />

2080 1650 3730 4950 2,379807692 1,327077748<br />

2121 1194 3315 3582 1,688826025 1,080542986<br />

2185 2776 4961 8328 3,811441648 1,678693812<br />

2194 4348 6542 13044 5,945305378 1,993885662<br />

2220 4428 6648 13284 5,983783784 1,998194946<br />

2406 4800 7206 14400 5,985037406 1,998334721<br />

2416 4776 7192 14328 5,930463576 1,992213571<br />

2646 5148 7794 15444 5,836734694 1,981524249<br />

2757 4725 7482 14175 5,141458107 1,894546913<br />

3093 5908 9001 17724 5,730358875 1,969114543<br />

3288 2600 5888 7800 2,372262774 1,324728261<br />

3300 6580 9880 19740 5,981818182 1,997975709<br />

3526 7032 10558 21096 5,982983551 1,998105702<br />

3664 9307 12971 27921 7,620360262 2,15257112<br />

3768 7461 11229 22383 5,940286624 1,993320866<br />

3900 5924 9824 17772 4,556923077 1,809039088<br />

3974 7392 11366 22176 5,580271766 1,951082175<br />

4536 8478 13014 25434 5,607142857 1,954356846<br />

4572 7112 11684 21336 4,666666667 1,826086957<br />

4860 8146 13006 24438 5,028395062 1,878978933<br />

5137 6741 11878 20223 3,936733502 1,702559353<br />

5254 10234 15488 30702 5,843547773 1,982308884<br />

5534 9588 15122 28764 5,197687026 1,902129348<br />

5535 9708 15243 29124 5,261788618 1,91064751<br />

5984 11165 17149 33495 5,597426471 1,953175112<br />

6306 10474 16780 31422 4,982873454 1,872586412<br />

6646 7210 13856 21630 3,254589227 1,561056582<br />

6732 7199 13931 21597 3,208110517 1,55028354<br />

6969 7419 14388 22257 3,193715024 1,546914095<br />

6978 13720 20698 41160 5,898538263 1,988597932<br />

7259 12831 20090 38493 5,302796528 1,916027875<br />

7337 7646 14983 22938 3,126345918 1,53093506<br />

7337 8964 16301 26892 3,66525828 1,649714741<br />

7424 14132 21556 42396 5,710668103 1,96678419<br />

8071 16031 24102 48093 5,958741172 1,995394573<br />

8412 16707 25119 50121 5,958273894 1,995342171<br />

8567 12822 21389 38466 4,490019844 1,798401047<br />

8606 11366 19972 34098 3,962119452 1,707290206<br />

9130 18209 27339 54627 5,983242059 1,998134533<br />

9374 18514 27888 55542 5,925112012 1,991609294<br />

9424 10960 20384 32880 3,488964346 1,613029827<br />

10086 16802 26888 50406 4,997620464 1,874665278<br />

10429 14470 24899 43410 4,162431681 1,743443512<br />

11220 12840 24060 38520 3,43315508 1,600997506<br />

11541 17541 29082 52623 4,559656875 1,809469775<br />

11698 14628 26326 43884 3,751410498 1,666945225<br />

14554 28792 43346 86376 5,934863268 1,992709823<br />

17132 16152 33284 48456 2,828391314 1,455834635<br />

18096 11098 29194 33294 1,839854111 1,140439816<br />

18418 17436 35854 52308 2,840047779 1,458916718<br />

20496 33264 53760 99792 4,868852459 1,85625<br />

22801 45000 67801 135000 5,920792948 1,991121075<br />

24056 23892 47948 71676 2,979547722 1,494869442<br />

26337 51544 77881 154632 5,871283745 1,985490685<br />

39240 67891 107131 203673 5,190443425 1,901158395<br />

44320 49032 93352 147096 3,318953069 1,575713429<br />

71


Bibliografie<br />

[3DS] Autodesc website. http://www.discreet.com/.<br />

[ATI] Ati devel<strong>op</strong>er website. http://www.ati.com/devel<strong>op</strong>er/.<br />

[AW87] John Amanatides and Andrew Woo. A fast voxel traversal algorithm<br />

for ray tracing. In Eurographics ’87, pages 3–10. Elsevier<br />

Sci<strong>en</strong>ce Publishers, Amsterdam, North-Holland, 1987.<br />

[Bro] Brookgpu website. http://graphics.stanford.edu/projects/<br />

brookgpu/.<br />

[Chr05] Martin Christ<strong>en</strong>. <strong>Ray</strong> tracing on gpu. Master’s thesis, University<br />

of Applied Sci<strong>en</strong>ces Basel, Switzerland, 2005.<br />

[DBB03] Philip Dutré, Philippe Bekaert, and Kavita Bala. Advanced Global<br />

Illumination. A K Peters, Natick, USA, 2003.<br />

[FK03] Randima Fernando and Mark J. Kilgard. The Cg Tutorial: The<br />

Definitive Guide to Programmable Real-Time Graphics. Addison-<br />

Wesley Longman Publishing Co., Inc., Boston, MA, USA, 2003.<br />

[FS05] Tim Foley and Jeremy Sugerman. Kd-tree acceleration structures<br />

for a gpu raytracer. 2005.<br />

[gpg] Gpgpu website. http://www.gpgpu.org/.<br />

[Hav00] Vlastimil Havran. Heuristic <strong>Ray</strong> Shooting Algorithms. Ph.d. thesis,<br />

Departm<strong>en</strong>t of Computer Sci<strong>en</strong>ce and Engineering, Faculty of Electrical<br />

Engineering, Czech Technical University in Prague, November<br />

2000.<br />

[J<strong>en</strong>01] H<strong>en</strong>rik Wann J<strong>en</strong>s<strong>en</strong>. Realistic image synthesis using photon mapping.<br />

A. K. Peters, Ltd., Natick, MA, USA, 2001.<br />

[KL04] Filip Karlsson and Carl Johan Ljungstedt. <strong>Ray</strong> tracing fully implem<strong>en</strong>ted<br />

on programmable graphics hardware. Master’s thesis,<br />

Chalmers University of Technology, Swed<strong>en</strong>, 2004.<br />

[lib] lib3ds website. http://lib3ds.sourceforge.net/.<br />

[MT97] Tomas Möller and B<strong>en</strong> Trumbore. Fast, minimum storage raytriangle<br />

intersection. j-J-GRAPHICS-TOOLS, 2(1):21–28, 1997.<br />

[nVi] nvidia devel<strong>op</strong>er website. http://devel<strong>op</strong>er.nvidia.com/.<br />

72


[Ope] Op<strong>en</strong>gl website. http://www.<strong>op</strong><strong>en</strong>gl.org/.<br />

[PDC + 03] Timothy J. Purcell, Craig Donner, Mike Cammarano, H<strong>en</strong>rik Wann<br />

J<strong>en</strong>s<strong>en</strong>, and Pat Hanrahan. Photon mapping on programmable<br />

graphics hardware. In Proceedings of the ACM SIGGRAPH/EU-<br />

ROGRAPHICS Confer<strong>en</strong>ce on Graphics Hardware, pages 41–50.<br />

Eurographics Association, 2003.<br />

[PF05] Matt Pharr and Randima Fernando. <strong>GPU</strong> Gems 2 : Programming<br />

Techniques for High-Performance Graphics and G<strong>en</strong>eral-Purpose<br />

Computation. Addison-Wesley Professional, March 2005.<br />

[Pur] Timothy John Purcell. <strong>Ray</strong> <strong>Tracing</strong> on a Stream Processor. PhD<br />

thesis.<br />

[Sh] Sh website. http://libsh.org/.<br />

[sha] Microsoft website. http://www.microsoft.com/whdc/winhec/<br />

partners/shadermodel30\_NVIDIA.mspx.<br />

[Shi00] Peter Shirley. Realistic ray tracing. A. K. Peters, Ltd., Natick, MA,<br />

USA, 2000.<br />

[Tro] Trolltech website. http://www.trolltech.com/.<br />

[Wal04] Ingo Wald. Realtime <strong>Ray</strong> <strong>Tracing</strong> and Interactive Global Illumination.<br />

PhD thesis, Computer Graphics Group, Saarland University,<br />

2004. Available at http://www.mpi-sb.mpg.de/ ∼ wald/PhD/.<br />

[WBWS01] Ingo Wald, Carst<strong>en</strong> B<strong>en</strong>thin, Markus Wagner, and Philipp<br />

Slusallek. Interactive r<strong>en</strong>dering with coher<strong>en</strong>t ray tracing. In Alan<br />

Chalmers and Theresa-Marie Rhyne, editors, Computer Graphics<br />

Forum (Proceedings of EUROGRAPHICS 2001, volume 20,<br />

pages 153–164. Blackwell Publishers, Oxford, 2001. available at<br />

http://graphics.cs.uni-sb.de/ wald/Publications.<br />

[WSB01] Ingo Wald, Philipp Slusallek, and Carst<strong>en</strong> B<strong>en</strong>thin. Interactive<br />

distributed ray tracing of highly complex models. In S.J.Gortler<br />

and K.Myszkowski, editors, R<strong>en</strong>dering Techniques 2001 (Proceedings<br />

of the 12th EUROGRAPHICS Worksh<strong>op</strong> on R<strong>en</strong>dering),<br />

pages 277–288. Springer, 2001. available at http://graphics.cs.unisb.de/<br />

wald/Publications.<br />

73

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!