…en belichting
Een van de belangrijkste aspecten van een realistische 3D-wereld is de belichting. In vroege 3D-spellen werden licht en donker ‘gesimuleerd’ door middel van een zogenaamde light map. Dit is de uitkomst van een belichtingsberekening die tijdelijk wordt opgeslagen als een speciale textuur en die over een oppervlak wordt ‘geplakt’. Het voordeel van light maps is dat ze er al snel mooi uitzien, het nadeel is dat ze statisch, ofwel gefixeerd zijn: hoe je er ook naar kijkt, het licht verandert niet mee. Zoiets als een zaklamp die het personage in je spel met zich meedraagt, is dan ook niet mogelijk. Een ander nadeel van light maps is dat ze verderop in de pipeline voor meer werk zorgen, want feitelijk moet er een extra textuur verwerkt worden.

Figuur 10: Een textuur met alleen omgevingslicht.

Figuur 11: Een belichtingstextuur (light map).

Figuur 12: Het eindresultaat oogt heel realistisch.
Een alternatief is vertex lighting, een methode waarbij voor iedere vertex informatie is opgeslagen met betrekking tot hoe deze verlicht is, welke wordt gecombineerd met de informatie van de twee vertices waarmee hij verbonden is (de andere twee hoekpunten van de driehoek). Deze manier van belichten heeft gevolgen voor ieder van de (maximaal drie) driehoeken waarvan de vertex onderdeel is. Ook vertex lighting heeft voor- en nadelen: omdat het feitelijk niets anders is dan een reeks variabelen die zijn gedefinieerd per vertex, kunnen die variabelen bewerkt worden en kan het licht dus gemanipuleerd worden op een groot aantal manieren. Deze mogelijke dynamiek is een groot voordeel in het realistischer maken van een 3D-omgeving. Het nadeel is natuurlijk inherent aan deze manier van belichting: juist omdat de belichtingsinformatie per vertex bepaald is, zijn veel vertices nodig voor een realistische belichting. Dit is goed zichtbaar in Quake 3 Arena: wanneer gebruik gemaakt wordt van vertex lighting zien de player models er goed uit, want die bestaan uit relatief veel driehoeken, maar met een object als een vlakke muur is in het ergste geval zelfs de driehoek zichtbaar die belicht wordt. Figuur 13 en 14 laten duidelijk zien waarom vertex lighting alleen kan werken met voldoende polygonen.

Figuur 13: Te weinig polygonen leiden tot onrealistische vertex lighting.

Figuur 14: Met genoeg polygonen is realistische vertex lighting mogelijk.
Inmiddels wordt vertex lighting toch steeds meer gemeengoed in 3D-werelden. Dit heeft twee oorzaken: moderne videokaarten hebben weinig moeite met een groot aantal polygonen, waardoor een muur – die in theorie maar uit twee driehoeken hoeft te bestaan – toch realistisch belicht kan worden, simpelweg door hem uit meer driehoeken op te bouwen dan nodig is.
De tweede oorzaak is dat de specificatie van hoe licht ‘gemaakt’ wordt in een 3D-omgeving met iedere nieuwe versie van DirectX nauwkeuriger wordt. ‘Licht’ zoals we dat zien in moderne 3D-werelden wordt samengesteld door een aantal ‘lichtsoorten’ te combineren: omgevingslicht (ambient light), indirect reflecterend licht (diffuse light), direct reflecterend licht (specular light) en stralend licht.
Omgevingslicht is in deze context een soort ‘basislicht’: het heeft overal in een virtuele ruimte dezelfde sterkte en kleur. Het is eenvoudig te berekenen maar niet erg realistisch zonder de andere belichtingssoorten. Indirect reflecterend licht zorgt voor schaduwen en kleurgradaties op objecten en kan de illusie van 3D in hoge mate versterken; het is dan ook een stuk rekenintensiever. Direct reflecterend licht voegt hieraan toe; stralend licht ten slotte creëert bijvoorbeeld een lichtschijnsel. Deze laatste vorm van belichting wordt weinig gebruikt, aangezien andere technieken een overtuigender effect creëren.

Figuur 15: De belangrijkste verschillende lichtsoorten.
De belichtingsinformatie wordt zoals gezegd per vertex opgeslagen. Aangezien deze zich bevindt in een 3D-omgeving, zijn er drie richtingen ofwel vectoren die de manier waarop licht reflecteert op het object beïnvloeden. Ieder van deze drie vectoren moet dus ‘beschreven’ worden in de vertex-data. Verder is uiteraard kleurinformatie nodig, 4 bytes per vertex indien gebruik wordt gemaakt van 32-bits ware kleuren. Voeg hieraan toe informatie over wat voor soort textuur later in de pipeline bij de vertex hoort, informatie over waar deze textuur geplaatst moet worden (texture mapping), op wat voor manier meerdere texturen (multitexturing, waarover later meer) met elkaar gecombineerd moeten worden (blending)… al snel kom je dan tot de conclusie dat 75 bytes informatie per driehoek benodigd is. Als dat niet veel lijkt, bedenk dan eens hoeveel miljoen polygonen een modern 3D-spel op een willekeurig moment op het scherm tovert.
Op naar deel 2...
Met deze conclusie zijn we aan het einde gekomen van deel 1 van deze reeks artikelen over de werking van een moderne videokaart. In het volgende deel gaan we in op enkele van de technieken om intelligent om te gaan met de enorme hoeveelheid vertex-informatie waar we het nu over hebben. Vervolgens gaan we naadloos over in het volgende onderdeel van de 3D graphic pipeline: clipping en back face culling. Om alvast een tipje van de sluier op te lichten van wat verder nog aan bod komt: we zullen in meer detail ingaan op de vertex en pixel shaders van DirectX 8 en 9, en we gaan uitgebreid kijken naar shading, texturing, filtering en antialiasing.