Realtidsskuggalgoritmer för virtuella 3D-världar på modern grafikhårdvara M A R C U S B E A U S A N G

Storlek: px
Starta visningen från sidan:

Download "Realtidsskuggalgoritmer för virtuella 3D-världar på modern grafikhårdvara M A R C U S B E A U S A N G"

Transkript

1 Realtidsskuggalgoritmer för virtuella 3D-världar på modern grafikhårdvara M A R C U S B E A U S A N G Examensarbete Stockholm, Sverige 2006

2 Realtidsskuggalgoritmer för virtuella 3D-världar på modern grafikhårdvara M A R C U S B E A U S A N G Examensarbete i datalogi om 20 poäng vid Programmet för datateknik Kungliga Tekniska Högskolan år 2006 Handledare på CSC var Lars Kjelldahl Examinator var Lars Kjelldahl TRITA-CSC-E 2006:069 ISRN-KTH/CSC/E--06/069--SE ISSN Kungliga tekniska högskolan Skolan för datavetenskap och kommunikation KTH CSC Stockholm URL:

3 Sammanfattning En skugga kan ge viktiga ledtrådar om var objekt är placerade i en scen. Vidare kan skuggor ge information om formen på objektet som kastar skuggorna och formen på objektet som skuggas. Skuggor kan även ge virtuella scener ett mer realistiskt utseende. Trots detta är skuggor sällsynta i applikationer som visar upp virtuella scener. Denna exjobbsrapport sammanfattar litteraturen och forskningen kring realtidsskuggalgoritmer. Framförallt inriktas det på algoritmer som utnyttjar modern grafikhårdvara. Dessa algoritmer utvärderas sedan och resultatet av utvärderingen kan användas för att föreslå lämpliga algoritmer för olika applikationer och användningsområden. Rapporten presenterar även en ny skuggalgoritm som kan användas för att i realtid generera skuggor i stora utomhusmiljöer. Real-time shadow algorithms for virtual 3Dworlds using modern graphics hardware Abstract A shadow can give important cues about objects placement in a scene, it also gives cues about the shape of the object casting the shadows and the object being shadowed. Shadows can also give virtual scenes a more lifelike appearance. Despite this shadows are rarely seen in applications displaying virtual scenes. This master s thesis summarizes the literature and research in real-time shadow algorithms, in particular algorithms utilizing modern graphics hardware. These algorithms are then evaluated and the result of the evaluation can be used to suggest suitable algorithms for different application areas. This report also presents a new real-time shadow algorithm that can be used to create shadows in large outdoor environments.

4 Förord Jag skulle först och främst vilja tacka min handledare och examinator vid Nada, Lars Kjelldahl, för hans hjälp och stöd genom hela exjobbet. Jag vill även tacka min handledare på Scalo AB, Magnus Andersson, för att ha presenterat mig inför uppgiften och för all hjälp och information under arbetets gång. Slutligen vill jag även säga tack till min familj och mina vänner för deras stöd.

5 Innehållsförteckning Innehållsförteckning Inledning... 1 Bakgrund... 1 Problembeskrivning... 1 Målbeskrivning... 1 Struktur... 2 Grafikhårdvara... 3 Introduktion... 3 Buffertar, stenciltest och alfablandning... 4 Rendera till textur... 5 Vertex och pixel shaders... 5 Cg, HLSL och GLSL... 6 Skuggor... 8 Varför skuggor är viktiga... 8 Skuggornas kvalitet...10 Skuggalgoritmer Skuggvolymalgoritmer Inledning Z-pass, z-fail och ZP Konstruktion av skuggvolym Optimeringar Skuggvolymalgoritm för mjuka skuggor Shadow map-algoritmer Inledning Ljus i flera riktningar Aliasing Modifieringar av shadow map-algoritmen Perspective shadow map Light space perspective shadow map Trapezoidal shadow map Shadow silhouette map Penumbra map och smoothies Mjuka skuggor med shadow map-algoritmen Percentage closer soft shadows Andra algoritmer Skuggtexturer Objektidentifikation Shadow map - skuggvolym hybrid Algoritmer med försteg Occlusion interval maps Precomputed radiance transfer Skuggfält... 34

6 Innehållsförteckning Utvärdering och jämförelse Utvärderingskriterier...35 Resursförbrukning Kvalitet Generalitet Utvärdering av skuggalgoritmer Skuggvolymalgoritmer Z-pass, z-fail och ZP Skuggvolymer på grafikhårdvaran CC skuggvolymer Skuggvolymalgoritm för mjuka skuggor Shadow map-algoritmer Shadow map-algoritmen Perspective shadow map, light space perspective shadow map och trapezoidal shadow map Shadow silhouette map Penumbra map och smoothies Single sample soft shadows Mjuka skuggor genom att använda PCF Percentage closer soft shadows Andra algoritmer Skuggtexturer Objektidentifikation Shadow map - skuggvolym hybrid Occlusion interval maps Precomputed radiance transfer Skuggfält Tabeller Rekommenderade algoritmer Virtual terrain project Existerande algoritm...51 Ny algoritm Bakgrund Metoden Utvärdering Framtiden Avslutning Litteraturlista Bilaga A... 65

7 Inledning Inledning Bakgrund Skuggor är en viktig komponent i en renderad bild. Utan skuggor kan bilden lätt uppfattas som konstgjord eller felaktig. Detta eftersom vi är vana vid att objekt skall kasta skuggor, när dessa element fattas upplevs det som fel. Vidare är skuggor bra hjälpmedel för att visa hur objekt är placerade i förhållande till varandra. Det är till exempel lättare att uppfatta om en boll ligger på marken eller befinner sig i luften, om bollen även kastar skuggor på marken. Trots att skuggor är en sådan viktig del i en renderad bild är de sällsynta i applikationer som skapar virtuella 3D-världar. Detta kan till stor del bero på att genereringen av skuggor är en ganska kostsam process och att centralprocessorn används till andra beräkningar i sådana applikationer. Under de senaste åren har dock grafikhårdvaran blivit mer kraftfull och programmerbar. Genom att flytta över mycket av arbetet med att generera skuggor till grafikhårdvaran kan det nu bli möjligt för VR-applikationer att inkludera skuggor i sina virtuella världar. Detta samtidigt som processorkapaciteten kan användas till annat. Vad som också är intressant är att denna kraftiga grafikhårdvara medföljer som standardutrustning på moderna hem- och arbetsdatorer, vilket gör att antalet potentiella användare är mycket stort. Problembeskrivning Under de senaste åren har det kommit en uppsjö av förslag på algoritmer för att generera skuggor i realtid. Trots detta är skuggor relativt ovanliga i virtuella 3D-världar. Det skulle därför vara intressant att undersöka vilka skuggalgoritmer som passar bra för att generera skuggor i dessa virtuella 3D-världar. Då VR-applikationer kan se olika ut och vara uppbyggda på olika sätt kan vissa algoritmer passa bättre till vissa applikationer och sämre till andra. Detta bör tas i åtanke när skuggalgoritmerna undersöks. Vidare är det intressant att undersöka hur den moderna programmerbara grafikhårdvaran kan användas i samband med skuggenerering. Grafikhårdvaran kan användas både för att öka prestanda och för att öka den visuella kvaliteten. Målbeskrivning Ett mål med examensarbetet är att rekommendera en eller flera skuggalgoritmer som lämpar sig bäst för att med modern grafikhårdvara generera skuggor i virtuella 3D-världar. För att nå detta mål har en genomgång av litteraturen kring skuggalgoritmer genomförts. Framförallt har det inriktats på de skuggalgoritmer som lämpar sig för att exekvera i realtid på modern grafikhårdvara. Därefter utvärderades de olika algoritmerna mot ett antal kriterier. Resultatet av denna utvärdering användes sedan för att hitta lämpliga skuggalgoritmer. Eftersom uppdragsgivaren bygger sin programvara på Virtual terrain project (VTP), har dess egenheter setts över för att avgöra om någon algoritm passar bättre än någon annan. Ett annat mål med examensarbetet är att implementera den eller de föreslagna skuggalgoritmerna i en prototyp, detta för att visa vilken prestanda och kvalitet som kan förväntas av algoritmerna. 1

8 Inledning Struktur Kapitel Grafikhårdvara ger en introduktion till hur modern grafikhårdvara fungerar, och beskriver närmare de funktioner som är användbara vid generering av skuggor. Kapitel Skuggor introducerar de begrepp som används i samband med skuggor. Vidare beskrivs varför skuggor är viktiga i virtuella 3D-världar. Kapitel Skuggalgoritmer är en sammanfattning av litteraturen kring realtidsskuggalgoritmer och beskriver kort de centrala algoritmerna. I kapitel Utvärdering och jämförelse utvärderas de skuggalgoritmer som beskrevs i kapitlet Skuggalgoritmer. Därefter följer Rekommenderade algoritmer där jag rekommenderar lämpliga algoritmer för applikationer som liknar VTP. Kapitel Framtiden innehåller tankar om framtiden för grafikhårdvara och skuggalgoritmer. Rapporten sammanfattas med kapitlet Avslutning. 2

9 Grafikhårdvara Grafikhårdvara Grafikhårdvaran som används i hem- och arbetsdatorer har utvecklats mycket under de senaste åren. Detta kapitel visar hur dagens grafikhårdvara fungerar, speciellt fokuseras på de funktioner som kan användas vid generering av skuggor. För mer information om grafikhårdvaran och realtidsrendering i allmänhet se Akenine-Möller och Haines bok [Aken02] Introduktion För att förstå hur modern grafikhårdvara fungerar och hur den har utvecklats under de senaste åren kan det vara bra att veta vilka steg som är involverade vid renderingen av en scen. Figur 1 illustrerar denna renderings-pipeline. Applikationssteget Scendata Geometristeget Vertex shader Bestämd belysning och transformation Clipping Screen mapping Rastreringssteget Pixel shader Textursteg Dimma (Fog) Alfa, stencil och djuptester Figur 1: Figuren visar de olika stegen i en renderingspipeline. I en modern renderingspipeline ersätter vertex shader de tidigare bestämda belysning- och transformationsberäkningarna, likaså ersätter pixel shader de tidigare texturstegen. I applikationssteget bestäms vilka polygoner (objekt) som skall ritas ut. Här bestäms även de parametrar som behövs i efterföljande steg. Applikationssteget använder sig egentligen inte av hårdvaran, utan är det steg som ser till att hårdvaran får all information den behöver för att utföra de efterföljande stegen. Geometristeget arbetar med de hörn och polygoner som applikationssteget tillhandahållit. En viktig funktion i geometristeget är att beräkna transformationer och belysning för polygonernas hörn. I detta steg sker även clipping och screen mapping. Clipping ser till att de delar av polygonerna som inte syns plockas bort, dessa bortplockade delar behöver därmed inte behandlas i efterföljande steg. Screen mapping ser till att scenen positioneras på rätt ställe på skärmen. Rastreringssteget har som indata positionen på de transformerade och projicerade hörnen i screen space, samt data såsom färg och texturkoordinater för varje hörn. Resultatet av rastreringen blir de pixlar som kan visas på skärmen. I rastreringssteget sker texturering, beräkning av dimma och djuptest. Här kan även stenciltest och alfablandning ske (mer om detta nedan). Innan det fanns speciellt dedicerad hårdvara för rendering utfördes samtliga steg ovan av centralprocessorn. Tidig grafikhårdvara hade bara stöd för att utföra funktioner i rastrerings- 3

10 Grafikhårdvara steget, denna grafikhårdvara hjälpte dock till att avlasta centralprocessorn. Då grafikhårdvaran var specialiserad på sin uppgift var den mycket snabbare än centralprocessorn och kallades därför för accelerator. Nästa steg för grafikhårdvaran kom 1999 då Nvidia lanserade GeForce256, som hade stöd i hårdvaran för transformationer och ljusberäkningar vilket gjorde att även geometristeget kunde accelereras. En begränsning dessa acceleratorer hade var att transformationerna och ljusberäkningarna var implementerade i hårdvaran. Det gick därför inte att utföra godtyckliga ljusberäkningar eller transformationer som accelererades av hårdvaran. När Nvidia lanserade GeForce 3 introducerades vertex och pixel shaders 1. Dessa shaders är små program som exekveras på grafikhårdvaran och kan till exempel avgöra hur belysningen skall beräknas eller hur texturering skall gå till. Denna moderna och programmerbara grafikhårdvara brukar kallas för GPU (Graphics Processing Unit). Buffertar, stenciltest och alfablandning Vid realtidsrendering med grafikhårdvara används ett antal buffertar. En buffert är ett minnesutrymme som kan lagra ett eller flera värden för varje pixel. Den kanske viktigaste bufferten är färgbufferten. Denna buffert lagrar färgen på de objekt som renderas och är den buffert som presenteras på skärmen. Färgbufferten består av fyra kanaler, där tre av kanalerna används för att lagra färgdata. Dessa tre kanaler lagrar i tur och ordning färgens röda, blåa och gröna komponent. Vanligtvis lagrar varje kanal ett 8-bitars tal, modern grafikhårdvara har dock stöd för att lagra tal med 32-bitars precision. I färgbufferten ingår ytterligare en kanal, nämligen alfa-kanalen. I denna kanal lagras ett värde som vanligtvis används för att tala om hur transparent ett objekt är. Utöver färgbufferten finns det även en z-buffert (eller djupbuffert). Z-bufferten lagrar avståndet mellan kamerans frontplan och objektet. Z-bufferten används för att ta bort skymda objekt, det vill säga objekt som befinner sig bakom ett annat objekt sett från kameran. Det finns även en stencilbuffert som används tillsammans med ett stenciltest för att utföra olika operationer. Stencilbufferten lagrar ett heltal per pixel, och grafikhårdvaran kan rendera till stencilbufferten för att öka eller minska dessa heltal. Därefter använder stenciltestet sig av innehållet i bufferten för att avgöra vilka pixlar som skall uppdateras i färg- och z-bufferten. Ett exempel där stencilbufferten och stenciltestet kan vara användbart är när en scen innehåller en spegel. För att skapa spegelbilden kan scenen renderas spegelvänd kring planet som innehåller spegeln. När den spegelvända scenen renderas skall dock bara de pixlar som spegeln upptar renderas. Detta åstadkoms genom att initiera stencilbuffertens värde till 0. Därefter renderas spegeln till denna buffert med funktionen att öka buffertens värde med 1 där rendering sker. Därefter aktiveras stenciltest med villkoret att endast uppdatera de pixlar där stencilbufferten innehåller värdet 1. Slutligen renderas den spegelvända scenen, stenciltestet ser då till att endast de pixlar som motsvarar spegelns placering kommer att uppdateras. Stencilbufferten och stenciltestet är även användbara vid generering av skuggor. I rastreringssteget kan en operation som heter alfablandning utföras. Vad alfablandning innebär är att färgen på det objekt som för närvarande renderas kan blandas med den färg som redan finns lagrad i färgbufferten. Alfablandning tillhandahåller ett antal olika operationer som bestämmer hur färgerna skall blandas. Vid alfablandning kan samma blandning utföras på samtliga pixlar. Alternativt kan alfa-kanalen i färgbufferten användas för att per pixel avgöra effekten av blandningen. Alfablandning kan till exempel användas för att rendera en scen innehållande flera ljuskällor. Scenen renderas då en gång per ljuskälla och resultatet från varje pass adderas med hjälp av alfablandning. 1 Jag har här valt att använda Microsofts benämningar, nämligen vertex shader och pixel shader. I OpenGL används uttrycket vertex program i stället för vertex shader, och fragment program i stället för pixel shader. 4

11 Grafikhårdvara Rendera till textur Möjligheten att kunna rendera till en textur har uppmärksammats av de ledande grafik- API:erna under de senaste åren. Vad rendering till textur innebär är att det som renderas lagras i en textur, denna textur kan sedan användas och läsas ifrån i ett senare renderingssteg. Möjligheten att rendera till textur kan användas för att skapa många olika effekter, t.ex. dynamiska reflektioner eller skuggor. Tidiga implementeringar för att rendera till textur gick ut på att rendera till en färgbuffert (samma färgbuffert som lagrar det som visas på skärmen) [Harris]. Därefter används anrop som glreadpixels() för att läsa in de renderade pixlarna till systemminnet. Dessa pixeldata kan sedan skickas till grafikhårdvaran i form av en textur. Denna implementering är tyvärr mycket långsam eftersom dataöverföring från grafikminnet till systemminnet är långsam. En bättre metod är att utföra denna kopiering helt i grafikminnet. Detta kan åstadkommas genom anrop som glcopytexsubimage2d(), där pixeldata kopieras från färgbufferten till ett minnesutrymme i grafikminnet som motsvarar en textur. Notera dock att själva kopieringen av data fortfarande kvarstår, vilket är kostsamt. De ovanstående metoderna har en del problem, utöver den kostsamma kopieringen. Bland annat är upplösningen på den renderade texturen beroende av färgbuffertens upplösning. För att effektivisera rendering till textur föreslogs därför ett nytt begrepp, nämligen pixel buffers (eller pbuffers) [Ext02]. Genom att använda pixel buffers tillhandahålls nya buffertar som kan renderas till. Dessa buffertar kan ha olika upplösningar och pixelformat. Vidare kan dessa buffertar användas som texturer [Ext01]. Detta innebär att rendera till textur kan implementeras utan att några data behöver kopieras, detta kan markant öka prestanda jämfört med ovanstående metoder. Ett problem med pixel buffers är att de är komplicerade att använda. Dessutom är metoden beroende av operativsystemets fönstersystemanrop för att byta renderingsbuffert, något som gör metoden svår att använda på olika fönstersystem. Under 2005 utarbetades en ny metod för att rendera till textur, nämligen framebuffer objects [Green05, Ext05]. Jämfört med pixel buffers är framebuffer objects enklare att använda. Dessutom är framebuffer objects helt inbyggd i API:et för OpenGL, vilket gör metoden mer portabel. Utformningen liknar mycket utformningen för pixel buffers, med olika buffertar att rendera till och möjlighet att använda dessa buffertar som texturer. Vertex och pixel shaders Som nämnts ovan har modern grafikhårdvara stöd för vertex och pixel shaders. Vad detta innebär är att delar av renderingspipelinen som är implementerad i hårdvara nu är programmerbar. Applikationer som tidigare velat göra dessa delar programmerbara var tvungna att låta centralprocessorn sköta exekveringen av de programmerbara delarna. Grafikhårdvaran användes då mindre och centralprocessorn mer, för att simulera grafikhårdvarans funktioner, vilket ledde till försämrad prestanda. Genom att ge hårdvarustöd för dessa programmerbara delar på modern grafikhårdvara, ökar prestanda markant för sådana applikationer. Delvis för att centralprocessorn då kan användas till andra beräkningar, men även för att grafikhårdvaran är specialiserad på den typen av beräkningar som förekommer inom datorgrafik. De delar som gjorts programmerbara kan ses i figur 1. Vertex shaders har ersatt de bestämda transformations- och belysningsberäkningarna, och pixel shaders har ersatt texturstegen. En vertex shader är ett program som är skrivet av en programmerare och som exekveras på grafikhårdvaran. Som namnet antyder exekveras detta program för varje hörn (vertex) som hårdvaran behandlar. Vertex shaders kan till exempel användas för att implementera godtyckliga transformationer av hörn eller nya belysningsmodeller. Vertex shaders använder sig av fyra olika uppsättningar register. Inmatningsregisterna innehåller data som varierar mellan olika hörn, till exempel normalen eller positionen. Konstantregisterna innehåller data som inte varierar mellan hörnen, exempelvis ljuskällans position. Vid beräkningar används temporär- 5

12 Grafikhårdvara registerna för att spara delresultat. Slutligen skrivs resultatet av beräkningarna till utmatningsregisterna. Eftersom en bestämd del av hårdvaran tar vid efter exekveringen av en vertex shader är det viktigt att rätt data skrivs till rätt utmatningsregister. Används pixel shaders är det viktigt att se till att vertex och pixel shaders kommunicerar med varandra på rätt sätt, detta eftersom utmatning från vertex shaders sedan blir till inmatning för pixel shaders. Används textursteget är det viktigt att data såsom texturkoordinater och färg hamnar i rätt register. Utmatningsregisterna är därför namngivna utifrån vad de är tänkta att innehålla, till exempel opos, ofog eller ot1 (texturkoordinatuppsättning 1). Idag existerar det flera olika vertex shader modeller, nämligen vs 1.1, vs 2.0, vs 2.x och vs 3.0 [Micro05-1]. Den första modellen, vs 1.1, är ganska begränsad, till exempel kan programmen som mest bestå av 128 instruktioner. Allteftersom grafikhårdvaran utvecklades, blev dessa modeller alltmer kraftfulla. Den senaste modellen, vs 3.0, måste åtminstone ha stöd för 512 instruktioner. Genom slingor och villkorssatser, vilka inte fanns tillgängliga i den första modellen, kan antalet exekverade instruktioner överstiga 512. Även nya instruktioner har tillkommit i de senare modellerna, till exempel för att beräkna sinus och cosinus eller för att normera vektorer. Även en instruktion för att läsa från en textur har tillkommit i vs 3.0. En pixel shader är likt en vertex shader ett program skrivet av en programmerare som exekverar på hårdvaran. Skillnaden är att en pixel shader exekverar per pixel i stället för per hörn. Pixel shaders kan till exempel användas för att avgöra hur texturering skall gå till eller för att utföra belysningsberäkningar per pixel. Likt vertex shaders har pixel shaders olika register att arbeta mot. Inmatningsregisterna innehåller data som var utmatning från vertex shaders och som interpolerats över triangeln som rastrerats. Konstant- och temporärregisterna fungerar på liknande sätt som i vertex shaders. Resultatet av en pixel shader är färgen på pixeln. Likt vertex shader modellerna existerar det idag flera pixel shader modeller: ps 1.x, ps 2.0, ps 2.x och ps 3.0 [Micro05-2]. De första pixel shader modellerna är hårt begränsade. Program skrivna för modell 1.4 är till exempel begränsade till endast 8 aritmetiska instruktioner, samt 6 texturinstruktioner för att indexera texturer. Modellerna har dock utvecklats fort. Ps 3.0 modellen är nästan likvärdig med vs 3.0 modellen, med stöd för åtminstone 512 instruktioner samt slingor och villkorssatser. Cg, HLSL och GLSL När vertex och pixel shaders introducerades programmerades shaders i ett assemblerspråk. Detta är förståeligt för de tidiga pixel shader modellerna som bara kunde innehålla 8+6 instruktioner. Här ger assemblerspråket god kontroll för optimeringen av shaders. De tidiga vertex shader modellerna kan dock innehålla 128 instruktioner, ett sådant stort program blir svårt att programmera och underhålla i assembler. I de senare shader modellerna kan programmen vara ännu större och det finns fler instruktioner att hålla reda på. Många av dessa instruktioner har också begränsningar för vilka register de kan ta som argument och var resultatet returneras. Vidare är skillnaderna mellan olika hårdvara stora, ett assemblerprogram för vs 1.1-hårdvara kan skilja sig ganska mycket från ett program skrivet för vs 3.0-hårdvara. För att underlätta för programmerare skapade Nvidia ett högnivåspråk för att programmera shaders, Nvidia kallar detta system Cg eller C for graphics [Mark03]. Cg är inriktat åt att vara ett generellt språk för att programmera grafikhårdvara. Detta skiljer sig från tidigare shaderspråk, såsom Renderman, vilket är mer inriktat mot att utföra beräkningar för ytor och lampor. I Cg används samma språk, dvs. samma syntax, för att skriva både vertex och pixel shaders. Kompilatorn gör sedan sitt bästa för att skapa assemblerinstruktioner för respektive shadertyp. Kompilatorn försöker även utjämna skillnaderna mellan de olika shader-modellerna genom att approximera funktioner som saknas i de tidigare versionerna. Till exempel saknar vs 1.1- modellen en instruktion för att beräkna sinusfunktionen. Med Cg kan en vertex shader skrivas innehållande en sinusfunktion och sedan kompilera till valfri modell. Om shadern skall 6

13 Grafikhårdvara kompileras till vs 1.1-modellen approximerar kompilatorn sinusfunktionen, om shadern skall kompileras till vs 2.0-modellen används instruktionen som beräknar sinusvärdet. Själva språket är likt programmeringsspråket C. Figur 2 visar hur en shader kan se ut i Cg och i assemblerform. void main(float4 position : POSITION, float4 incolor : COLOR, float3 normal : NORMAL, out float4 clipposition : POSITION, out float4 outcolor : COLOR, uniform float4x4 worldviewproj, uniform float3 lightvec) { clipposition = mul(worldviewproj, position); outcolor = dot(normal, lightvec)*incolor; } vs.1.1 dp4 opos.x, c0, v0 dp4 opos.y, c1, v0 dp4 opos.z, c2, v0 dp4 opos.w, c3, v0 dp3 r0.x, v3.xyz, c4.xyz mul od0, r0.x, v5 a) b) Figur 2 a): Cg kod för en vertex shader som utför transformation till clip space samt en enkel belysningsberäkning. b): Motsvarande kod i assembler. Samtidigt som Nvidia utvecklade Cg, arbetade utvecklarna av de två dominerande grafik API:erna, Direct3D och OpenGL, med att skapa sina egna versioner av ett högnivåspråk för att programmera shaders. Språket som används i Direct3D kallas för HLSL (High Level Shading Language) [Micro05-3], motsvarigheten för OpenGL kallas GLSL (OpenGL Shading Language) [Kessen04]. Lyckligtvis skedde mycket samarbete mellan utvecklarna av Cg, HLSL och GLSL. Detta ledde till att språken blev lika varandra, vilket innebär att utvecklare som lärt sig ett av språken lätt kan förstå hur de andra språken fungerar. En fördel Cg har över HLSL och GLSL, är att Cg inte är bundet till något specifikt grafik API. Detta innebär att shaders skrivna i Cg kan användas både i Direct3D och i OpenGL. Fördelen med HLSL och GLSL är att de är mer integrerade i respektive grafik API, vilket gör användningen av shaders smidigare. 7

14 Skuggor Skuggor Figur 3a illustrerar en enkel scen bestående av en punktljuskälla och två objekt. Punkt A och B på objekt X kan se ljuskällan och är därför belysta. Punkt C på objekt X kan däremot inte se ljuskällan eftersom objekt Y skymmer denna. I detta fall befinner sig punkt C i skugga och skuggas av objekt Y. Punkt D ligger på gränsen där objekt Y skuggar objekt X, här kommer en hård skuggkant att uppstå. En punktljuskälla är en ljuskälla som bara sprider ljus från en enda punkt. En sådan ljuskälla används ofta inom datorgrafiken eftersom belysningsberäkningarna blir enkla. I verkligheten har dock ljuskällorna ofta en area, vilket innebär att ljus sprids från flera punkter. Figur 3b visar motsvarande scen som i figur 3a, men här har punktljuskällan bytts ut mot en ljuskälla med en area. Likt fallet med punktljuskällan kommer punkt A vara fullständigt belyst eftersom hela ljuskällan syns. Punkt C kommer även den befinna sig i skugga eftersom objekt Y skymmer hela ljuskällan. Punkt B kan däremot se en del av ljuskällan, medan objekt Y skymmer den andra delen. Punkt B befinner sig därmed inte helt i skugga, men inte heller är punkten helt belyst. Punkt B befinner sig här i den halvskugga som objekt Y ger upphov till. De tjocka linjerna i figur 3b visar vilka områden som befinner sig i halvskugga. Intensiteten på ljuset som når dessa punkter beror på hur stor del av ljuskällan punkten kan se, och kommer att variera inom halvskuggområdet. Detta ger upphov till mjuka skuggor. Punktljuskälla Ljuskälla med area a) b) Y Y A B C D A B C X X Figur 3 a): Scen belyst av en punktljuskälla. Punkt A och B är fullständigt belysta, medan punkt C befinner sig helt i skugga. Punkt D visar var den hårda skuggkanten kommer att uppträda. b): Scen belyst av en ljuskälla med area. Punkt A är fullständigt belyst och punkt C befinner sig helt i skugga. Punkt B befinner sig i halvskugga. De tjocka linjerna visar var de mjuka skuggkanterna kommer att uppträda. Varför skuggor är viktiga Skuggor är viktiga att inkludera i virtuella scener av flera anledningar. För det första vill man med många virtuella scener ge ett intryck av realism. Eftersom skuggor är naturliga i vår omgivning uppfattas en virtuell scen utan skuggor ofta som konstgjord. Genom att inkludera mjuka realistiska skuggor i en scen kan intrycket av realism ökas. En annan anledning till att inkludera skuggor i en virtuell scen är att skuggorna ger ledtrådar om objektens form och förhållandet mellan olika objekt. Mamassian m.fl. [Mamassian98] beskriver hur skuggor kan ge oss information om: Formen på det objekt som kastar skuggor. Formen på det objekt som skuggas. Det spatiala förhållandet mellan det objekt som kastar skuggor och det objekt som skuggas. 8

15 Skuggor Figur 4 visar hur skuggor kan hjälpa till att beskriva ett objekts form. Eftersom kameran inte samtidigt kan se hela objektet kan skuggor hjälpa till att förklara hur de skymda delarna av objektet ser ut. a) b) Figur 4 a): Utan skuggor är det lätt att tro att objektet är en sfär. b): När objektet kastar skuggor liknar det i stället en hantel. Figur 5 visar även hur skuggor kan hjälpa till att beskriva formen på det objekt som skuggas. a) b) Figur 5 a): Utan skuggor är det svårt att uppfatta underlagets form. b): När objektet kastar skuggor på underlaget framträder dess form tydligare. Mamassian m.fl. nämner dock att ibland ger skuggorna inte speciellt mycket information om vare sig objektets form eller mottagarens form. Detta kan till exempel inträffa när både objektet som kastar skuggan och objektet som skuggas har en mycket ojämn form. Den avbildade skuggan blir då en blandning av de båda objektens ojämna former och det blir svårt att skilja det ena objektets inverkan från det andra. Wanger [Wanger92] nämner även att mjuka skuggor ofta är sämre än hårda skuggor på att ge information om ett objekts form. Wanger och Mamassian är dock båda överens om att skuggor är mycket bra på att förmedla information om det spatiala förhållandet mellan det objekt som kastar skuggor och det objekt som skuggas. Figur 6 visar hur en scens utseende kan förändras genom att bara ändra på skuggans position och form. Mamassian m.fl. nämner även hur skuggors rörelse i en scen ger information om hur de ingående objekten rör sig i förhållande till varandra. I två filmer [Film1, Film2] visar de hur intryck av att objekt rör sig på olika sätt kan ges genom att bara ändra en skuggas position och form. I den första filmen är objekten i scenen helt statiska. Genom att ändra på skuggans position och form ges ändå intrycket av att objekten rör sig i förhållande till varandra. I den andra filmen ges intrycket av att en boll rör sig antingen i djupled eller i höjdled i ett rum endast genom att ändra skuggans position. 9

16 Skuggor a) b) Figur 6 a): Skuggans position ger intrycket av att sfären befinner sig nära underlaget. b): Skuggan befinner sig längre bort, och ger därmed intrycket av att avståndet mellan sfären och underlaget är större än i a). Skuggornas kvalitet I en rapport från 1992 beskriver Wanger [Wanger92] tre experiment rörande skuggors kvalitet och form. Experimenten genomfördes för att se vilken effekt skuggors kvalitet och form har på hur vi uppfattar ett objekt i en scen. I det första experimentet undersöktes hur hårda och mjuka skuggor påverkar uppfattningen av ett objekts position och storlek. Resultatet av experimentet blev att skuggornas kvalitet inte påverkar hur vi uppfattar ett objekts position och storlek. Det andra experimentet undersökte hur skuggornas form påverkade uppfattningen av ett objekts position och storlek. Objektet som användes i detta experiment var två sfärer som satt fast på var sin sida om en stång (likt en hantel). Den första formen på skuggor som skapades var objektets riktiga skuggor. Den andra formen på skuggor skapades genom att låta en box som omsluter objektet kasta en skugga. Detta gör att den senare skuggans form inte direkt liknar objektet. Inte heller i detta experiment kunde de finna någon signifikant skillnad i hur skuggornas form påverkar uppfattningen av position och storlek. I det tredje experimentet undersöktes hur hårda och mjuka skuggor påverkar uppfattningen av objektets form. Här skapades bilder liknande figur 4, där bara skuggan kan användas för att skilja mellan olika objekt. Resultatet av detta experiment visade att med de hårda skuggorna blev det lättare att uppfatta objektens form än med de mjuka, mer realistiska, skuggorna. Speciellt blev det svårt att avgöra ett objekts form med mjuka skuggor när objektet befann sig långt ovanför marken. Detta eftersom skuggorna blir suddigare ju längre från marken objektet befinner sig, och formen på objektet blir svårare att urskilja. Resultaten av dessa experiment kan vara värt att ha i åtanke när en skuggalgoritm ska väljas för en VR-applikation. Experimenten visar att hårda och mjuka skuggor fungerar lika bra som hjälpmedel för att uppfatta position och storlek. Däremot kan hårda skuggor vara bättre än mjuka skuggor på att avslöja ett objekts form. Detta bör göra skuggalgoritmer som genererar hårda skuggor mycket attraktiva i många VR-applikationer, speciellt eftersom dessa algoritmer kräver mindre beräkningskraft än algoritmer för mjuka skuggor. Endast i de VRapplikationer där skuggornas utseende måste vara verklighetstroget bör mjuka skuggor användas. 10

17 Skuggalgoritmer Skuggalgoritmer Det finns en stor mängd olika algoritmer för att generera skuggor inom datorgrafik. Vissa algoritmer passar dock bättre än andra för att generera skuggor i realtid, speciellt gäller detta algoritmer som kan utnyttja grafikhårdvaran. Idag finns det två olika grundalgoritmer som dominerar litteraturen inom realtidsskuggor, skuggvolymalgoritmen och shadow mapalgoritmen. Dessa algoritmer har sedan deras upptäckt modifierats ett flertal gånger, som vi ska se nedan. Den som redan är insatt i hur dessa algoritmer fungerar kan hoppa över detta kapitel och gå direkt till kapitel Utvärdering och jämförelse. Skuggvolymalgoritmer Inledning Skuggvolymalgoritmen föreslogs redan 1977 av Crow [Crow77]. Grundidén i algoritmen är att med hjälp av polygoner innesluta den volym där ett objekt ger upphov till skugga. Denna skuggvolym kan konstrueras på flera olika sätt, alla med sina för och nackdelar. Den metod som Crow föreslog var att börja med att leta fram objektets siluettkanter sett ifrån ljuskällan. En siluettkant är en kant mellan två polygoner där ena polygonens normal är vänd mot ljuskällan och den andra polygonens normal är vänd bort från ljuskällan. För varje siluettkant skapas sedan en polygon genom att använda sig av siluettkanten, vy-volymens begränsning (den delen av scenen användaren ser) och de linjer som går från ljuskällan genom siluettkantens ändpunkter, se figur 7. Dessa polygoner bildar skuggvolymen. Polygonerna för skuggvolymen som är riktade utåt från volymen benämns framsidepolygoner, baksidan av dessa polygoner benämns baksidepolygoner. Ljuskälla Vy-volym Kamera Skuggpolygon Siluettkant Figur 7: Ljuskällans position, vy-volymens utsträckning samt siluettkanten används för att skapa en skuggpolygon. När skuggvolymer för alla skuggkastande objekt i scenen är skapade, kan dessa användas för att ta reda på vilka ytor som befinner sig i skugga. Genom att räkna hur många framsiderespektive baksidepolygoner som korsas när man tar sig från ögat till en punkt på ett föremål i scenen, kan man avgöra om punkten befinner sig i skugga eller inte. När en framsidepolygon korsats kommer allt som stöts på fram tills en baksidepolygon korsats att vara i skugga. Om fler framsidepolygoner än baksidepolygoner korsats befinner sig punkten i skugga, se figur 8. Anledningen att skuggvolymalgoritmen har blivit populär är att den effektivt kan implementeras på modern grafikhårdvara. Heidmann [Heidma91] beskriver hur skuggvolymalgoritmen kan implementeras genom att använda stencilbufferten och stenciltestet. 11

18 Skuggalgoritmer Stencilbufferten används här för att beräkna antalet framside- respektive baksidepolygoner som korsats. Ljuskälla Kamera X D Y Skuggvolym Skuggvolym A B C Figur 8: När en stråle från kameran korsar en framsidepolygon ökar räknaren med 1, när strålen korsar en baksidepolygon minskar räknaren med 1. Strålen som når punkt C korsar först en framsidepolygon för skuggvolymen av objekt X (räknare C: 1). Därefter korsar strålen en framsidepolygon för skuggvolymen av objekt Y (räknare C: 2). Strålen korsar därefter en baksidepolygon för skuggvolymen av objekt X (räknare C: 1) och en baksidepolygon för skuggvolymen av objekt Y (räknare C: 0). Eftersom lika många framsidepolygoner som baksidepolygoner korsats befinner sig punkt C inte i skugga. Följer vi de andra strålarna får vi räknare A: 1, räknare B: 2 och räknare D: 1, vilket betyder att dessa punkter befinner sig i skugga. Heidmann föreslår följande steg för att rendera en scen innehållande skuggor: 1. Rendera scenen med endast allmänljus och emitterat ljus påslaget, detta uppdaterar z- bufferten och färgbufferten. 2. Nollställ stencilbufferten och stäng av uppdatering av z-bufferten och färgbufferten. 3. Rendera alla skuggvolymers framsidepolygoner och öka värdet i stencilbufferten där dessa polygoner klarar djuptestet. 4. Rendera alla skuggvolymers baksidepolygoner och minska värdet i stencilbufferten där dessa polygoner klarar djuptestet. 5. Aktivera uppdateringen av färgbufferten och aktivera stenciltest med villkoret att endast uppdatera de pixlar där stencilbufferten innehåller värdet 0. Rendera scenen med endast matt ljus och highlights påslaget och addera detta till färgbufferten. Figur 9 illustrerar hur uppdateringen av stencilbufferten går till. a) b) c) Figur 9 a): Figuren visar skuggvolymens framsidepolygoner (det vita området), enligt steg 3 kommer värdet i stencilbufferten att ökas för de pixlar dessa polygoner täcker. b): Figuren visar skuggvolymens baksidepolygoner (det vita området), enligt steg 4 kommer värdet i stencilbufferten att minskas för de pixlar dessa polygoner täcker. c): Endast för de pixlar där stencilbufferten inte innehåller värdet 0 kommer skugga att uppstå. Algoritmen kan även användas för att rendera en scen innehållande flera ljuskällor, detta åstadkoms genom att upprepa steg 2-5 för varje ljuskälla. Genom att placera många ljuskällor 12

19 Skuggalgoritmer i närheten av varandra kan denna metod användas för att skapa mjuka skuggor. Fler ljuskällor innebär dock flera renderingspass, vilket gör att renderingstiden för scenen ökar. Z-pass, z-fail och ZP+ Ett stort problem med Heidmanns metod är att den inte fungerar om kameran befinner sig inuti en skuggvolym. Detta eftersom en punkt kan befinna sig i skugga utan att några polygoner korsats. Inte heller behöver fler framsidepolygoner än baksidepolygoner ha korsats (figur 10). Akenine-Möller och Haines [Aken02] nämner att detta kan åtgärdas genom att inte initiera stencilbufferten till noll, utan i stället till det antalet skuggvolymer kameran befinner sig inuti. Tyvärr är detta inte en speciellt robust lösning på problemet. Detta eftersom den virtuella kameran även har ett frontplan som klipper bort de delar av polygonerna som är närmare kameran än frontplanet. Detta kan göra att skuggvolymens polygoner inte renderas, trots att kameran befinner sig utanför volymen (figur 11). Flera författare [Aken02, Carmack00, Everitt02, Kwoon] har nämnt detta problem. De nämner även att problemet kan lösas genom att ta reda på vilka delar som klippts bort och se till att dessa delar ändå renderas strax efter frontplanet. Denna lösning är dock beräkningskrävande och lämpar sig därför inte i realtidssammanhang. Ljuskälla Figur 10: Om kameran befinner sig inuti en skuggvolym uppstår problem. Strålen som når punkt A korsar ingen skuggvolympolygon, men punkten är helt klart i skugga. Strålen som når punkt B korsar lika många framsidepolygoner som baksidepolygoner, den ursprungliga algoritmen skulle se punkt B som en punkt som inte befinner sig i skugga. Kamera X +1 Y Skuggvolym Skuggvolym -1 Ljuskälla A B Kamera X Y +1 Skuggvolym Skuggvolym +1-1 A B Figur 11: Problem kan uppstå när kamerans frontplan klipper bort delar av skuggvolymens polygoner. Den stråle som når punkt A kommer att behandlas på rätt sätt eftersom den delen av polygonen som strålen korsar ligger inuti vy-volymen. Strålen som når punkt B kommer bara att notera en korsning med en framsidepolygon (för objekt Y), framsidepolygonen för objekt X hamnar utanför vy-volymen och klipps därför bort. Eftersom även en baksidepolygon korsas kommer stencilbufferten att innehålla värdet 0, vilket enligt algoritmen innebär att punkten inte befinner sig i skugga. 13

20 Skuggalgoritmer Carmack [Carmack00] beskriver en annan metod som kan användas för att undvika de problem frontplanet skapar. Vad han föreslår är att ändra steg 3 och 4 i metoden ovan till följande: 3. Rendera alla skuggvolymers baksidepolygoner och öka värdet i stencilbufferten där dessa polygoner inte klarar djuptestet. 4. Rendera alla skuggvolymers framsidepolygoner och minska värdet i stencilbufferten där dessa polygoner inte klarar djuptestet. Denna metod brukar kallas för z-fail metoden. Detta eftersom stencilbufferten uppdateras när skuggvolymspolygonerna inte klarar z-buffer testet. Heidmanns metod, som uppdaterar stencilbufferten när polygonerna klarar djuptestet, brukar kallas för z-pass metoden. Z-fail metoden går ut på att räkna antalet framside- och baksidepolygoner som korsas bakom objektet i fråga. Genom att räkna på detta sätt uppstår inga problem när kameran befinner sig inuti en skuggvolym, se figur 12. Som figur 13a visar ställer inte heller frontplanet till med några problem, detta eftersom endast skuggvolymspolygoner bakom det första objektet räknas. Tyvärr dyker det upp ett nytt problem, skuggvolymspolygonerna kan nu i stället klippas bort om de hamnar bakom vy-volymens bakplan. Som figur 13b visar flyttar Carmacks metod bara problemet från klippning mot frontplanet till klippning mot bakplanet. Everitt m.fl. [Everitt02] har beskrivit en lösning på detta problem. Genom att flytta bakplanet oändligt långt bort undviks problemet med att polygoner klipps bort. Denna modifikation gör skuggvolymalgoritmen till en robust algoritm som klarar av att generera korrekta skuggor oberoende av var kameran och frontplanet är placerat. Z-fail metoden har dock en nackdel jämfört med z-pass metoden. För att z-fail metoden skall fungera måste skuggvolymen helt inneslutas. Detta innebär att fler trianglar måste ritas ut för att begränsa volymen framtill och baktill (figur 12). Kamera Ljuskälla Volymbegränsning framtill Ljuskälla X Y D Skuggvolym Kamera X Y Skuggvolym Skuggvolym Skuggvolym A B +1, +1 C +1 Volymbegränsning baktill A +1 B +1 Figur 12: I z-fail algoritmen räknas endast de korsade skuggvolymspolygoner som ligger bakom objektet i fråga. Som figuren till höger visar fungerar z-fail algoritmen även när kameran befinner sig inuti en skuggvolym. När z-fail algoritmen används måste skuggvolymen även begränsas framtill och baktill, detta innebär att fler polygoner måste ritas ut. Hornus m.fl. [Hornus05] presenterade nyligen en algoritm som bygger på z-pass algoritmen, men som inte lider av de problem som frontalplanet ger upphov till. Deras algoritm utför ytterligare ett renderingspass som initierar stencilbufferten. Detta initierande renderingspass uppdaterar stencilbufferten för att kompensera för de polygoner som klipps bort av frontplanet. Därefter används z-pass metoden som den beskrivits ovan, Hornus m.fl. kallar därför algoritmen för ZP+ (z-pass plus). 14

21 Skuggalgoritmer Ljuskälla Ljuskälla Kamera X Y Kamera X Y Skuggvolym Skuggvolym Skuggvolym Skuggvolym A B +1 A B a) +1 b) +1 Figur 13 a): Med z-fail algoritmen fås inga problem med att frontplanet klipper bort delar av skuggvolymspolygonerna. b): Bakplanet kan dock ställa till med problem i z-fail algoritmen. Punkt B i figuren, som skuggas av objekt Y, kommer enligt z-fail algoritmen inte befinna sig i skugga. Anledningen till detta är att bakplanet klipper bort delar av skuggvolymens polygoner. Det initierande renderingspasset renderas med kameran placerad på ljuskällans position. Bakplanet för denna vy sätts till att vara samma som frontplanet för den ursprungliga kamerans vy. Frontplanet, som är parallellt med bakplanet, väljs så att inga objekt befinner sig mellan ljuskällan och frontplanet. Figur 14 illustrerar vy-volymen för detta renderingspass. Objekten i scenen renderas sedan och uppdaterar stencilbufferten. Ljuskälla Vy-volym som används under initieringspasset Kamera X Y +1 Skuggvolym Skuggvolym +1-1 Detta område kommer att initieras till 1 i stencilbufferten Figur 14: Till vänster visas den vy-volym som används för att initiera stencilbufferten. Efter att objekten har renderats, kommer det markerade området att innehålla värdet 1 i stencilbufferten. Till höger visas samma scen som i figur 11, där visades hur z-pass algoritmen inte renderade punkt B på rätt sätt. Med initieringssteget i ZP+ algoritmen kommer stencilvärdet för den pixel punkt B projiceras på att innehålla 1 innan z-pass algoritmen tar vid. Z-pass algoritmen noterar sedan en framsidepolygon (+1) och en baksidepolygon (-1). Stencilbufferten kommer efter detta att innehålla värdet 1, vilket innebär att punkten befinner sig i skugga. A B 15

22 Skuggalgoritmer Författarna jämför även denna algoritm med z-fail algoritmen, som annars är den algoritm som används vid robust skuggvolymrendering. Som nämnts ovan behövs fler polygoner renderas med z-fail algoritmen, detta för att begränsa skuggvolymen framtill och baktill. Likt z-fail algoritmen renderar även ZP+ algoritmen begränsningen framtill. Detta sker under initieringspasset. ZP+ algoritmen behöver däremot inte rendera någon bakre begränsning på skuggvolymen, eftersom z-pass algoritmen används. Hornus m.fl. noterar även att begränsningen framtill endast renderas för de objekt som hamnar inom den vy-volym som skapas. Vid z-fail algoritmen renderas begränsningen framtill för samtliga objekt som befinner sig inuti den ursprungliga vy-volymen. Denna ursprungliga vy-volym är oftast mycket större än vy-volymen i ZP+, vilket innebär att fler polygoner behöver renderas med z-fail algoritmen. ZP+ algoritmen kan dock ge upphov till sprickor i skuggorna. Detta visar sig genom att vissa pixlar blir belysta trots att de egentligen befinner sig i skugga. Anledningen till detta är att hårdvarans begränsade aritmetiska precision ger upphov till numeriska fel när de två olika vyvolymerna används. Författarna beskriver en lösning som åtgärdar dessa sprickor. I vissa fall måste de dock använda sig av z-fail algoritmen för att undvika artefakterna. Konstruktion av skuggvolym Som nämndes ovan kan skuggvolymen konstrueras på olika sätt. Vilken metod som används för att skapa skuggvolymen kan ha stor inverkan på hur snabbt skuggvolymalgoritmen exekverar. Den metod som Crow föreslog, och som beskrevs ovan, är inte speciellt effektiv. För det första måste varje objekts siluettkanter letas fram. Detta är en relativt kostsam process eftersom varje kant och dess angränsande polygoner måste undersökas. Då dessa siluettkanter sedan skall användas för att skapa nya polygoner måste dessa operationer utföras på centralprocessorn. Detta eftersom dagens grafikhårdvara inte klarar av att skapa nya godtyckliga polygoner 2. I en scen innehållande komplexa objekt, bestående av tiotusentals polygoner, kommer centralprocessorn att bli hårt belastad. Vad som är ännu värre med Crows metod är att när polygonerna väl skapas kommer dessa att begränsas mot vy-volymens utsträckning, som illustrerades i figur 7. Denna operation är kostsam och utförs även den på centralprocessorn. Crows metod är därför inte speciellt användbar för att skapa skuggor i realtid på dagens grafikhårdvara. När Heidmann beskrev hur stencilbufferten kan användas för att implementera skuggvolymalgoritmen, använde han en annan metod för att skapa skuggvolymen. Heidmann valde att skapa en skuggvolym för varje polygon i varje objekt. Alla dessa skuggvolymer dras sedan ut så långt att de täcker in alla objekt i scenen. Även om denna metod undviker båda de kostsamma operationerna ovan, söka efter siluettkanter och begränsa polygoner mot vyvolymen, är den inte speciellt effektiv. Eftersom varje polygon skapar en skuggvolym, kommer varje polygon ge upphov till tre nya polygoner. Detta innebär inte bara att grafikhårdvaran måste rendera fler polygoner, utan centralprocessorn måste även arbeta med att skapa alla dessa polygoner och föra över de till grafikhårdvarans minne. Värt att notera är också att i och med att Heidmann inte begränsar polygonerna till vy-volymen uppstår problem med att polygoner klipps bort av frontplanet. När detta inträffar uppstår de problem som beskrivs i figur 11. Den stora nackdelen med Heidmanns metod är att den skapar många nya polygoner. Flera författare [Everitt02, McGuire03] beskriver en ny metod där de kombinerat idéer från Crow och Heidmann för att minska antalet polygoner. Metoden börjar med att leta fram objektets siluettkanter, likt Crows metod. Därefter används endast dessa kanter för att skapa polygonerna som omsluter skuggvolymen. Skuggvolymen sträcks sedan ut till oändligheten bort från ljuskällan. I och med detta behövs inte den kostsamma vy-volymbegränsningen 2 Modern grafikhårdvara klarar visserligen av att skapa ny geometri i samband med mjuka ytor, vilket innebär att en triangel delas upp i flera mindre trianglar för att skapa en mjukare yta. Detta handlar dock inte om några godtyckliga polygoner vilket är vad som krävs för att skapa skuggvolymer. 16

23 Skuggalgoritmer utföras. McGuire m.fl. [McGuire03] beskriver vidare hur vertex shaders kan användas för att flytta de bakre hörnen oändligt långt bort från ljuskällan. Genom att utföra detta på grafikhårdvaran behöver inte centralprocessorn beräkna och föra över dessa positioner till grafikhårdvarans minne. När z-fail algoritmen används måste skuggvolymen även begränsas framtill och baktill. Baktill kan skuggvolymen begränsas genom att återanvända de bakre hörnen på skuggvolymspolygonerna. För att skapa begränsningen framtill används de polygoner på det skuggkastande objektet som är riktade mot ljuskällan. De metoder som beskrivits ovan har alla involverat centralprocessorn på ett eller annat sätt när skuggvolymen skapas. När komplexa objekt, innehållande massvis med hörn, skall behandlas, vore det bra om grafikhårdvaran i stället för centralprocessorn används för att skapa skuggvolymen. Anledningen till detta är att modern grafikhårdvara är parallelliserad, och kan därför arbeta på flera hörn samtidigt. Everitt och Kilgard [Everitt03] beskriver hur en enkel vertex shader kan användas för att skapa en skuggvolym. Vad vertex shadern gör är att beräkna skalärprodukten mellan hörnets normalvektor och vektorn riktad mot ljuskällan. Om skalärprodukten är större än eller lika med noll, vilket innebär att hörnets normalvektor är riktat mot ljuskällan, avslutas shadern. Om skalärprodukten är mindre än noll, vilket innebär att hörnets normalvektor är riktat bort från ljuskällan, flyttas hörnet bort från ljuskällan (figur 15a). Dessa hörns normalvektorer är riktade bort från ljuskällan och kommer därför att flyttas. a) Skillnad mellan en riktig skuggvolym, och volymen som skapas med den beskrivna metoden b) Figur 15 a): Hörn, vars normaler är riktade bort från ljuskällan, kommer att flyttas i riktning bort från ljuskällan och därmed skapa skuggvolymen. b): Skuggvolymen som skapas med denna metod kan dock skilja sig ganska mycket från den riktiga skuggvolymen. Som figur 15b visar fungerar dock inte denna metod speciellt bra. Everitt och Kilgard nämner att detta beror på att metoden bara tar hänsyn till hörnets riktning. När skuggvolymerna skapas bör hänsyn tas till hur polygonerna är riktade. Detta kan åstadkommas genom att för varje hörn skapa ett nytt hörn på samma position [Everitt03, Kwoon]. Normalen på dessa hörn sätts till att vara samma som för de angränsande polygonerna, hörnen kopplas även samman med en ny polygon (figur 16a). Därefter kan samma vertex shader som beskrevs ovan användas för att skapa skuggvolymen (figur 16b). Denna metod skapar korrekta skuggvolymer, med begränsning både framtill och baktill, endast genom att använda grafikhårdvaran. Det stora problemet med metoden är att den skapar mycket extra geometri genom att lägga till nya hörn. 17

24 Skuggalgoritmer a) b) Figur 16 a): För varje hörn skapas ett nytt hörn, det nya hörnet kopplas samman med det gamla hörnet. Hörnens normaler sätts till normalen för de angränsande polygonerna. b): Om den ovan beskrivna vertex shadern används på dessa nya objekt kommer skuggvolymen som skapas att vara korrekt. Vilken av de två metoderna, den som endast använder grafikhårdvaran eller den som använder centralprocessorn för att leta reda på siluettkanter, som är snabbast varierar från scen till scen [Kwoon]. Därför är det svårt att på förhand avgöra vilken metod som bör användas. Brabec och Seidel [Brabec03-1] har föreslagit en ny metod för att generera skuggvolymer endast genom att använda grafikhårdvaran. De nämner att en metod som helt exekverar på grafikhårdvaran har ett antal fördelar över en hybridmetod som använder sig av både centralprocessorn och grafikhårdvaran. För det första är dagens grafikhårdvara programmerbar genom vertex och pixel shaders. När vertex shaders används för att beräkna nya positioner för hörnen, uppstår problem med hybridmetoden. Hörnens positioner måste vara kända för att centralprocessorn skall kunna leta fram siluettkanterna. Detta innebär att centralprocessorn måste simulera dessa vertex shaders för att få reda på positionen. Dagens vertex shaders kan exekvera tusentals instruktioner, och det kommer krävas mycket beräkningskraft från centralprocessorn om den skall simulera dessa shaders. Ett annat problem med hybridmetoden är att precisionen på beräkningarna kan vara olika på olika hårdvara, här centralprocessor och grafikhårdvara. Detta kan ge upphov till visuella artefakter. Metoden som Brabec och Seidel föreslår använder sig av texturer för att lagra delresultat. Den första texturen lagrar alla hörns positioner, den andra texturen lagrar information om alla kanter. Metoden består av tre delar: 1. En vertex shader används för att beräkna hörnens positioner. Dessa positioner sparas i en textur där varje pixel motsvarar ett hörn. 2. En pixel shader och texturen som skapades i steg 1 används för att för varje kant avgöra om det är en siluettkant eller inte. Resultatet sparas i en ny textur där varje pixel motsvarar en kant. 3. En vertex shader och texturerna som skapades i steg 1 och steg 2 används i detta steg. Vertex shadern avgör om de fyrhörningar (som i förväg skapats för varje kant) skall dras ut till oändligheten (dvs. skapa skuggpolygonen) eller flyttas ut ur vy-volymen (dvs. inte renderas). När metoden beskrevs kunde inte steg 3 implementeras helt på grafikhårdvaran. Detta eftersom de vertex shader-modeller som hårdvaran hade stöd för då inte kunde läsa från texturer. Detta löstes genom att låta centralprocessorn läsa in data från texturerna och 18

25 Skuggalgoritmer vidarebefordra denna till vertex shadern. Den senaste vertex shader modellen, vs 3.0, innehåller dock en instruktion för att läsa från texturer, därmed bör denna algoritm kunna exekvera helt på grafikhårdvaran. En stor nackdel med metoden är att den inte skapar någon begränsning framtill och baktill på skuggvolymen. Detta innebär att metoden måste kompletteras för att kunna användas i samband med z-fail algoritmen. Samtliga metoder som beskrivits ovan och som använder sig av ett objekts siluettkanter, har förlitat sig på samma algoritm för att hitta dessa siluettkanter. Nämligen genom att titta på de två polygoner som angränsar till en kant. Om ena polygonens normal är vänd mot ljuskällan och den andra polygonens normal är vänd bort från ljuskällan är kanten en siluettkant. Denna algoritm sätter dock vissa begränsningar på vilka polygonobjekt som kan användas. Aldridge och Woods [Aldrid04] noterar speciellt att i de objekt som används måste varje kant angränsa till exakt två polygoner. Det händer dock att objekt ibland innehåller kanter som angränsar till endast en polygon, detta är fallet om objekten innehåller hål. Även objekt med kanter som angränsar till fler än två polygoner förekommer. Aldridge och Woods har därför föreslagit en algoritm som hanterar även dessa objekt. Algoritmen skapar en räknare för varje kant. Därefter undersöks varje kant i varje polygon. Om kantens hörn är definierade i samma ordning som hörnen för polygonen ökas räknaren, annars minskas räknaren. När samtliga polygoner undersökts innehåller siluettkanternas räknare ett positivt eller negativt värde. Kanter som inte är siluettkanter innehåller värdet noll. Räknaren talar även om hur många skuggpolygoner som måste skapas för kanten, detta innebär att även kanter med fler än två angränsande polygoner kan hanteras. Optimeringar Kostnaden för att generera skuggor med skuggvolymalgoritmen kan delas upp i två delar. Den ena delen innefattar kostnaden för att skapa skuggvolymen. Det vill säga kostnaden för att hitta siluettkanter, skapa skuggpolygonerna och föra över data till grafikhårdvaran. Den andra delen omfattar kostnaden för att rendera alla skuggpolygoner. För varje pixel som täcks av en skuggpolygon utförs ett djuptest, för många pixlar uppdateras även stencilbufferten. Eftersom skuggpolygonerna ofta täcker stora delar av scenen innebär detta att många pixlar kommer att uppdateras. Figur 17 visar en enkel scen som är dyr att rendera med skuggvolymalgoritmen. Ljuskälla Skuggvolym Kamera Figur 17: Denna scen innehåller fem pelare som kastar skuggor i scenen. Notera att om z-pass algoritmen används skulle varje pixel behöva uppdateras för varje framside- och baksidepolygon. Detta trots att det enda synliga objektet i scenen, rektangel, inte befinner sig i skugga. 19

26 Skuggalgoritmer I detta avsnitt kommer jag att presentera idéer som framförts för att minska kostnaderna i skuggvolymalgoritmen. Everitt och Kilgard [Everitt02] noterar att om riktat ljus (där samtliga ljusstrålar är parallella) används, förenklas skuggvolymen om z-fail algoritmen används. Detta eftersom samtliga siluetthörn kommer att projiceras till samma punkt vid oändligheten. Därmed behövs ingen bakre begränsning av skuggvolymen. Vidare kommer sidopolygonerna endast att bestå av trianglar och inte fyrhörningar vilket är det vanliga fallet. McGuire m.fl. [McGuire03, McGuire04] har presenterat ett flertal idéer för att optimera skuggvolymalgoritmen. För det första noterar de att intensiteten på ljuset från punktljuskällor avtar med avståndet från ljuskällan. Efter ett visst avstånd kommer intensiteten att vara försumbar. För objekt som befinner sig på detta avstånd eller längre bort behövs inga skuggvolymer skapas. Vidare kan skuggvolymer, för objekt som befinner sig närmare ljuskällan, begränsas till detta avstånd, vilket gör skuggvolymerna mindre och kan därmed minska antalet uppdaterade pixlar. Dessa optimeringar kan även appliceras på objekt och skuggvolymer som hamnar utanför ljuskonen från en spotlight. McGuire m.fl. nämner även att z- pass algoritmen bör användas, i stället för z-fail algoritmen, i de fall det är möjligt. Detta eftersom z-pass algoritmen inte kräver att begränsningarna framtill och baktill på skuggvolymen renderas. Ett enkelt test med omslutande volymer kan användas för att avgöra om z- pass eller z-fail algoritmen skall användas. Även grafikhårdvaran har utvecklats för att göra implementeringen av skuggvolymalgoritmen mer effektiv. För det första har de flesta moderna grafikkort stöd för dubbelsidigt stenciltest [Everitt02]. Detta innebär att en viss stencilfunktion kan utföras på polygoner som är riktade mot kameran, medan en annan funktion kan utföras på polygoner som är riktade bort från kameran. Detta innebär att skuggvolymerna bara behöver renderas en gång, och inte två gånger som beskrevs ovan (steg 3-4). Modern grafikhårdvara tar även vara på att uppdateringen av stencilbufferten inte kräver någon texturering av objekt eller uppdatering av färgbufferten. Därför kan vissa grafikkort rendera scener som endast uppdaterar stencilbufferten nästan dubbelt så snabbt [Nvidia05-1]. Vidare kan så kallade depth bounds användas för att begränsa inom vilket djupintervall skuggor kan uppstå. Detta innebär att stencilbufferten inte behöver uppdateras om motsvarande pixel befinner sig utanför djupintervallet. Lloyd m.fl. [Lloyd04] föreslår en algoritm som rejält kan minska antalet pixlar som behöver uppdateras när skuggpolygonerna renderas. Deras algoritm består av två delar. Den första delen av algoritmen plockar bort alla objekt som inte bidrar till några skuggor i den renderade bilden. För dessa bortplockade objekt behövs inga skuggvolymer skapas. Detta skär ner kostnaden både för skapandet och renderingen av skuggvolymerna. Figur 18 visar exempel på objekt som kan plockas bort. Denna del implementeras genom två extra renderingspass med tillhörande occlusion query-pass 3 av objektens omslutande volymer. Ett av dessa pass renderas ur ljuskällans synvinkel. Den andra delen av algoritmen begränsar skuggvolymernas utsträckning. Som figur 19 visar behövs egentligen bara delar av skuggvolymerna renderas. Den andra delen av algoritmen letar rätt på dessa delar och ser till att endast de renderas. Detta kan spara många pixeluppdateringar eftersom de mindre delarna täcker ett mindre antal pixlar på den renderade bilden. Lloyd m.fl. kallar algoritmen CC skuggvolymer, där CC (culling and clamping) kommer från de funktioner algoritmens två delar utför. 3 I ett occlusion query-pass undersöks hur många pixlar som skulle uppdateras om ett objektet skulle renderas med den aktuella djupbufferten [Ext03]. 20

27 Skuggalgoritmer Ljuskälla B A F Kamera D C E Figur 18: Objekt A kastar inte någon skugga på något objekt inom vy-volymen, dess skuggvolym behövs därför inte. Detsamma gäller för objekt E. Objekt C befinner sig redan helt i skugga, dess skuggvolym bidrar inte med någon ny information och behövs därför inte. Skuggvolymerna för objekt B, D och F behövs fortfarande. Ljuskälla B F Kamera D Figur 19: Endast vissa delar av skuggvolymerna behöver renderas. De heldragna linjerna visar de delar av skuggvolymerna som måste renderas. Notera att dessa volymer bara täcker en liten del av kamerans synfält. Skuggvolymalgoritm för mjuka skuggor Som tidigare nämnts kan den ovan beskrivna skuggvolymalgoritmen användas för att skapa mjuka skuggor. De mjuka skuggorna åstadkoms genom att rendera flera hårda skuggor, med ljuskällans position ändrad lite för varje hård skugga. Därefter beräknas medelvärdet av alla dessa hårda skuggor per pixel för att skapa de mjuka skuggorna. Denna metod är inte speciellt användbar i realtidssammanhang eftersom medelvärdet av många hårda skuggor krävs för ett bra resultat. Assarsson m.fl. [Assar03-1] rapporterar att antalet renderingspass med hårda skuggor som krävs ligger någonstans mellan 256 och Assarsson m.fl. [Assar03-1, Assar03-2] presenterar därför en ny algoritm som kan rendera mjuka skuggor i realtid. Deras algoritm bygger vidare på skuggvolymalgoritmen. Den ursprungliga algoritmen använder sig av en skuggpolygon (figur 7) för att per pixel avgöra om en punkt befinner sig i skugga eller är fullt belyst. Assarsson m.fl. använder sig i stället av 21

28 Skuggalgoritmer en kil (figur 20), inom denna kil varierar ljusintensiteten beroende på hur stor del av ljuskällan som kan ses. Assarsson m.fl. föreslår följande tre steg för att rendera mjuka skuggor: 1. Rendera scenen med endast matt ljus och highlights påslaget, detta uppdaterar z- bufferten och färgbufferten. 2. Beräkna hur stor del av ljuskällan varje punkt ser och lagra detta i V-bufferten (Visibility Buffer). Multiplicera därefter innehållet i färgbufferten med innehållet i V- bufferten. 3. Rendera scenen med endast allmänljus och emitterat ljus påslaget och addera detta till färgbufferten. V-bufferten är ett nytt begrepp Assarsson m.fl. introducerar. V-bufferten har samma storlek som färgbufferten. Varje pixel i V-bufferten motsvarar en punkt i scenen på samma sätt som för färg- och z-bufferten. Det värde, v, som lagras i V-bufferten är ett mått på hur stor del av ljuskällan motsvarande punkt i scenen kan se. Om punkten kan se hela ljuskällan har v värdet 1, om punkten helt befinner sig i skugga har v värdet 0. Om punkten kan se en del av ljuskällan innehåller v ett värde som motsvarar hur stor del av ljuskällan som kan ses från punkten. Ljuskälla Siluettkant Skuggpolygon Ljuskälla Siluettkant Kil a) b) Figur 20 a): Figuren visar skuggpolygonen som används i den ursprungliga skuggvolymalgoritmen. b): Figuren visar den kil som Assarsson m.fl. använder sig av för att skapa mjuka skuggor. Värdena i V-bufferten beräknas i två pass. Det första passet fungerar på samma sätt som den ursprungliga skuggvolymalgoritmen. V-bufferten initieras till värdet 1, därefter renderas skuggpolygonerna. På de pixlar där en framsidepolygon renderas, subtraheras 1 från V- bufferten. Där en baksidepolygon renderas adderas 1 till V-bufferten (figur 21). I det andra passet renderas en kil för varje siluettkant. Renderingen utförs genom att rendera framsidepolygonerna för denna kil. För de pixlar som uppdateras exekveras en pixel shader. Denna pixel shader avgör först om punkten som renderas befinner sig inuti kilen. Om så inte är fallet skall V-bufferten inte uppdateras. Om punkten befinner sig inuti kilen är det möjligt att värdet i V-bufferten skall justeras. Som figur 21 visar delar skuggpolygonen upp kilen i två delar. Om punkten befinner sig i den inre delen, inuti kilen och i skugga enligt skuggvolymalgoritmen, beräknas hur stor del av ljuskällan som kan ses från punkten. Detta värde adderas sedan till V-bufferten. Kom ihåg att första passet ansåg att denna punkt befann sig helt i skugga, det vill säga V-buffertens värde är 0. Nu adderas ett värde till V-bufferten, vilket innebär att en del av ljuset når punkten. Om punkten i stället befinner sig i den yttre delen av kilen, inuti kilen men inte i skugga enligt skuggvolymalgoritmen, beräknas hur stor del av ljuskällan som skyms av siluettkanten. Detta värde subtraheras sedan från V-bufferten. Första passet ansåg att denna punkt skulle vara fullt belyst. Det andra passet kan dock justera detta värde om det visar sig att en del av ljuskällan är skymd. Assarsson m.fl. rapporterar att de mjuka skuggor som genereras av algoritmen håller hög kvalitet, ofta jämförbart med 1024 pass i den flerpassteknik som beskrevs ovan. De hävdar även att den håller realtidsprestanda med bildhastigheter på 150 bilder per sekund för enkla scener. 22

29 Skuggalgoritmer Ljuskälla a) Kil Skuggpolygon Yttre del av kil Inre del av kil A B C D 1 b) 0 Figur 21 a): Kilar används för att skapa skuggor med mjuka kanter. För punkt C och D fungerar algoritmen på samma sätt som skuggvolymalgoritmen. Strålen som når punkt C har korsat en framsidepolygon, V-bufferten innehåller därför värdet 0.0. Strålen som når punkt D har korsat en framsidepolygon och en baksidepolygon, V-bufferten innehåller därför värdet 1.0 vid punkt D. Punkt A befinner sig i den yttre delen av kilen. Därför beräknas hur stor del av ljuskällan som skyms av objektet, detta värde subtraheras sedan från V-bufferten. Punkt B befinner sig i den inre delen av kilen. Därför beräknas hur stor del av ljuskällan som kan ses från punkten, detta värde adderas sedan till V-bufferten. b): Figuren visar värdet i V-bufferten. Algoritmen kan i vissa fall generera skuggor som inte är helt korrekta. För det första kan det uppstå problem när två objekt kastar skuggor på samma punkt. Det kan då hända att en punkt inte får så mycket ljus som den bör få. Anledningen till detta är att algoritmen antar att objekten i scenen inte överlappar varandra (figur 22). För det andra kan det uppstå problem eftersom ett objekts siluettkanter sett från ljuskällan kan vara olika beroende på var på ljuskällan man befinner sig. Algoritmen bestämmer alltid siluettkanterna sett ifrån ljuskällans mitt. Ljuskälla A B Figur 22: Figurerna visar hur den punkt som renderas ser ljuskällan. Till vänster visas ett fall som algoritmen kommer att behandla på rätt sätt. Först kommer den del av ljuskällan som skyms av objekt A att subtraheras från V-bufferten. Därefter subtraheras den del av ljuskällan som skyms av objekt B. Om situationen som visas till höger uppstår kommer samma beräkningar som för vänstra figuren att äga rum. Här kommer en skymd del av ljuskällan att subtraheras två gånger (den del som skyms av båda objekten), vilket gör att punkten kommer att belysas för lite. 23

30 Skuggalgoritmer Assarsson m.fl. hävdar dock att effekten av dessa problem kan minskas genom att dela upp en ljuskälla i flera delar. Oftast uppnås goda resultat med en uppdelning i 2x2 eller 3x3 delar [Assar03-2]. Shadow map-algoritmer Inledning År 1978 föreslog Williams [William78] en ny algoritm för att generera skuggor. Vad Williams föreslog var att z-bufferten kan användas för att generera skuggor. Algoritmen består av två steg: 1. Rendera scenen med kameran placerad på ljuskällans position. Vid renderingen behövs endast z-bufferten uppdateras. Ljusberäkningar och uppdatering av färgbufferten kan därför stängas av, vilket snabbar upp renderingen. Resultatet av detta steg är en z-buffert som innehåller avstånden till de objekt i scenen som befinner sig närmast ljuskällan. 2. Rendera scenen med kameran placerad på sin normala position. För varje punkt som renderas, jämför punktens avstånd till ljuskällan med det avstånd som finns lagrat z- bufferten från steg 1 (figur 23). Detta åstadkoms genom att transformera punkten med samma transformationsmatris som användes i steg 1. Resultatet av denna operation är koordinaterna (x, y, z) för punkten i screen space när scenen beskådas ur ljuskällans synvinkel. (x, y) koordinaterna kan användas för att hämta det z värde som finns lagrat i z-bufferten. Om z < z finns det en punkt som ligger närmare ljus-källan än punkten i fråga. Detta innebär att punkten befinner sig i skugga och skall då endast belysas med allmänljus och emitterat ljus. Om z z skall punkten även belysas med matt ljus och highlights påslaget. Ljuskälla Avstånd lagrat i z-buffert Avstånd mellan punkt och ljuskälla A Kamera Figur 23: För punkt A är avståndet till ljuskällan samma som det avstånd som är lagrat i z- bufferten, punkten är därför belyst. För punkt B är avståndet till ljuskällan större än det avstånd som är lagrat i z-bufferten, punkten befinner sig därför i skugga. Algoritmen är lätt att implementera på modern grafikhårdvara. Z-bufferten som skapas i steg 1 är precis likadan som den z-buffert som skapas för alla andra scener. Transformationerna och jämförelserna i steg 2 kan implementeras med en pixel shader eller genom hårdvarustöd på modern grafikhårdvara. Av de två ovan beskrivna stegen, är steg 2 betydligt dyrare än steg 1. Detta eftersom en transformation och en jämförelse måste utföras för varje punkt som renderas. Detta gäller även punkter som renderas och som sedan skrivs över av objekt som befinner sig närmare kameran. Williams föreslog att steg 2 kunde utföras som en efterprocess. Efter att scenen renderats med full belysning utförs transformation och jämförelse endast för de punkter som syns från kameran. Om en punkt befinner sig i skugga görs motsvarande pixel mörkare. Detta snabbar upp steg 2, men kan också innebära att områden i skugga innehåller highlights. En B 24

31 Skuggalgoritmer annan liknande metod är att använda ett initierande z-bufferpass. Ett initierande z-bufferpass är ett renderingspass där endast z-bufferten uppdateras. Därefter renderas scenen igen och steg 2 utförs. I det andra renderingspasset renderas endast de pixlar vars djupvärde överrensstämmer med det värde som finns lagrat i z-bufferten, det vill säga att endast de pixlar som verkligen syns renderas. Ljus i flera riktningar Den ursprungliga algoritmen klarar bara av ljuskällor som sprider ljus i ett begränsat område. Detta beror på att steg 1 renderar scenen utifrån ljuskällans synvinkel, vilket innebär att bara en del av scenen kommer renderas. Endast denna del av scenen kommer att innehålla skuggor. Om en scen innehåller en ljuskälla som sprider ljus i alla riktningar måste algoritmen utvidgas. Williams föreslår att ljuskällans omgivning delas upp i sektorer. Steg 1 skapar sedan en z-buffert för varje sådan sektor. Steg 2 väljer vilken av dessa z-buffertar som skall användas beroende på var i scenen ett objekt befinner sig. Gerasimov [Gerasi04] beskriver hur en cube map kan användas för att dela upp omgivningen i sex sektorer, de sex sidorna av en kub. För att skapa denna cube map placeras kameran på ljuskällans position. Omgivningen renderas därefter i sex pass, med ett 90-gradigt synfält och med riktningar som motsvarar kubens sidor. Notera att vid uppslagning i denna cube map behöver inte punkten som renderas transformeras med ljuskällans transformationsmatris, utan endast vektorn från ljuskällan till punkten behövs för att slå upp rätt värde. Denna vektor finns ofta redan uträknad, eftersom den används vid belysningsberäkningarna. Brabec m.fl. [Brabec02-1] noterar att det är dyrt att uppdatera denna cube map för varje bild som renderas, eftersom scenen måste renderas sex gånger. De föreslår att en annan metod som används inom environment mapping bör användas, nämligen paraboloid mapping. Paraboloid mapping har fördelen att kunna representera hela omgivningen med endast två texturer, vilket innebär att scenen endast behöver renderas två gånger. Om det är en taklampa som modelleras, som endast sprider ljus i en halvsfär, räcker det med en paraboloid map. Aliasing Visuella artefakter kan uppstå när shadow map-algoritmen används. För det första kan objekten skugga delar av sig själva, även delar som egentligen belyses av ljuskällan. För det andra kan skuggkanterna få ett hackigt utseende. Dessa problem uppstår på grund av att scenen samplas med ett för lågt antal samplingspunkter i steg 1. Figur 24 visar varför objekten ibland skuggar sig själva. Detta beror på att två punkter som befinner sig nära varandra hamnar inom samma pixel i z-bufferten. På grund av detta kommer djupvärdet som samplades i steg 1 inte stämma överens med det djupvärde som samplas i steg 2. Ljuskälla Avstånd lagrat i z-buffert En pixels utsträckning i z-bufferten Avstånd mellan punkt och ljuskälla Kamera A B Figur 24: Punkt A är den punkt som samplas i steg 1, dess avstånd lagras i z-bufferten. När punkt B renderas hamnar den inom samma pixel som punkt A i z-bufferten. Eftersom avståndet till punkt B är större än avståndet lagrat i z-bufferten bedöms punkten vara i skugga, självskuggning har uppstått. 25

32 Skuggalgoritmer Williams löste detta problem genom att subtrahera ett konstant värde från den transformerade z-koordinaten. Detta får till följd att punkten flyttas närmare ljuskällan och därför inte längre befinner sig i skugga. Det är dock inte helt trivialt att välja värdet på konstanten. Är konstanten för liten kan objekten fortfarande skugga sig själva. Är konstanten för stor kan skuggkanterna flyttas. Problemet med självskuggning kan även uppstå på grund av z- buffertens begränsade precision. En 8-bitars z-buffer kan till exempel bara skilja mellan 256 (2 8 ) olika djupvärden. Problemet med hackiga skuggkanter beror även det på z-buffertens begränsade upplösning. Z- buffertens upplösning begränsar antalet samplingspunkter i ljuskällans synfält. Detta kan innebära att delar av scenen som upptar hela kamerans synfält, bara upptar några få pixlar i ljuskällans synfält (figur 25). Detta problem är svårare att rätta till. Ett förslag är att öka z- buffertens upplösning, genom detta ökas antalet samplingspunkter. Detta löser dock inte problemet. Om kameran flyttas närmare skuggkanten uppstår de hackiga skuggkanterna igen. a) b) Figur 25 a): Om kameran flyttas närmare skuggkanten får den ett hackigt utseende. b): Denna figur visar z-bufferten som skapas från kamerans synfält. De hackiga skuggkanterna beror på att den delen kameran ser bara tilldelas ett fåtal pixlar i z-bufferten (det inringade området). Reeves m.fl. [Reeves87] minskar effekten av de hackiga skuggkanterna genom att använda ett filter över ett antal pixlar i z-bufferten. Den ursprungliga shadow map-algoritmen jämför en punkts avstånd till ljuskällan med endast ett värde i z-bufferten. Nämligen värdet på den pixel punkten hamnar inom när den transformerats till ljuskällans synfält. Reeves m.fl. föreslår att även de kringliggande pixlarna bör undersökas. Det är här viktigt att först utföra djupjämförelserna och därefter filtrera resultatet. Djupjämförelserna utförs för varje pixel inom det område som skall filtreras. Om punktens avstånd till ljuskällan är större än det avstånd som lagras i z-bufferten blir resultatet 0 (skuggad), annars 1 (belyst). Dessa värden är sedan de som filtreras. Reeves m.fl. kallar metoden för Percentage closer filtering (PCF). Effekten av att använda PCF är att skuggkanterna blir suddiga och kantigheten uppträder därmed inte lika tydligt. För att bestämma storleken på filtret som används beräknar Reeves m.fl. den renderade pixelns utbredning på z-bufferten. Denna operation är kostsam och lämpar sig därför inte speciellt bra i realtidssammanhang. Brabec och Seidel [Brabec01] och även Bunell och Pellacini [Bunell04] använder sig i stället av ett filter med konstant storlek. Detta ger både ett bra resultat och gör att filtreringen kan implementeras effektivt. 26

33 Skuggalgoritmer Uralsky [Uralsky05] har presenterat en metod för att generera mjuka skuggor. Metoden använder sig av PCF för att skapa mjuka skuggkanter. Uralsky noterar att det behövs ett stort filter när PCF utförs om visuella artefakter i halvskuggområdena skall minskas. Att alltid använda ett stort filter är dyrt, eftersom det krävs många uppslagningar i z-bufferten för varje pixel som renderas. Uralsky utnyttjar villkorlig exekvering, som bekant finns tillgängligt på modern grafikhårdvara, för att endast använda detta stora filter för de pixlar som befinner sig i halvskuggområdet. Notera att pixlar som befinner sig helt i skugga eller som är helt belysta inte behöver ett stort filter. Detta eftersom samtliga djupjämförelser ger samma resultat i dessa två fall. Uralsky använder sig även av slumpen för att variera samplingen av z-bufferten mellan pixlarna som renderas. Detta leder till att de regelbundna artefakter som syntes tidigare, ersätts med brus. Eftersom vårt synsystem är mer förlåtande mot brus, resulterar detta i bilder som uppvisar mindre artefakter [Uralsky05]. Modifieringar av shadow map-algoritmen Perspective shadow map Shadow map-algoritmen lider som bekant av aliasing-problem som uppvisar sig i form av hackiga skuggkanter. Reeves m.fl. föreslog att flera pixlar i z-bufferten skulle undersökas och att resultatet från dessa undersökningar sedan skulle filtreras. Detta löser visserligen problemet med hackiga skuggor i den mening att skuggkanterna blir suddiga och därmed döljer hackigheter. Grunden till problemet finns dock kvar, den delen av scenen som kameran ser är för dåligt samplad utifrån ljuskällans synvinkel. Stamminger och Drettakis [Stamm02] föreslår en modifikation till shadow map-algoritmen med syftet att bättre sampla den delen av scenen kameran ser. De noterar att när kamerans perspektivtransformation appliceras på scenen blir objekt nära kameran större och objekt som befinner sig långt ifrån kameran blir mindre. Vad de föreslår är att även applicera denna transformation i steg 1, när z-bufferten skapas. Detta innebär att de stora objekten, som befinner sig nära kameran, kommer att täcka fler pixlar på z-bufferten. Det vill säga objekt nära kameran kommer att samplas bättre. Att bara implementera denna modifikation rakt av kräver inte speciellt mycket arbete. Tyvärr uppstår olika scenarier när ljuskällan transformeras, och dessa måste hanteras på olika sätt. Vidare uppstår även problem med objekt som befinner sig bakom kameran och kastar skuggor på delar av scenen som kameran ser. Även dessa situationer måste upptäckas och hanteras. Om dessa olika scenarier hanteras kan den modifierade algoritmen användas för att generera skuggor som ofta uppvisar betydligt mindre aliasing-effekter än den ursprungliga shadow map-algoritmen. Noteras bör även att genom att applicera den föreslagna modifikationen, blir skuggalgoritmen beroende av kamerans position. Detta innebär att en ny z-buffert måste skapas varje gång kameran förflyttar sig. I den ursprungliga shadow map-algoritmen behöver z-bufferten endast uppdateras när ljuskällan eller något objekt i scenen flyttats. Light space perspective shadow map Wimmer m.fl. [Wimmer04] noterar att perspective shadow map-algoritmen ger upphov till ett antal olika scenarier som måste hanteras på olika sätt. Detta leder till att implementeringen blir besvärlig. De noterar även att perspective shadow map-algoritmen ibland utför för dålig sampling på objekt som befinner sig långt bort ifrån kameran. De föreslår därför en ny metod för att skapa den perspektivtransformation som sedan appliceras i steg 1 av shadow map-algoritmen. Stamminger och Drettakis använde sig av kamerans perspektivtransformation, tyvärr ger denna transformation upphov till olika besvärliga fall när ljuskällan transformeras. Wimmer m.fl. föreslår i stället en metod som tar hänsyn till ljusets riktning när transformationen skapas. De ser även till att täcka in alla objekt som kan kasta skuggor. Genom att använda denna transformation uppstår inget av de besvärliga fallen som uppstår i perspective shadow map-algoritmen. 27

34 Skuggalgoritmer Deras transformation förbättrar även samplingen av objekt som befinner sig långt ifrån kameran. Detta på bekostnad av att objekt nära kameran inte samplas lika bra som i perspective shadow map-algoritmen, dock fortfarande bättre än shadow map-algoritmen. Trapezoidal shadow map Shadow map-algoritmen kan i vissa fall slösa bort stora delar av upplösningen på z-bufferten. Ett exempel är en stor scen innehållande en ljuskälla med ett stort synfält, som ser hela scenen. Om kameran bara kan se en del av denna scen kommer de objekt som kameran inte ser att renderas till z-bufferten i onödan. Brabec m.fl. [Brabec03-2] föreslår att den minsta rektangeln, i ljuskällans synfält, som omsluter de objekt som kameran ser skall beräknas. Endast objekten inom denna rektangel renderas till z-bufferten. Detta ger högre upplösning i z-bufferten för de objekt som verkligen kan ses från kameran. Martin och Tan [Martin04] bygger vidare på denna idé. I stället för en omslutande rektangel använder de sig av en trapets som omsluter vy-volymen. Anledningen till detta är att kamerans vy-volym, sett från ljuskällan, ofta har en form som liknar en trapets. Därefter skapas en transformationsmatris som transformerar denna trapets till en fyrkant. Denna transformationsmatris appliceras på scenen efter att ljuskällans vy- och projektionsmatriser har applicerats. Detta får till följd att det verkligen är den delen av scenen kameran ser som samplas av z-bufferten. Vidare förvränger transformationen scenen genom att objekt nära kameran blir större samtidigt som objekt långt ifrån kameran blir mindre, likt perspective shadow map algoritmen. Detta leder till att den begränsade z-buffert upplösningen används ännu mer effektivt. Figur 26 visar hur ljuskällan uppfattar scenen före och efter transformationen. a) b) Figur 26 a): Scenen från ljuskällans synvinkel, alla objekt är lika stora. b): Scenen från ljuskällans synvinkel efter transformation, notera att objekten här ändrar storlek. De stora objekten nära kameran kommer att uppta fler pixlar i z-bufferten och kommer därmed att samplas bättre. Shadow silhouette map Sen m.fl. [Sen03] har föreslagit en algoritm som bygger både på shadow map-algoritmen och på skuggvolymalgoritmen. De noterar att skuggvolymalgoritmen skapar skarpa skuggkanter som inte lider av de aliasing effekter shadow map-algoritmen uppvisar. Shadow mapalgoritmen däremot kräver betydligt mindre pixeluppdateringar än skuggvolymalgoritmen. Sen m.fl. föreslår en algoritm som i många fall uppvisar lika skarpa skuggkanter som skuggvolymalgoritmen men som inte använder mycket mer minnesbandbredd än shadow map- 28

35 Skuggalgoritmer algoritmen. Den nya algoritmen utvidgar shadow map-algoritmen genom att förutom z- bufferten även använda sig av en textur de kallar för en siluettkarta. Siluettkartan skapas genom att först, likt skuggvolymalgoritmen, leta fram alla siluettkanter i scenen sett ifrån ljuskällan. Dessa siluettkanter renderas till siluettkartan. Om en siluettkant går igenom en pixel i siluettkartan, lagras i pixeln koordinaterna för en punkt som ligger på siluettkanten och befinner sig inuti pixeln i fråga. Om flera siluettkanter går igenom samma pixel, kommer endast koordinaterna för en punkt på den senast renderade kanten att lagras. Siluettkartan förskjuts 0,5 pixlar i x- och y-led och läggs över z-bufferten (figur 27b). När z-bufferten och siluettkartan är skapade fortsätter algoritmen likt steg 2 i shadow mapalgoritmen. Varje punkt som renderas transformeras till ljuskällans synfält. I den ursprungliga shadow map-algoritmen används dessa transformerade koordinater för att slå upp ett djupvärde i z-bufferten. Den nya algoritmen slår i stället upp fyra djupvärden i z-bufferten, de fyra pixlar som är närmast punkten. Djupjämförelser utförs för var och en av dessa värden. Om samtliga jämförelser ger samma resultat, det vill säga att punkten befinner sig i skugga eller är belyst, renderas punkten enligt dessa jämförelser. Om jämförelserna visar olika resultat betyder det att en skuggkant finns någonstans mellan de värden som leder till skugga och de värden som leder till full belysning (figur 27a). I dessa fall används värdena i siluettkartan av en pixel shader för att räkna ut var dessa skuggkanter befinner sig. Därefter undersöks på vilken sida om skuggkanten punkten befinner sig innan den renderas (figur 27b). Z-buffert Punkt som renderas Z-buffert Punkt som renderas Siluettkarta Skuggkant a) b) Figur 27 a): Djupvärdet för punkten som skall renderas är 30. Endast djuptestet med den övre vänstra pixeln i z-bufferten placerar punkten i skugga. Eftersom punkten hamnar inom just denna pixel, skulle shadow map-algoritmen ha placerat punkten i skugga. b): Figuren visar siluettkartan utlagd över z-bufferten. De vita cirklarna visar de koordinater siluettkartan lagrar. En pixel shader används för att räkna ut var skuggkanten befinner sig. Eftersom punkten befinner sig på samma sida om skuggkanten som de tre värden som placerar punkten i ljus kommer punkten att renderas som om den är belyst. Som nämndes ovan kommer bara koordinaterna för en punkt på en av siluettkanterna att lagras i siluettkartan om flera siluettkanter går igenom samma pixel. Eftersom siluettkartan är en textur, som har en begränsad upplösning, finns det en stor chans att detta kommer att inträffa. Speciellt om scenen innehåller många siluettkanter eller om siluettkanterna befinner sig nära varandra. När detta inträffar kommer algoritmen inte att kunna återskapa de skuggkanter som inte lagras, vilket leder till visuella artefakter för vissa skuggkanter. Författarna noterar att algoritmen kan användas tillsammans med perspective shadow map-algoritmen för att bättre utnyttja texturernas begränsade upplösning. Penumbra map och smoothies Wyman och Hansen [Wyman03] har föreslagit en algoritm för att generera mjuka skuggor. Algoritmen utvidgar shadow map-algoritmen med en ny textur. Denna textur, halvskuggkartan (penumbra map), lagrar ljusets intensitet i de områden som befinner sig i halvskugga. Halvskuggkartan skapas, likt z-bufferten i shadow map-algoritmen, genom att placera kameran på ljuskällans position. Författarna noterar att om kameran placeras i mitten av ljuskällan, kommer kameran att se en del av det område som befinner sig i halvskugga 29

36 Skuggalgoritmer (figur 28). Det är detta område som renderas till halvskuggkartan, med ett lågt värde (0) nära den hårda skuggkanten och ett högt värde (1) nära halvskuggans yttre gräns. Halvskuggområdet renderas genom att skapa nya objekt som representerar området. Dessa objekt påminner mycket om de kilar som Assarsson m.fl. skapar i skuggvolymalgoritmen för mjuka skuggor. Wyman och Hansen skapar även koner för samtliga siluetthörn. Detta innebär att penumbra map-algoritmen måste leta fram siluettkanter likt skuggvolymalgoritmen. Ljuskälla Hård skuggkant Område som egentligen befinner sig helt i skugga Område som enligt algoritmen befinner sig helt i skugga Halvskuggområde kameran ser Hela halvskuggområdet Figur 28: Figuren visar ett objekt som belyses av en ljuskälla med en area. Penumbra mapalgoritmen klarar bara av att skapa det halvskuggområde kameran ser. Detta leder i sin tur till att det område som befinner sig helt i skugga blir för stort. När både z-bufferten och halvskuggkartan är skapade, renderas scenen utifrån kamerans normala position. För varje pixel som renderas utförs ett djuptest precis som i shadow mapalgoritmen. Om djuptestet visar att punkten befinner sig i skugga, renderas punkten på detta sett. Om djuptestet däremot visar att punkten är belyst, hämtas det värde som finns på motsvarande pixel i halvskuggkartan. Detta värde talar om hur mycket ljus som når punkten och används vid ljusberäkningarna. Oberoende av Wyman och Hansen utvecklade Chan och Durand [Chan03] en algoritm för att generera mjuka skuggor. Den Algoritm Chan och Durand beskriver, har många likheter med penumbra map-algoritmen. Algoritmen utvidgar shadow map-algoritmen med en ny textur, Chan och Durand kallar denna textur för smoothie-bufferten. Denna textur renderas, likt z- bufferten, med kameran placerad på ljuskällans position. Smoothie-bufferten lagrar avståndet från ljuskällan till de smoothies som skapas. En smoothie är en polygon som skapas för varje siluettkant och siluetthörn (figur 29). Storleken på en smoothie avgör hur stort halvskuggområdet kan bli. Smoothie-bufferten lagrar även, likt penumbra map-algoritmen, ljusets intensitet i de områden som befinner sig i halvskugga. Dessa intensitetsvärden beräknas av en pixel shader. Vid beräkningarna används avståndet till en smoothie (detta avstånd finns i smoothie-bufferten) och avståndet till det objekt som skuggas (detta avstånd finns i z-bufferten) för att avgöra hur stort halvskuggområdet ska bli (figur 29b). När z-bufferten och smoothie-bufferten är skapade renderas scenen utifrån kamerans ursprungliga position. Varje renderad punkts avstånd till ljuskällan jämförs med avståndet lagrat i z-bufferten. Om punktens avstånd är större än avståndet i z-bufferten befinner sig punkten i skugga. Annars jämförs punktens avstånd med det avstånd som finns lagrat i smoothie-bufferten. Om punktens avstånd är större än avståndet i smoothie-bufferten, det vill säga att punkten är skymd av en smoothie, används intensitetsvärdet i smoothie-bufferten för att belysa punkten. Om inget av ovanstående fall inträffar är punkten fullt belyst. 30

37 Skuggalgoritmer Ljuskälla Objekt Smoothie Objekt Kamera Smoothie a b Figur 29 a): Figuren visar objektet sett från ljuskällan, en smoothie skapas för varje siluettkant och siluetthörn. b): Avståndet mellan ljuskällan och en smoothie och avståndet mellan punkten som skuggas och ljuskällan används för att approximera hur stort halvskuggområdet skall vara. Om objektet som kastar skuggor och objektet som skuggas befinner sig nära varandra blir halvskuggområdet litet. Om objekten befinner sig långt ifrån varandra blir halvskuggområdet stort. Precis som i algoritmen av Assarsson m.fl. blir approximationen av skuggorna sämre när ljuskällans area ökar. En anledning till detta är att ett objekts siluettkanter sett från ljuskällan kan vara olika beroende på var på ljuskällan man befinner sig. Algoritmerna som beskrivits ovan bestämmer alltid siluettkanterna sett ifrån ljuskällans mitt. Ett annat problem med båda dessa algoritmer är att halvskuggan egentligen blir för liten, och det område som befinner sig helt i skugga blir för stort (figur 27). Anledningen till detta är att den ursprungliga shadow map-algoritmen används för att bestämma det område som befinner sig helt i skugga. Eftersom shadow map-algoritmen endast ser ljuskällan som en punktljuskälla kommer detta område att bli för stort. Notera dock att algoritmen som Assarsson m.fl. presenterar, inte lider av det senare problemet. Mjuka skuggor med shadow map-algoritmen Både smoothie- och penumbra map-algoritmerna kräver att siluettkanterna på objekten i scenen letas fram. Som diskuterats tidigare kräver detta en del arbete, speciellt om objekten består av många polygoner. Det begränsar även vilka sorts objekt som kan renderas. Vidare skapas nya polygoner för dessa siluettkanter, som även de måste renderas. Brabec och Seidel [Brabec02-2] har presenterat en algoritm som utökar shadow mapalgoritmen för att generera mjuka skuggor. Deras algoritm behöver inte leta reda på siluettkanter eller på något annat sätt modifiera objekten i scenen. Det enda som krävs är z-bufferten som skapas i shadow map-algoritmen, och en identitetskarta. En identitetskarta är en textur som används för att avgöra vilka objekt de olika pixlarna i z-bufferten tillhör. Identitetskartan kan till exempel skapas genom att ge varje objekt en färg, en identitet, och sedan rendera scenen sett ifrån ljuskällan. Varje pixel i z-bufferten har då en motsvarande pixel i identitetskartan som talar om vilket objekt som befinner sig på detta djup. När dessa båda texturer är skapade renderas scenen utifrån kamerans position. Likt shadow map-algoritmen används z-bufferten för att avgöra om punkten som renderas befinner sig i skugga eller inte. Detta ger upphov till två fall: 1. Om punkten inte befinner sig i skugga enligt shadow map-algoritmen kan punkten fortfarande befinna sig i den yttre halvskuggan. Omgivningen runt punktens projektion i z-bufferten undersöks för att hitta en blockerande pixel som tillhör ett annat objekt och som befinner sig närmare ljuskällan. Hur stort område som undersöks beror på hur långt ifrån ljuskällan punken befinner sig. Intensiteten på ljuset som når punkten bestäms delvis av avståndet i z-buffertens plan mellan punkten 31

38 Skuggalgoritmer och den blockerande pixeln. Det vill säga hur stor del av det totala sökområdet som behövdes sökas igenom innan en blockerande pixel hittades. Även avståndet mellan punkten som renderas och ljuskällan, och avståndet mellan ljuskällan och den blockerande punkten används för att avgöra ljusets intensitet. Detta får till följd att halvskuggområdet minskas om objektet som kastar skuggan och objektet som skuggas befinner sig nära varandra. 2. Om punken befinner sig i skugga enligt shadow map-algoritmen kan punkten fortfarande befinna sig i den inre halvskuggan. Även här undersöks omgivningen runt punktens projektion i z-bufferten, men nu för att hitta en pixel som enligt djuptestet är belyst. Intensiteten beräknas sedan på motsvarande sätt som i steg 1. Noteras bör att algoritmen som Brabec och Seidel beskriver genererar hela halvskuggområdet. Detta till skillnad från penumbra map- och smoothie-algoritmen som bara genererar det yttre halvskuggområdet. Percentage closer soft shadows Fernando [Fern05-1, Fern05-2] beskriver en algoritm som har många likheter med algoritmen av Brabec och Seidel. Algoritmen bygger på PCF och Fernando kallar algoritmen därför Percentage closer soft shadows (PCSS). Fernando noterar att om området som filtreras med PCF ökar, blir skuggkanterna mjukare. Algoritmen han beskriver går ut på att variera detta filterområde beroende på avståndet mellan punkten som renderas och ljuskällan, avståndet mellan det blockerande objektet och ljuskällan och ljuskällans storlek. Algoritmen består av 3 steg: 1. Sök efter blockerande objekt genom att undersöka området runt punktens projektion i z-bufferten. Områdets storlek beror på punktens avstånd till ljuskällan och ljuskällans storlek. Detta steg påminner mycket om Brabec och Seidels algoritm. Fernando väljer dock att leta fram samtliga blockerande pixlar inom detta område och beräknar därefter medelvärdet av deras avstånd till ljuskällan. 2. Beräkna storleken på halvskuggområdet genom formeln: ( Ap Ab) L Hs =, där Hs är storleken på halvskuggområdet, Ap är avståndet Ab mellan ljuskällan och punkten som renderas, Ab är avståndet mellan ljuskällan och de blockerande objekten och L är storleken på ljuskällan. 3. Utför PCF där Hs utgör filtrets storlek. Andra algoritmer Skuggtexturer Skuggtexturer [Aken02, Dietrich01] är en algoritm som till viss del liknar shadow mapalgoritmen. Likt shadow map-algoritmen renderas scenen med kameran placerad på ljuskällans position. Här sparas dock inte djupvärdet, utan objekten renderas helt enkelt i svart på en vit bakgrund. Detta skapar en svart-vit textur. Likt shadow map-algoritmen renderas scenen sedan från kamerans ursprungliga position. De punkter som renderas transformeras till ljuskällans synfält och koordinaterna används för att göra en texturuppslagning. Om den pixel som slås upp är svart befinner sig punkten i skugga, annars är punkten belyst. Denna algoritm har dock en stor nackdel, objekten kan inte skugga sig själva. Detta innebär att scenen måste delas upp i objekt som kastar skuggor och objekt som kan skuggas. Kozlov [Kozlov04] noterar dock att denna algoritm kan vara användbar i samarbete med shadow map-algoritmen. Han menar att shadow map-algoritmen används för objektens självskuggning. Skuggtexturer används sedan för objekt som kastar skuggor på andra objekt, till exempel en bil som kastar skuggor på en väg. Ett filter som gör skuggtexturerna suddigare kan även användas för att simulera mjuka skuggor. 32

39 Skuggalgoritmer Objektidentifikation Objekt identifikation [Aken02, Dietrich01] är ytterligare en algoritm som liknar shadow mapalgoritmen. Här ges varje objekt en identitet, i form av en unik färg. Objekten, sett från ljuskällan, renderas sedan med denna färg. Detta ger upphov till en identitetskarta, likt den som används i Brabec och Seidels algoritm. Scenen renderas därefter från kamerans position, och likt shadow map-algoritmen utförs en uppslagning i den tidigare skapade texturen. Om den uppslagna identiteten överensstämmer med identiteten på objektet som renderas, är punkten belyst. Om identiteterna inte är samma finns det ett objekt med en annan identitet närmare ljuskällan, punkten befinner sig därför i skugga. Shadow map - skuggvolym hybrid Skuggvolymalgoritmen kan som bekant ge upphov till massvis av pixeluppdateringar när skuggpolygonerna renderas, vilket ger dålig prestanda i komplexa scener. Skuggkanterna som skapas med denna algoritm är dock skarpa. Shadow map-algoritmen däremot kräver inte många pixeluppdateringar och är relativt effektiv att implementera. Det stora problemet med shadow map-algoritmen är att skuggkanterna uppvisar aliasing-effekter i form av hackiga skuggkanter. Chan och Durand [Chan04] har föreslagit en hybridalgoritm för att effektivt generera skuggor med skarpa skuggkanter. De noterar att skuggvolymalgoritmen endast behöver användas för de pixlar som befinner sig i närheten av skuggkanter. Den mer effektiva shadow mapalgoritmen används sedan för de resterande pixlarna. Algoritmen startar likt shadow map-algoritmen genom att rendera scenen till en z-buffert utifrån ljuskällans synvinkel. Därefter identifieras alla pixlar som befinner sig i närheten av skuggkanter. Detta åstadkoms genom att, precis som i shadow silhouette map-algoritmen, titta på de fyra närmaste djupvärdena i z-bufferten. Om samtliga fyra djupvärden ger samma resultat, det vill säga att punkten befinner sig i skugga eller är belyst, befinner sig pixeln inte i närheten av en skuggkant. I detta fall kan shadow map-algoritmen användas för att avgöra om pixeln skall skuggas eller inte. Om djupvärdena däremot ger olika resultat finns det en skuggkant i närheten, pixeln flaggas då som en siluettpixel. När samtliga pixlar blivit klassificerade används skuggvolymalgoritmen. Skuggvolymalgoritmen används dock endast på de pixlar som blivit flaggade som siluettpixlar. Skuggkanter, och då även siluettpixlar, upptar ofta endast en liten del av den renderade bilden. Detta minskar antalet pixeluppdateringar skuggvolymalgoritmen ger upphov till. Algoritmer med försteg Offline-algoritmer såsom raytracing eller radiosity kan användas för att rendera bilder innehållande verklighetstrogna skuggor. Dessa renderingsmetoder är dock alldeles för tidskrävande för att i dagsläget kunna användas i realtid i större scener. Om belysningen i scenen är bestämd och samtliga objekt är statiska, kan dock dessa metoder användas i ett försteg. I detta försteg skapas texturer för varje objekt. Varje pixel i texturerna innehåller ett intensitetsvärde för motsvarande punkt på objektet. Vid realtidsrendering används dessa intensitetsvärden för att belysa scenen. Den självklara nackdelen med denna metod är att scenen måste vara helt statisk, något som ofta inte är fallet i interaktiva virtuella miljöer. Occlusion interval maps Donnelly och Demers [Donne04] har beskrivit en algoritm för att generera mjuka skuggor. Algoritmen förutsätter att samtliga objekt i scenen är statiska, däremot kan ljuskällan röra sig i en bestämd bana. Dessa förutsättningar är ofta uppfyllda i utomhusmiljöer där objekt såsom byggnader och dylikt är statiska, medan solen rör sig i en bestämd bana. Deras algoritm bygger på att ljuskällan befinner sig på en viss punkt på sin bana vid en viss tidpunkt. Som ett försteg skapas texturer som, för varje punkt på objekten, lagrar de tidpunkter där punkten hamnar i skugga. Det vill säga den tidpunkt när ljuskällan förflyttar sig 33

40 Skuggalgoritmer bakom ett objekt i scenen, som därmed skuggar punkten i fråga. Det skapas även texturer som lagrar de tidpunkter när punkten går från att ha varit skuggat till att bli belyst. Vid rendering kan de lagrade tidpunkterna användas för att ta reda på om punkten som renderas befinner sig i skugga eller inte vid en viss tidpunkt. Detta ger dock bara upphov till hårda skuggkanter. Författarna beräknar därför belysningen under ett litet tidsintervall. Intensiteten som används när punkten renderas motsvarar hur stor del av detta tidsintervall som punkten var belyst. Denna approximation kommer dock att leda till att skuggorna bara blir mjukare i riktningen som är parallell med ljuskällans bana. Författarna noterar trots det att de resulterande skuggorna ser tilltalande ut för mindre ljuskällor, såsom solen skådad från jorden. Precomputed radiance transfer Sloan m.fl. [Sloan02] har beskrivit en algoritm för att ljussätta föremål i realtid, algoritmen bygger på ett försteg och kallas Precomputed radiance transfer (PRT). De flesta andra algoritmer för ljussättning tar endast hänsyn till ljuskällorna i scenen. Algoritmen Sloan m.fl. beskriver kan däremot även använda sig av ljus beskrivet i en environment map och därmed ta hänsyn till ljus infallande ifrån samtliga riktningar. Algoritmen klarar även av lokala ljuskällor. Deras algoritm består av ett försteg som för varje hörn i objekten i scenen beräknar en belysningsfunktion. Denna funktion beskriver hur just detta hörn skall belysas, givet belysningen för den punkt hörnet befinner sig på. I försteget tas hänsyn till i vilka riktningar objektet skymmer sig själv, algoritmen kommer därför att ge upphov till självskuggning. För att representera belysningsfunktionerna används spherical harmonics [Ramam01]. Vidare används endast ett fåtal termer för att representera dessa funktioner, detta får till följd att endast lågfrekventa ljusförändringar kan åstadkommas med algoritmen. Skuggfält Zhou m.fl. [Zhou05] använder sig av något de kallar för skuggfält för att generera skuggor i en dynamisk scen. I ett försteg beräknas för varje objekt ett skuggfält. Ett skuggfält beskriver hur ett objekt ger upphov till skuggor i sin omgivning. Skuggfältet skapas genom att skapa flera samplingspunkter i objektets omgivning. För varje sådan samplingspunkt skapas en cube map. Dessa cube maps kan därefter svara på om objektet ger upphov till skugga vid en viss samplingspunkt med ljus infallande i en viss riktning. Skuggfälten kan skapas enskilt för varje objekt, utan att ta hänsyn till scenens utformning. Skuggfält skapas både för objekt och för ljuskällor. För ljuskällorna handlar det dock om hur ljus sprids i omgivningen runt ljuskällan. Vid rendering kan dessa skuggfält snabbt kombineras för att ge upphov till skuggor. Likt PRT-algoritmen är de skuggor som skapas ofta alldeles för mjuka, detta eftersom data från försteget komprimeras kraftigt. Zhou m.fl. noterar även att mer högfrekventa ljuseffekter kan åstadkommas, detta kräver dock betydligt mer minne och beräkningskraft. 34

41 Utvärdering och jämförelse Utvärdering och jämförelse I denna del kommer jag att utvärdera de ovan beskrivna algoritmerna mot ett antal kriterier, dessa kriterier beskrivs i nästa avsnitt. Målet med denna utvärdering är att den skall kunna användas för att snabbt ge förslag på lämpliga skuggalgoritmer. Denna utvärdering kan användas på flera sätt. Till exempel kan den användas vid planeringsfasen av en applikation. Då fastställs vissa krav på algoritmens resursutnyttjande och kvalitet. Utvärdering kan då användas för att föreslå ett antal algoritmer. Vidare ger den information om vilka begränsningar dessa algoritmer sätter på de objekt och ljuskällor som kan användas i applikationen. Utvärderingen kan även användas för en redan utvecklad applikation. Här är i stället redan bestämt vilka objekt och ljuskällor som måste stödjas. Utvärderingen kan då ge förslag på algoritmer som stöder dessa objekt och ljuskällor. Antalet föreslagna algoritmer kan sedan minskas genom att även sätta krav på önskad kvalitet och/eller prestanda. Det senare användningssättet är vad jag använder för att föreslå skuggalgoritmer för VTP. Utvärderingskriterier I detta avsnitt kommer jag att presentera de kriterier som jag valt att använda vid utvärderingen av de olika algoritmerna. Avsnittet beskriver även varför dessa kriterier är viktiga. Jag har valt att inkludera olika typer av kriterier såsom algoritmens resursförbrukning, kvalitet samt generalitet. Resursförbrukning De första kriterierna handlar om algoritmens resursförbrukning. Jag har valt att koncentrera mig på tre typer av resurser: minne, centralprocessor samt grafikhårdvara. En algoritms förbrukning av minnesutrymme och minnesbandbredd kan vara avgörande för hur effektivt en algoritm exekverar. Dagens datorsystem kan lagra data som används vid rendering i tre olika minnen: grafikhårdvarans minne, datorsystemets primärminne eller datorsystemets sekundärminne. Datorsystemets sekundärminne (det vill säga hårddisken) klarar idag av att lagra flera hundra GB data, sekundärminnet är dock mycket långsamt. Datorsystemets primärminne är betydligt snabbare men också mycket mindre, i dagsläget är minnesstorlekar mellan MB vanliga. Grafikhårdvarans minne är ännu mindre, minnesstorlekar på MB är vanliga. Renderingsalgoritmer som skall exekvera i realtid bör inte för varje bild som renderas läsa data från sekundärminnet. Detta brukar inte vara något problem för realtidsalgoritmer, då grafikhårdvarans minne och datorsystemets primärminne ofta klarar av att lagra den data som används. Endast vid byte av scen och liknande läses data från sekundärminnet. För att använda data i primärminnet vid rendering måste data transporteras över till grafikhårdvaran. Denna transport sker idag av en AGP-buss eller en PCI-express buss. Dessa bussar har en begränsning på hur mycket data som kan transporteras per sekund. Data som finns i grafikminnet kan däremot hämtas direkt av grafikhårdvaran, vilket ökar mängden data som kan transporteras per sekund. Tabell 1 visar den maximala bandbredd som kan uppnås genom att använda AGP-buss, PCI-express buss eller grafikhårdvarans interna minnesbuss [Ati04, Nvidia06]. Av dessa siffror framgår att det finns möjlighet till en stor prestandaökning om all data som används vid rendering kan lagras i grafikhårdvarans minne. Det är även intressant att veta hur många rastreringsoperationer som grafikhårdvaran behöver utföra. Med rastreringsoperationer menas de operationer som läser och skriver i z-bufferten, stencilbufferten och färgbufferten. Dessa operationer kräver kommunikation med grafikminnet. Alldeles för många rastreringsoperationer kan därför snabbt sluka den tillgängliga bandbredden i grafikhårdvarans interna minnesbuss. 35

42 Utvärdering och jämförelse Tabell 1: Maximal bandbredd i AGP-buss, PCI-express buss och grafikhårdvarans interna minnesbuss. Minnesbuss Bandbredd (GB/sekund) AGP 2.1 (i riktning till grafikhårdvaran) PCI Express 4.0 (i varje riktning) Intern minnesbuss 54.4 Hur mycket en algoritm belastar centralprocessorn kan vara viktigt att känna till. I applikationer där centralprocessorn redan används mycket, till exempel för AI eller fysikberäkningar, kan det vara önskvärt att använda en algoritm med en låg belastning av centralprocessorn. Dagens programmerbara grafikhårdvara har som bekant stöd för vertex och pixel shaders. Som vi sett ovan finns det många skuggalgoritmer som använder sig av vertex och pixel shaders i olika utsträckning. Som ett kriterium har jag därför valt vilken shader modell som krävs för att algoritmen skall exekvera. Detta är viktigt eftersom äldre grafikhårdvara endast stöder de tidigare shader modellerna, vilket innebär att vissa algoritmer inte kan användas på sådan grafikhårdvara. Som förklaras av Cebenoyan [Cebenoy04] är de ovan beskrivna kriterierna även användbara vid optimering av applikationer. De kan därför användas för att välja en lämplig skuggalgoritm när eventuella flaskhalsar är kända i en applikation. Kvalitet För att utvärdera algoritmernas kvalitet används följande kriterier: skuggornas mjukhet och visuella artefakter. Med skuggornas mjukhet menas här om algoritmen ger upphov till hårda eller mjuka skuggkanter. För algoritmer som ger upphov till mjuka skuggor diskuteras även hur verklighetstroget skuggorna uppträder. Skuggalgoritmer som genererar hela halvskuggområdet anses till exempel vara mer verklighetstrogna än algoritmer som bara genererar en del av halvskuggområdet (figur 28). När en skuggalgoritm skall väljas för en viss applikation är det viktigt att känna till mjukheten på de skuggor algoritmen ger upphov till. Detta eftersom vissa applikationer kan dra nytta av skarpa skuggor som är bra på att förmedla ett objekts form. Ett exempel på en sådan applikation är ett CAD-program, där det är viktigt att formen på ett komplicerat objekt förmedlas. Andra applikationer kan dra nytta av mjuka realistiska skuggor som smälter in i sin omgivning och ger mer realism till scenen. Exempel på sådana applikationer kan vara spel där man vill skapa en realistisk miljö för spelaren. Som vi sett ovan kan visuella artefakter uppstå vid genereringen av skuggor. Vid hårda skuggor kan aliasing-effekter uppträda i form av hackiga skuggkanter. Visuella artefakter kan även uppstå i form av att objekt felaktigt skuggar sig själva. Dessa effekter försöks oftast undvikas, ibland kan dock vissa visuella artefakter tålas om prestanda är viktigare än kvalitet. Generalitet Det är även bra att veta hur generell en viss algoritm är. För att utvärdera en algoritms generalitet används här följande tre kriterier: möjlighet till självskuggning, vilka typer av objektmodeller som kan hanteras och vilka typer av ljuskällor som kan hanteras. Vissa skuggalgoritmer klarar bara av att skapa skuggor för objekt som kastar skuggor på andra objekt i scenen. Sådana algoritmer klarar därmed inte av objekt som skuggar sig själva. I vissa applikationer är det möjligt att dela upp en scens objekt i skuggkastande objekt och skuggmottagande objekt. I sådana applikationer fungerar dessa begränsade algoritmer bra. Andra applikationer kan innehålla ett fåtal stora objekt, där självskuggning utgör en stor del av skuggorna i scenen. Därför är det bra att känna till om algoritmen hanterar självskuggning eller inte. 36

43 Utvärdering och jämförelse Ett annat viktigt kriterium för skuggalgoritmer är vilka objektmodeller som stöds. Skuggvolymalgoritmen undersöker som bekant polygonmodeller för att hitta siluettkanter, för sådana kanter skapas sedan skuggpolygoner. Skuggvolymalgoritmen är därmed begränsad till att användas i samband med polygonmodeller. Inom datorgrafiken används dock många fler typer av objektmodeller. Till exempel används ibland matematiska funktioner för att definiera ett objekt. Inom realtidsrendering är texturerade och delvis transparanta polygoner populära för att skapa objekt såsom träd och buskar. Skall dessa objekt ge upphov till skuggor måste någon annan algoritm än skuggvolymalgoritmen användas. Det är därför bra att veta vilka objekt en viss algoritm kan hantera. Vissa skuggalgoritmer är även begränsade av vilka typer av ljuskällor som kan hanteras. Vissa algoritmer hanterar bara ljuskällor som sprider ljus inom en viss sektor, medan andra algoritmer hanterar ljuskällor som sprider ljus i alla riktningar. I scener där solen är den enda ljuskällan, sprids ljuset oftast bara inom en viss sektor sett från ljuskällan. Andra scener, innehållande lokala ljuskällor, kräver skuggalgoritmer som klarar av att hantera ljuskällor som sprider ljus i alla riktningar. Ibland används även en environment map som beskriver hur ljus inkommer från alla riktningar runtom ett objekt. Utvärdering av skuggalgoritmer I detta avsnitt kommer en grundlig utvärdering genomföras av de ovan beskrivna skuggalgoritmerna enligt de kriterier som satts upp. I utvärderingen kommer ett antal olika variabler att användas för att beskriva beräkningskomplexitet och minnesutnyttjande, tabell 2 sammanfattar dessa variabler. Tabell 2: Tabellen beskriver de variabler som används i utvärderingen nedan. Variabel Beskrivning t Antalet trianglar i en scen. Jag har här valt att använda trianglar i stället för godtyckliga polygoner eftersom just triangeln är den primitiv grafikhårdvaran hanterar. Detta innebär även att antalet hörn och antalet kanter är O(t), eftersom en triangel som mest kan bestå av tre hörn eller tre kanter. e Antalet siluettkanter i en scen. I de flesta scener gäller e << t. p a n c o Antalet pixlar i den renderade bilden. Medelvärdet av antalet pixlar, i den renderade bilden, som uppdateras när en triangel renderas. Antalet pixlar i z-bufferten som används i shadow map-algoritmen. Storleken, i antalet pixlar, på det filter som används vid PCF. Antalet objekt i scenen. I slutet av detta avsnitt sammanfattas denna utvärdering i tre tabeller, dessa tabeller kan användas för att snabbt ge information om de olika skuggalgoritmerna. Skuggvolymalgoritmer Jag börjar med att granska skuggvolymalgoritmerna. Till dessa räknas den ursprungliga skuggvolymalgoritmen, CC skuggvolymer samt skuggvolymalgoritmen för mjuka skuggor. Z-pass, z-fail och ZP+ Grundidén i skuggvolymalgoritmen är att skapa skuggpolygoner som definierar de områden som befinner sig i skugga. Dessa skuggpolygoner kan skapas på olika sätt. Jag kommer att börja med att redogöra för den metod som Crow [Crow77] beskrev. Därefter beskrivs vilka inverkningar de övriga metoderna ger. I Crows metod skapas skuggpolygonerna genom att 37

44 Utvärdering och jämförelse låta centralprocessorn undersöka samtliga kanter i ett objekt. Med denna metod kommer arbetsbördan för centralprocessorn att öka linjärt med antalet trianglar i scenen, dvs. beräkningskomplexiteten för att skapa skuggpolygonerna är O(t). När samtliga skuggpolygoner är skapade, renderas de för att uppdatera stencilbufferten. Varje siluettkant har gett upphov till en skuggpolygon som i värsta fall täcker hela bilden. Detta innebär att antalet djupjämförelser och stencilbuffertuppdateringar för varje pixel är O(e). För hela bilden skapas därmed minnestrafik motsvarande O(pe). Detta värsta fall-scenario är ganska vanligt i samband med skuggvolymalgoritmen. Problemet ligger i att skuggpolygonerna ofta är stora, eftersom de sträcks ut till oändligheten (eller i alla fall så att de täcker in hela scenen). Detta gör att skuggpolygonerna ofta täcker stora delar av den renderade bilden. Om z-fail algoritmen används måste även begränsningen framtill och baktill på skuggvolymen renderas. Då dessa begränsningar ofta utgörs av objektets polygoner skapas ytterligare minnestrafik motsvarande O(at). Z-pass algoritmen genererar inte denna extra minnestrafik. Detta är anledningen till att vissa skuggalgoritmer endast använder z-fail algoritmen för de scenkonfigurationer z-pass algoritmen inte klarar av [McGuire03, Everitt02]. Ett problem med skuggvolymalgoritmen är att den genererade minnestrafiken kan variera mycket mellan olika scenkonfigurationer. Detta leder till att algoritmens prestanda kan variera mycket när kameran förflyttar sig i en scen. Hur mycket av grafikhårdvarans minnesutrymme algoritmen behöver, beror på vilket sätt hörndata hanteras. Om nya skuggpolygoner (dvs. skuggpolygonernas hörn) skapas av centralprocessorn vid varje bilduppdatering, behövs endast ett litet utrymme för att temporärt lagra dessa hörn innan de renderas. Om denna metod används måste dock dessa hörndata transporteras från centralprocessorn till grafikminnet vid varje bilduppdatering. Detta kan utnyttja en stor del av PCI-express (eller AGP) bussens tillgängliga bandbredd. För att minska på kommunikationen av hörndata har McGuire m.fl. [McGuire03] föreslagit att hörndata skall lagras i grafikminnet. Deras metod lagrar två uppsättningar positionskoordinater per hörn, vilket innebär att minnesutrymmet som används är O(t). I stället för att skicka över hörndata till grafikhårdvaran, skickar centralprocessorn över referenser till de hörn som finns lagrade i grafikminnet. Detta sparar bandbredd eftersom en referens inte kräver lika mycket data som ett hörn. Vid skuggvolymalgoritmen används även stencilbufferten för att lagra vilka pixlar som är skuggade och vilka som är belysta. Denna buffert tar dock oftast inte upp något extra minnesutrymme eftersom den delar minnesutrymme med djupbufferten, och finns där även när den inte används. Den största fördelen med skuggvolymalgoritmen är att den ger upphov till hårda skuggor, där skuggkanterna bestäms per pixel för den renderade bilden. I och med detta uppstår inga aliasing-effekter i form av hackiga skuggkanter. Skuggvolymalgoritmen skapar som bekant volymer vilka definierar de områden som befinner sig i skugga. De delar av ett objekt som befinner sig inuti dessa volymer är skuggade, detta gäller även för objektet som gav upphov till volymen. Skuggvolymalgoritmen klarar därför av objekt som skuggar sig själva. Vidare hanteras skuggor från ljuskällor som sprider ljus i alla riktningar. Ett problem med skuggvolymalgoritmen är att den bara kan skapa skuggor från objekt som är uppbyggda av polygoner. Om Crows metod används finns även en begränsning på hur dessa polygonobjekt kan se ut. Genom att använda Aldridge och Woods [Aldrid04] metod för att skapa skuggpolygonerna kan samtliga polygonobjekt användas. Beräkningskomplexiteten för Aldridge och Woods metod är O(t), vilket är samma som för Crows metod. Skuggvolymer på grafikhårdvaran Som beskrivits ovan finns det även förslag på algoritmer som undviker att belasta centralprocessorn för att skapa skuggvolymen. Den algoritm Everitt och Kilgard [Everitt03] beskriver använder sig av en vertex shader för att avgöra om ett hörn skall flyttas till oändligheten eller inte. Denna shader kräver endast vertex shader modellen vs 1.1, vilket 38

45 Utvärdering och jämförelse innebär att ett stort antal olika grafikhårdvara kan använda deras metod. Algoritmen kan ge ökad prestanda i applikationer där centralprocessorn är flaskhalsen. Å andra sidan leder algoritmen ofta till försämrad prestanda om grafikhårdvarans bearbetning av hörn är flaskhalsen. Detta eftersom nya hörn måste skapas, vilket illustrerades i figur 16. Vidare klarar algoritmen inte av godtyckliga polygonmodeller likt de Aldridge och Woods algoritm klarar av, t.ex. uppstår problem där modellerna innehåller hål. Brabec och Seidel [Brabec03-1] har även de presenterat en algoritm för att skapa skuggvolymen på grafikhårdvaran. Deras algoritm använder sig av två texturer i storleksordningen O(t) för att lagra delresultat. Den första texturen lagrar samtliga hörns positioner och måste därför klara av att lagra flyttal. Den andra texturen lagrar endast två binära data för varje kant, därmed räcker en vanlig textur med 8-bitar per färgkanal. Vid framtagningen av skuggpolygonerna används en vertex shader som läser från dessa texturer. Detta innebär att hårdvara med stöd för vs 3.0 är att rekommendera. Om vs 3.0-stöd saknas måste data överföras från grafikminnet till systemminnet vilket ger en kraftig sänkning av prestanda. Brabec och Seidels algoritm skapar ingen begränsning framtill eller baktill på skuggvolymen, den kan därmed inte användas i samband med z-fail algoritmen. Dessutom finns en begränsning på vilka polygonmodeller som kan användas, detta eftersom Crows siluettbedömningsmetod används. CC skuggvolymer Renderingen av de oftast stora skuggpolygonerna är en dyr operation och ger upphov till mycket minnestrafik. Lloyd m.fl. [Lloyd04] har föreslagit en algoritm som försöker att minska antalet skuggvolymer som måste renderas, de försöker även minska storleken på de skuggpolygoner som väl måste renderas. Första delen av deras algoritm går ut på att rendera scenen både från kamerans och från ljuskällans synvinkel, detta skapar minnestrafik motsvarande O(at). Denna minnestrafik tjänas ofta igen genom att ett mindre antal skuggpolygoner måste renderas. I andra delen av deras algoritm används centralprocessorn för att bestämma storleken på skuggvolymerna. Eftersom varje objekts skuggvolym i värsta fall måste jämföras med de resterande objekten är beräkningskomplexiteten O(o 2 ) för att bestämma skuggvolymernas utsträckning. I många fall kan dock den första delen av algoritmen ha plockat bort många objekt som inte behöver behandlas. När skuggvolymerna skapas kan varje objekt ge upphov till flera volymer, se figur 19. Detta innebär mer arbete för centralprocessorn samt att mer hörndata måste överföras till grafikminnet. Fördelen med allt detta extra arbete är att skuggpolygonerna blir små och går snabbare att rendera. Algoritmen bör dock inte användas i applikationer där centralprocessorn redan är en flaskhals, på grund av allt detta extra arbete. Likt den ursprungliga skuggvolymalgoritmen är CC skuggvolymalgoritmens prestanda beroende på scenkonfigurationen. För vissa scener och kameravinklar fungerar algoritmen mycket bra och ger upphov till få och små skuggvolymer. För andra scenkonfigurationer, där det inte går att minska skuggvolymernas antal och storlek, fungerar algoritmen mindre bra. En nackdel med algoritmen är att den inte klarar av ljuskällor som sprider ljus i alla riktningar. Anledningen till detta är att algoritmen innehåller ett steg där scenen renderas sett ur ljuskällans synvinkel. Detta innebär att CC skuggvolymer endast skapas inom en viss sektor runt ljuskällan, för de resterande riktningarna används vanliga skuggvolymer. Alternativt kan algoritmen användas i flera pass för olika riktningar runt ljuskällan. Skuggvolymalgoritm för mjuka skuggor Assarsson m.fl [Assar03-1, Assar03-2] har presenterat en algoritm som ger upphov till mjuka skuggor genom att utvidga skuggvolymalgoritmen. Likt den ursprungliga skuggvolymalgoritmen startar deras algoritm med att söka efter samtliga siluettkanter i scenen. Detta arbete utförs på centralprocessorn och har som bekant beräkningskomplexiteten O(t). Förutom att skapa en skuggpolygon för varje siluettkant, skapas även en kil som representerar halvskuggområdet. Denna kil ger upphov till fyra polygoner med tillhörande hörn. Dessa 39

46 Utvärdering och jämförelse extra polygoner innebär att mycket mer data måste överföras från centralprocessorn till grafikkortet för varje bilduppdatering. När skuggpolygonerna och kilarna renderas för att uppdatera V-bufferten och stencilbufferten skapas minnestrafik motsvarande O(pe), likt den ursprungliga skuggvolymalgoritmen. Algoritmen kräver en del minnesutrymme för att skapa de mjuka skuggorna. För det första använder sig Assarsson m.fl. av två stycken 32-bitars texturer (8-bitar per färg-/alfakanal) för att skapa V-bufferten. Dessa texturer har samma upplösning som bilden som renderas, vilket innebär att de upptar O(p) minne. Utöver detta används ett antal förberäknade texturer för att minska antalet beräkningar i den pixel shader som används. Författarna rapporterar att dessa texturer sammanlagt upptar cirka 300kB. En intressant funktion med deras algoritm är att den klarar av att hantera rektangulära ljuskällor vars yta är texturerad. Detta kräver dock mer minnesutrymme för de förberäknade texturer som pixel shadern använder sig av. För en ljuskälla texturerad med en pixlar stor textur, krävs en förberäknad textur på 3MB. För de punkter som befinner sig inuti en kil exekveras en pixel shader som beräknar hur stor del av ljuskällan som punkten kan se. Författarna rapporterar att denna pixel shader innehåller 63 instruktioner. Detta innebär att grafikhårdvaran åtminstone måste ha stöd för pixel shader modell ps 2.0. Algoritmen ger upphov till mjuka skuggor och hela halvskuggområdet genereras. Det kan dock vara värt att komma ihåg att skuggorna som skapas inte är helt korrekta, utan endast en approximation. Till exempel beräknas siluettkanterna endast från en punkt, mittpunkten, på ljuskällan. Detta stämmer inte helt överens med verkligheten eftersom olika punkter på ljuskällan kan ge upphov till olika siluettkanter. Skuggvolymalgoritmen för mjuka skuggor kan hantera objekt som skuggar sig själva samt ljuskällor som sprider ljus i alla riktningar, likt den ursprungliga skuggvolymalgoritmen. Algoritmen är dock begränsad till att användas i samband med polygonobjekt. Shadow map-algoritmer Shadow map-algoritmen Shadow map-algoritmen skiljer sig mycket från skuggvolymalgoritmen, både vad gäller resursutnyttjande och kvalitet på de skuggor som skapas. En stor fördel med shadow mapalgoritmen är att den inte belastar centralprocessorn, alla beräkningar utförs på grafikhårdvaran. Det enda centralprocessorn behöver göra är att skicka de renderingsanrop som grafikhårdvaran behöver. Shadow map-algoritmen renderar scenen i två pass. I det första passet renderas scenen med kameran placerad på ljuskällans position. Resultatet av detta renderingspass är en textur, z- bufferten, som för varje pixel lagrar avståndet från ljuskällan till den punkt i scenen som pixeln representerar. Denna z-buffert behöver inte ha samma upplösning som den bild som renderas. Låt n stå för antalet pixlar i denna textur. För att uppdatera denna z-buffert skapas minnestrafik motsvarande O(atn/p), och för att lagra densamma upptas O(n) minne. Storleken på denna z-buffert är direkt kopplad till algoritmens prestanda och kvaliteten på de skuggor som genereras. En stor z-buffert kräver mer minnestrafik och lagringsutrymme, men ger också mindre aliasing-effekter än en liten z-buffert. I det andra renderingspasset renderas scenen utifrån kamerans ursprungliga position. För varje pixel som renderas utförs en uppslagning i den ovan nämnda texturen. Därefter genomförs en jämförelse mellan två djupvärden för att avgöra om pixeln befinner sig i skugga eller inte. Om PCF används utförs c texturuppslagningar och jämförelser per pixel, där c är storleken på det filter som används. Dessa texturuppslagningar ger upphov till minnestrafik motsvarande O(atc). Genom att utföra ett initierande z-bufferpass och därefter endast uppdatera de pixlar som verkligen syns, skapas i stället minnestrafik motsvarande O(pc). Minnestrafiken är då helt bestämd av bildens och filtrets storlek, och inte beroende på antalet trianglar eller objekt i scenen. 40

47 Utvärdering och jämförelse Algoritmen går att exekvera på hårdvara utan stöd för pixel shaders, genom att använda hårdvarans inbyggda stöd för shadow map-jämförelserna i steg 2. Om pixel shaders används ges däremot större frihet till hur skuggade och belysta områden skall behandlas. Vidare kan PCF lätt implementeras med hjälp av pixel shaders. Shadow map-algoritmen ger upphov till hårda skuggor. Skuggkanterna uppvisar dock ofta aliasing-effekter i form av hackiga skuggkanter. Vidare kan objekt felaktigt skugga sig själva på vissa pixlar. Som nämnts ovan kan problemet med självskuggningen minskas genom att subtrahera ett konstant värde från avståndet mellan ljuskällan och punkten som renderas. De hackiga skuggkanterna är desto svårare att bli av med. Genom att använda PCF görs skuggkanterna suddigare, vilket kan hjälpa till att dölja de hackiga kanterna. Ett annat problem med shadow map-algoritmen är att den kan missa skuggor från små objekt eller delar av objekt. Detta kan inträffa eftersom objekt eller delar av objekt kan missas när z-bufferten samplar scenen. En stor fördel med algoritmen är att den klarar av att rendera många olika typer av objekt. Vad som krävs är att objektet kan renderas till en z-buffert. Vad detta innebär är att algoritmen kan användas för att skapa skuggor för t.ex. objekt bestående av polygoner där delar av polygonen här helt transparent. Sådana objekt används vanligtvis för att rendera objekt såsom buskar, träd eller stängsel. Vidare hanterar algoritmen objekt som skuggar sig själva. I grundutförande hanterar Shadow map-algoritmen endast ljuskällor som sprider ljus inom en begränsad sektor. Som beskrivits ovan kan ljuskällor som sprider ljus i alla riktningar hanteras, för detta krävs dock att scenen renderas flera gånger. Perspective shadow map, light space perspective shadow map och trapezoidal shadow map Perspective-, light space perspective- och trapezoidal shadow map-algoritmerna har många likheter med den ursprungliga shadow map-algoritmen. Den enda skillnaden är att dessa algoritmer använder sig av ytterligare en matrismultiplikation när z-bufferten skapas, och när denna buffert används vid generering av skuggorna. För att skapa dessa matriser behöver centralprocessorn arbeta lite mer än i shadow map-algoritmen. Perspective shadow map och light space perspective shadow map använder sig av hela scenens omslutande box för att bestämma matrisens utseende. I en scen där objekten kan förflytta sig måste därför samtliga objekts omslutande boxar undersökas, detta ger upphov till O(o) arbete. Trapezodial shadow map-algoritmen undersöker endast vy-volymens åtta hörn, och är därmed inte beroende av antalet objekt i scenen. I övrigt utnyttjas resurser på samma sätt som i shadow mapalgoritmen. Likt shadow map-algoritmen ger dessa algoritmer upphov till hårda skuggor. Skuggorna som genereras med perspective-, light space perspective- och trapezoidal shadow mapalgoritmerna lider dock inte av lika allvarliga aliasing-effekter som shadow map-algoritmen. Som beskrivits ovan åstadkoms detta genom att applicera en transformation som förstorar objekt nära kameran och förminskar objekt långt ifrån kameran. Detta får till följd att de stora objekten nära kameran kommer att breda ut sig över många pixlar på z-bufferten, samtidigt som de små objekten endast kommer att uppta ett fåtal pixlar. Detta innebär att objekten nära kameran, där aliasing-effekterna är som värst, kommer att samplas bättre och därmed minska aliasing-effekterna. När objekten förstoras och förminskas ändras även avstånden från ljuskällan till punkter på objekten. I och med detta ökar problemen med felaktig självskuggning. I shadow map-algoritmen minskades detta problem genom att subtrahera ett konstant värde från avståndet mellan ljuskällan och punkten som renderas. Denna lösning fungerar inte här eftersom värdet som subtraheras måste vara större för objekt nära kameran och mindre för objekt långt ifrån kameran. Martin och Tan [Martin04] beskriver hur en pixel shader kan användas för att skriva över värdet i z-bufferten med avståndet som fås genom den ursprungliga shadow map-algoritmen. Om en sådan pixel shader används, kan subtraktion av en konstant återigen användas för att minska problemet med självskuggning. För att kunna skriva ett nytt djupvärde i en pixel shader måste grafikhårdvaran ha stöd för ps

48 Utvärdering och jämförelse Perspective- och light space perspective shadow map-algoritmerna kan uppvisa hackiga skuggkanter i vissa scenkonfigurationer. Detta händer speciellt när ett objekt som kastar en skugga i scenen befinner sig långt bakom kameran. På grund av detta kan skuggorna växla kvalitet när kameran rör sig genom scenen. Trapezoidal shadow map-algoritmen lider inte av detta problem utan försöker i stället se till att skuggkvaliteten ändras på ett mjukt sätt mellan två bilduppdateringar. Perspective-, light space perspective- och trapezoidal shadow map-algoritmerna hanterar ljuskällor som sprider ljus inom en begränsad sektor. Om ljuskällor som sprider ljus i samtliga riktningar används måste scenen renderas flera gånger. Dessa algoritmer ger dock bästa förbättringen över shadow map-algoritmen när ljuskällan sprider ljus över ett stort område, t.ex. när solen lyser över ett landskap. I sådana fall handlar det oftast om en ljuskälla som sprider ljus inom en begränsad sektor. Shadow silhouette map Shadow silhouette map-algoritmen utökar shadow map-algoritmen med information om siluettkanterna i scenen. Denna information används för att minska skuggkanternas hackighet. Då shadow map-algoritmen utgör en del av algoritmen gäller det resursutnyttjande som beskrevs ovan även för shadow silhouette map-algoritmen. Utöver detta behövs ytterligare resurser för att skapa och lagra siluettkartan. För det första måste samtliga siluettkanter i scenen hittas. Som beskrivits i samband med skuggvolymalgoritmen innebär detta arbete motsvarande O(t) för centralprocessorn. Det krävs även minnesutrymme för att lagra siluettkartan. Då denna textur har samma upplösning som z-bufferten som skapas i steg 1 i shadow map-algoritmen blir det sammanlagda minnesutnyttjandet 2n. Den minnestrafik som genereras när siluettkartan skapas är oftast låg, detta eftersom endast siluettkanterna av objekten renderas. När skuggorna renderas skapas även extra minnestrafik eftersom uppslagning även måste ske i siluettkartan. För att skapa siluettkartan och för att använda informationen i den vid generering av skuggor krävs relativt komplicerade pixel shaders. Författarna rapporterar att en pixel shader på 60 instruktioner används för att rendera till siluettkartan, och att en pixel shader på 46 instruktioner används vid genereringen av skuggor. Detta innebär att grafikhårdvara med stöd för åtminstone ps 2.0 krävs för att använda shadow silhouette map-algoritmen. De hårda skuggor som skapas håller hög kvalitet, där skuggkanterna bestäms per pixel i den renderade bilden. Hackiga skuggkanter kan dock uppstå där två eller flera siluettkanter går igenom samma pixel i siluettkartan. Skuggkonturerna kan även uppträda hackigare än vad själva objektet är. Detta beror på att siluettkartan endast lagrar en punkt i varje pixel, runda siluettkanter kommer därför att uppträda hackiga. Vidare kvarstår problemet med felaktig självskuggning. Likt skuggvolymalgoritmen begränsas shadow silhouette map-algoritmen till att endast användas i samband med objekt uppbyggda av polygoner. Vidare krävs flera renderingspass om ljuskällor som sprider ljus i samtliga riktningar används, likt shadow map-algoritmen. Slutligen klarar algoritmen av objekt som skuggar sig själva. Penumbra map och smoothies Penumbra map-algoritmen och smoothie-algoritmen har många likheter med varandra. Vad gäller utnyttjandet av resurser återfinns även många likheter med shadow silhouette mapalgoritmen. Alla tre algoritmer bygger på att siluettkanterna är kända, detta innebär extra arbete för att hitta siluettkanterna och begränsar vilka objekt algoritmerna kan hantera. Vad gäller minnesutrymme utnyttjar samtliga tre algoritmer en extra textur. Detta innebär att dubbelt så mycket utrymme används jämfört med shadow map-algoritmen. Dessutom krävs grafikhårdvara med stöd för ps 2.0 för att exekvera de shaders som används. De skuggor penumbra map-algoritmen och smoothie-algoritmen ger upphov till är mjuka. Algoritmerna klarar bara av att skapa det yttre halvskuggområdet (figur 28). Detta får till följd att det område som befinner sig helt i skugga blir för stort, vilket märks tydligt när ljuskällans area ökar. För små ljuskällor eller ljuskällor som befinner sig långt bort fungerar dock 42

49 Utvärdering och jämförelse algoritmerna bra. De mjuka skuggorna hjälper även till att dölja aliasing-effekter i form av hackiga skuggkanter. Den stora skillnaden mellan penumbra map-algoritmen och smoothie-algoritmen är hur de använder siluettkanterna för att uppskatta intensiteten i halvskuggområdet. Smoothiealgoritmen skapar en smoothie för varje siluettkant och för varje siluetthörn. En smoothie består av 2 trianglar. I penumbra map-algoritmen skapas i stället koner för siluetthörnen och för siluettkanterna skapas ett blad som sammanbinder de angränsande konerna. Dessa koner och blad kan behöva bestå av många trianglar för att skuggkanterna inte skall uppfattas som hackiga. Penumbra map-algoritmen kräver därmed att betydligt fler trianglar skapas och renderas. Likt skuggvolymalgoritmen för mjuka skuggor är de skuggor som penumbra map- och smoothie-algoritmen skapar endast approximationer. De skuggor som penumbra mapalgoritmen skapar kan dock anses vara mer realistiska än de skuggor smoothie-algoritmen skapar. Detta eftersom penumbra map-algoritmen använder sig av ljuskällans position och storlek för att bestämma utseendet på de koner som sedan används för att generera halvskuggområdet. I smoothie-algoritmen används i stället en användarparameter som avgör hur stora halvskuggområdena som mest kan bli. Problemet med felaktig självskuggning gäller även för dessa algoritmer. Vidare krävs flera renderingspass om ljuskällor som sprider ljus i samtliga riktningar skall hanteras. Single sample soft shadows Brabec och Seidel [Brabec02-2] har presenterat en algoritm för generering av mjuka skuggor genom att använda två texturer, en z-buffert och en identitetskarta. Den z-buffert som används fungerar på samma sätt som z-bufferten i shadow map-algoritmen, därför gäller samma resursutnyttjande för att skapa och lagra denna textur. Detta resursutnyttjande gäller även för identitetskartan, då den enda skillnaden mellan dessa texturer är att identitetskartan lagrar ett identitetsvärde per pixel där z-bufferten i stället lagrar ett avstånd. När z-bufferten och identitetskartan är skapade renderas scenen till en buffert av storleken p, dvs. samma storlek som den slutliga bilden, där varje pixel lagrar en färg och ett djupvärde. Renderingen till denna buffert ger upphov till minnestrafik motsvarande O(at). Denna buffert innehåller scenens utseende utan några skuggor. Själva arbetet för att skapa skuggor utförs på centralprocessorn. Därför måste denna buffert samt de två texturerna föras över till primärminnet där centralprocessorn kan nå dem. För varje pixel i bufferten genomförs sedan en sökning i z-bufferten, som beskrivits ovan. Hur stort område som undersöks beror på avståndet till ljuskällan. Författarna sätter dock en maximal gräns på hur många pixlar, r, som maximalt undersöks. Centralprocessorns arbete blir därmed O(pr). Författarna noterar att i områden som är helt belysta eller helt i skugga räcker det med att beräkna intensiteten på endast ett antal pixlar och sedan interpolera resultatet för angränsande pixlar. Algoritmen ger upphov till mjuka skuggor där hela halvskuggområdet skapas. Algoritmen ger dock endast upphov till approximationer av mjuka skuggor. Likt ovanstående algoritmer för mjuka skuggor samplas scenen endast från en punkt på ljuskällan, detta ger ingen korrekt bild över hur ett objekt skymmer ljuset från olika delar på en ljuskälla med area. Vidare är halvskuggområdenas storlek beroende på användardefinierade parametrar, och inte på ljuskällans storlek. De objekt och ljuskällor som hanteras är samma som i shadow map-algoritmen. De mjuka skuggorna kan även hjälpa till att dölja de hackiga skuggkanterna som ofta uppträder i shadow map-algoritmen. Algoritmen använder sig av en identitetskarta för att undvika att objekten felaktigt skuggar sig själva. Tyvärr medför detta att även korrekt självskuggning försvinner. Genom att ge olika delar av samma objekt olika identiteter kan objekten delvis skugga sig själva. Det är dock inte helt trivialt hur dessa identiteter skall tilldelas. Mjuka skuggor genom att använda PCF Uralsky [Uralsky05] har beskrivit hur mjuka skuggor kan skapas genom att använda ett stort filter när PCF används. Prestanda för denna algoritm är samma som för den ursprungliga 43

50 Utvärdering och jämförelse shadow map-algoritmen. Dock använder Uralsky ett stort filter när PCF utförs, vilket leder till ett stort antal texturuppslagningar med tillhörande minnestrafik. För att minska denna minnestrafik utnyttjar Uralsky en pixel shader med villkorlig exekvering, detta kräver hårdvara med stöd för ps 2.x. Resultatet av detta blir att det stora filtret endast används på de pixlar där skuggkanter uppstår. Resterande pixlar använder ett filter med ett mindre antal samplingspunkter, vilket minskar minnestrafiken. De mjuka skuggor som skapas är inte realistiska, utan här handlar det endast om att de hårda skuggkanterna görs suddiga och därför liknar mjuka skuggkanter. Halvskuggområdet för dessa skuggor kommer till exempel inte att ändra storlek beroende på avståndet mellan objektet som skuggar och objektet som skuggas. De ljuskällor och objekt som hanteras är samma som för shadow map-algoritmen. Percentage closer soft shadows Fernando [Fern05-1, Fern05-2] har som bekant beskrivit en modifikation av shadow mapalgoritmen som är kapabel till att skapa mjuka skuggor. Detta åstadkoms genom att en mer avancerad pixel shader används i det andra renderingspasset. Detta innebär att PCSSalgoritmen, likt shadow map-algoritmen, inte belastar centralprocessorn. Vidare hanteras alla objekt som kan renderas till en z-buffert. Modifikationen innebär även att de skuggor som skapas är mjuka, vilket i sin tur döljer de hackiga skuggkanter shadow map-algoritmen i vanliga fall ger upphov till. Algoritmen klarar även av objekt som skuggar sig själva. De skuggor som skapas är grova approximationer. Trots detta uppvisar skuggorna många egenskaper som gör dem verklighetstrogna. Till exempel minskar området som befinner sig helt i skugga när ljuskällans area ökar. Vidare ändras halvskuggområdets storlek beroende på avståndet mellan objektet som kastar skuggor och objektet som skuggas, detta inträffar inte i den algoritm Uralsky beskrev. Den pixel shader som används är relativt avancerad och kräver grafikhårdvara med stöd för ps 3.0. Som beskrivits ovan utför algoritmen 3 steg. I steg 1, som söker efter blockerande objekt, använder Fernando alltid 36 stycken samplingspunkter. Detta kan innebära att små objekt kan missas när området som undersöks är större än 36 pixlar. Detta skiljer sig från Brabec och Seidels algoritm som undersöker samtliga pixlar tills ett objekt hittas. Deras algoritm kan dock behöva söka igenom flera hundra pixlar. I steg 3, som utför PCF, används återigen ett bestämt antal samplingspunkter, denna gång samplas 64 pixlar. Sammanlagt utförs 100 texturuppslagningar per renderad pixel, vilket genererar betydligt mer minnestrafik än den vanliga shadow map-algoritmen. Algoritmens nära relation till shadow map-algoritmen gör att den även ärver några av dess svaga punkter. Den hanterar endast ljuskällor som sprider ljus inom en begränsad sektor, vidare kan felaktig självskuggning uppstå. Andra algoritmer Skuggtexturer Likt shadow map-algoritmen belastar skuggtexturalgoritmen inte centralprocessorn. Hur mycket minnestrafik och minnesutrymme algoritmen använder är svårt att svara på. När det gäller shadow map-algoritmen används en textur (z-bufferten) till vilken samtliga objekt i scenen renderas. Detta tillvägagångssätt fungerar inte i skuggtexturalgoritmen, här måste varje skuggkastande objekt renderas till en egen textur. Denna textur används sedan för att skugga övriga objekt i scenen. Skuggtexturen kan inte användas för att skugga objektet själv eftersom det skuggkastande objektet då helt skulle skugga sig själv, enligt definitionen av skuggtexturen. Detta är anledningen till att två objekt som skall kunna skugga varandra inte kan renderas till samma skuggtextur. Hur många skuggtexturer som behövs beror således på hur många skuggkastande objekt scenen innehåller. Dessa skuggtexturer behöver oftast inte vara speciellt stora eftersom endast ett objekt skall renderas till varje textur. Vidare måste varje pixel bara lagra färgen svart eller vitt, det vill säga 1 bit räcker för varje pixel. Stödet för 44

51 Utvärdering och jämförelse 1-bits texturer är dock inte speciellt spritt, vilket innebär att texturer med högre precision måste användas. De skuggor som skapas är hårda och uppvisar hackiga skuggkanter likt shadow mapalgoritmen. Ett filter kan användas vid uppslagning i skuggtexturerna för att göra skuggkanterna suddigare och därmed dölja de hackiga skuggkanterna. För varje skuggtextur som skapas, begränsas ljuskällan till att sprida ljus inom en viss sektor. Algoritmen kan dock hantera ljuskällor som sprider ljus i samtliga riktningar så länge varje enskilt objekt befinner sig inom en viss sektor runt ljuskällan. Algoritmen hanterar en stor mängd objekt, vad som krävs är helt enkelt att ett objekt kan renderas. Ett problem med skuggtexturalgoritmen är att objekten inte kan skugga sig själva. Objektidentifikation Den stora skillnaden mellan algoritmen som bygger på objektidentifikation och shadow mapalgoritmen är vad som lagras i den textur som skapas i steg 1. Shadow map-algoritmen lagrar avståndet till det objekt som befinner sig närmast ljuskällan. Objektidentifikationalgoritmen lagrar i stället identiteten på det objekt som befinner sig närmast ljuskällan. Skillnaden detta får på de skuggor som skapas är att vid objektidentifikation kan inte objekt med samma identitet skugga varandra. Fördelen med objektidentifikation är att den felaktiga självskuggning som kan uppstå i shadow map-algoritmen undviks. Shadow map - skuggvolym hybrid Chan och Durand [Chan04] har beskrivit en algoritm som använder sig av både shadow mapalgoritmen och skuggvolymalgoritmen. Shadow map-algoritmen används här för att ta reda på vilka pixlar i den resulterande bilden som befinner sig i närheten av skuggkanter. Endast på dessa pixlar utförs sedan skuggvolymalgoritmen, de övriga pixlarna ljussätts enligt shadow map-algoritmen. Resursutnyttjandet för denna hybridalgoritm är summan av resursutnyttjandet för de två algoritmer hybriden bygger på. Dock minskar minnestrafiken i skuggvolymalgoritmen drastiskt. Eftersom skuggkanter ofta utgör en liten del av den renderade bilden minskas antalet pixeluppdateringar som krävs i skuggvolymalgoritmen. Eftersom skuggvolymalgoritmen används för att skapa skuggkanterna skapas hårda skuggor utan aliasing-effekter. Vidare kan objekten skugga sig själva. Författarna rapporterar även att visuella artefakter i form av felaktig självskuggning inte inträffar. Som beskrivits ovan kan detta inträffa när shadow map-algoritmen felaktigt klassificerar en belyst pixel som skuggad. Detta sker dock oftast för enskilda pixlar, grannpixlarna kommer därför att vara belysta. Dessa pixlar kommer i hybridalgoritmen tolkas som att de befinner sig i närheten av en skuggkant. Skuggvolymalgoritmen kommer därför att användas och klassificera pixlarna på rätt sätt. Hybridalgoritmen ärver vissa nackdelar från både shadow map-algoritmen och skuggvolymalgoritmen. För det första begränsas de skuggande objekten till polygonmodeller. För det andra hanteras endast ljuskällor som sprider ljus i en begränsad sektor, och flera pass krävs för att hantera godtyckliga ljuskällor. Dessutom kan z-buffertens begränsade sampling av scenen innebära att skuggor fattas för små objekt eller delar av objekt. Algoritmen kräver relativt modern grafikhårdvara. I detta fall är det inte shader-modellerna som bestämmer vilken hårdvara som behövs, utan något som författarna kallar för beräkningsmaskering. Beräkningsmaskering innebär att en pixel kan maskeras i ett renderingspass, under senare renderingspass kommer de maskerade pixlarna inte att behandlas av grafikhårdvaran. I algoritmen används detta för att maskera de pixlar som inte befinner sig i närheten av en skuggkant. Detta får till följd att skuggvolymalgoritmen endast utförs på de pixlar som faktiskt befinner sig i närheten av en skuggkant. Även om beräkningsmaskering inte finns tillgänglig på modern grafikhårdvara, kan funktionaliteten simuleras genom att använda depth bounds. Depth bounds finns tillgänglig på GeForce 6 och senare grafikhårdvara. 45

52 Utvärdering och jämförelse Occlusion interval maps Donnelly och Demers [Donne04] algoritm för att generera mjuka skuggor använder sig av ett försteg för att minska arbetet som krävs under själva renderingsprocessen. I detta försteg skapas texturer för samtliga objekt i scenen. Dessa texturer lagrar de tidsintervall texturernas motsvarande punkter på objekten är belysta. Hur mycket minne som krävs för att lagra dessa texturer är svårt att svara på eftersom det beror mycket på scenens uppbyggnad. Generellt gäller att samtliga trianglar som kan tänkas renderas måste täckas av en sådan textur. I ett par sådana texturer kan fyra tidsintervall lagras, ena texturen lagrar de tidpunkter punkten blir belyst och den andra texturen lagrar de tidpunkter punkten blir skuggad. Många scener kan kräva fler än fyra tidsintervall, i dessa fall måste flera texturer användas. Vid renderingen av scenen används en pixel shader för att beräkna belysningen under ett litet tidsintervall, detta ger upphov till de mjuka skuggorna. Denna pixel shader kräver grafikhårdvara med stöd för ps 2.0. Algoritmen ger inte upphov till speciellt mycket minnestrafik, för enkla scener utförs endast två texturuppslagningar per renderad pixel. Mer komplexa scener kan kräva 10 eller fler texturuppslagningar per pixel [Donne04]. Ljuskällan som används är begränsad till att röra sig i en bestämd bana. De skuggor som skapas är mjuka, men som beskrivits ovan blir skuggorna endast mjuka i riktningen som är parallell med ljuskällans bana. Algoritmen fungerar trots detta bra för små ljuskällor, allt för stora ljuskällor bör dock undvikas. Skuggorna kan uppvisa aliasing-effekter, de mjuka skuggkanterna hjälper dock till att dölja dessa effekter. Algoritmen ställer inga speciella krav på de objekt som används. Dock måste scenen vara statisk, eftersom algoritmen bygger på ett försteg för att beräkna texturerna. Precomputed radiance transfer Som beskrivits ovan har Sloan m.fl. [Sloan02] presenterat en algoritm för att ljussätta föremål i realtid. Deras algoritm använder sig av ett försteg där en belysningsfunktion beräknas för varje hörn i modellen. För att representera dessa funktioner används spherical harmonics med endast ett fåtal termer. I sina exempel använder författarna 25 termer. Detta innebär att varje hörn i modellen måste lagra 25 konstanter utöver alla andra hörndata. Vid ljussättningen av objektet måste skalärprodukten mellan två 25-elements vektorer beräknas. Denna beräkning går att utföra även på de tidigaste och hårt begränsade shader-modellerna genom att utnyttja deras instruktion för att beräkna skalärprodukten av två 4-elements vektorer. Författarnas ursprungliga algoritm ger endast upphov till skuggor i form av självskuggning. Sloan m.fl. beskriver därför en utvidgning av algoritmen för att ett objekt skall kunna skugga och reflektera ljus till ett annat objekt. Denna utvidgning går ut på att försteget beräknar ytterligare en uppsättning funktioner som beskriver hur objektet ger upphov till skuggor och reflekterar ljus i sin omgivning. Dessa funktioner beräknas vid förbestämda samplingspunkter i objektets omgivning. Funktionerna är mer komplicerade än de ovan beskrivna funktionerna, här lagras i stället en matris för varje samplingspunkt. Vid rendering multipliceras denna matris med en 25 elements vektor som beskriver belysningen vid punkten. Detta ger upphov till en ny 25 elements vektor som beskriver hur objektet reflekterar och skuggar ljuset vid denna punkt. Denna matrismultiplikation kräver betydligt fler instruktioner än den ovan beskrivna skalärprodukten, vilket ger en prestandasänkning. Ett problem med metoden som författarna nämner är att det inte är helt lätt att kombinera skuggor och reflektioner från flera objekt. Ett annat problem är att skuggornas kvalitet och utsträckning är beroende av hur stort område runt objektet som samplas och antalet samplingspunkter som används. Algoritmen kan endast ge upphov till mjuka skuggor. Anledningen till detta är att endast ett fåtal termer används för att approximera belysningsfunktionerna, vilket medför att högfrekventa ljusförändringarna inte kan representeras. En stor fördel med algoritmen är att den hanterar ljus som infaller ifrån samtliga riktningar. När det gäller de objekt som hanteras beror det på hur försteget implementeras, eftersom det är detta steg som bestämmer hur skuggor kastas. 46

53 Utvärdering och jämförelse Skuggfält Skuggalgoritmen som bygger på skuggfält [Zhou05] påminner en hel del om den ovan beskrivna utvidgningen av PRT-algoritmen. I skuggfältalgoritmen används likt PRTalgoritmen ett antal samplingspunkter i objektets omgivning. För varje samplingspunkt skapas i ett försteg en cube map som beskriver hur ljus i olika riktningar skyms av objektet. Ljuskällor hanteras på liknande sätt men här lagrar varje cube map i stället hur mycket ljus som sprids i de olika riktningarna. Att lagra alla dessa cube maps skulle kräva mycket minnesutrymme, författarna använder sig därför av spherical harmonics för att komprimera dessa data. Med denna komprimering rapporterar författarna att ett skuggfält för ett objekt upptar 384 KB. Fälten för ljuskällor som måste lagra tre värden, upptar 1 MB. Detta innebär att minnesutrymmet som krävs är beroende av hur många objekt scenen innehåller. Notera dock att minnesutrymme för endast ett skuggfält krävs, även om samma objekt återfinnes på flera platser i scenen. Algoritmen lider av liknande problem som PRT-algorimten. Genom den kraftiga kompressionen kan endast lågfrekventa ljusförändringar representeras, vilket kan resultera i skuggor som uppträder alldeles för mjuka. Skuggornas utsträckning är även beroende på hur stort område runt objektet som samplas i försteget. Författarna har även implementerat en variant av algoritmen som kan representera högfrekventa ljusförändringar. Denna modifikation kräver dock betydligt mer lagringsutrymme och beräkningskapacitet, och lämpar sig inte i realtidssammanhang. Till skillnad från PRT-algoritmen kan skuggfältalgoritmen snabbt använda data från försteget för att kombinera skuggfält från olika objekt och ljuskällor. Detta gör att algoritmen lämpar sig bra för dynamiska miljöer. Hur mycket av algoritmen som kan exekvera på grafikhårdvaran framgår inte av rapporten av Zhou m.fl. Men eftersom själva renderingssteget kräver global information i form av samtliga objekt och ljuskällor i scenen samt deras förhållande till varandra, talar mycket för att stora delar av algoritmen exekverar på centralprocessorn. Eftersom ljuskällorna representeras genom ett eget skuggfält (ljusfält), kan många olika typer av ljuskällor representeras. Vidare hanterar algoritmen belysning i form av en environment map som omger scenen. Självskuggning hanteras likt PRT-algoritmen, där varje hörn lagrar en funktion som beskriver hur hörnet skyms av objektet själv. Tabeller Nedan följer tre tabeller som sammanfattar utvärderingen. Dessa tabeller kan användas för att jämföra de olika skuggalgoritmerna. Tabell 3 sammanfattar algoritmernas resursutnyttjande. Tabell 4 sammanfattar kvaliteten på de skuggor algoritmerna ger upphov till. Tabell 5 sammanfattar slutligen hur generella algoritmerna är. 47

54 Utvärdering och jämförelse Tabell 3: Denna tabell sammanfattar skuggalgoritmernas resursutnyttjande. Algoritm Skuggvolym - Crow Skuggvolym på GPU - Everitt Skuggvolym på GPU - Brabec och Seidel CC skuggvolum Skuggvolym för mjuka skuggor Shadow map Perspective-, light space perspective- och trapezoidal shadow map Shadow silhouette map Penumbra map och smoothie Single sample soft shadow Mjuka skuggor genom PCF Percentage closer soft shadows Skuggtextur Objektidentifikation Shadow map - skuggvolym hybrid Occlusion interval maps Precomputed radiance transfer Skuggfält Sammanfattning av resursutnyttjande O(t) arbete på centralprocessorn, för att rendera skuggpolygonerna genereras minnestrafik motsvarande O(pe+at), kräver inga shaders Belastar inte centralprocessorn, minnestrafik likt Crows algoritm, måste bearbeta fler hörn än Crows algoritm, kräver vs 1.1 Belastar inte centralprocessorn, minnestrafik likt Crows algoritm, måste lagra flyttalstextur av storlek O(t), kräver vs 3.0 Belastar centralprocessorn mer än Crows algoritm, minskar den minnestrafik som genereras när skuggpolygonerna renderas, kräver inga shaders O(t) arbete för att skapa skuggpolygoner och kilar, vid rendering av skuggpolygoner och kilar skapas minnestrafik likt Crows algoritm, kräver extra minne för att lagra V-buffert och förberäknade texturer, kräver ps 2.0 Belastar inte centralprocessorn, genererar minnestrafik motsvarande O(atn/p+atc), måste lagra z-buffert av storlek O(n), kräver inga shaders Kräver en del arbete av centralprocessorn, utöver detta är resursutnyttjandet som i shadow map-algoritmen Centralprocessorn används för att hitta siluettkanter vilket har beräkningskomplexiteten O(t), utöver detta är resursutnyttjandet nästan det dubbla av shadow map-algoritmens, kräver ps 2.0 Utnyttjar resurser på samma sätt som shadow silhouette map-algoritmen, penumbra map-algoritmen kan dock ge upphov till fler renderade trianglar, kräver ps 2.0 O(pr) arbete på centralprocessorn för att skapa skuggorna, för att skapa identitetskarta och z-buffert är resursutnyttjandet det dubbla av shadow map-algoritmens, kräver inga shaders Samma resursutnyttjande som shadow map-algoritmen med ett stort filter (c), kräver ps 2.x Utnyttjar resurser på samma sätt som shadow map-algoritmen, PCSSalgoritmen genererar dock mer minnestrafik när skuggorna skapas, kräver ps 3.0 Belastar inte centralprocessorn, varje skuggkastande objekt kräver en egen textur, kräver inga shaders Samma resursutnyttjande som shadow map-algoritmen Resursutnyttjandet är summan av resursutnyttjandet för shadow map- och skuggvolymalgoritmen, dock minskar minnestrafiken i skuggvolymalgoritmen, kräver modern grafikhårdvara Belastar inte centralprocessorn, kräver mycket minnesutrymme för att lagra texturerna med tidsintervall, kräver ps 2.0 Belastar inte centralprocessorn vid rendering, måste lagra 25 konstanter per hörn utöver all annan hörndata, kräver ps 1.4 Kräver mycket minnesutrymme, måste lagra data för varje hörn likt PRTalgoritmen, vidare måste ett skuggfält lagras för varje objekt och ljuskälla 48

55 Utvärdering och jämförelse Tabell 4: Denna tabell beskriver de visuella artefakter skuggalgoritmerna kan ge upphov till, samt vilken typ av skuggor algoritmerna genererar. Algoritm Skuggors mjukhet Visuella artefakter Skuggvolym - Crow Hårda skuggor - Skuggvolym på GPU - Everitt Skuggvolym på GPU - Brabec och Seidel Hårda skuggor - Hårda skuggor - CC skuggvolym Hårda skuggor - Skuggvolym för mjuka skuggor Mjuka skuggor, hela halvskuggområdet - Shadow map Hårda skuggor Hackiga skuggkanter, felaktig självskuggning, kan missa små objekt eller delar av objekt Perspective-, light space perspective- och trapezoidal shadow map Hårda skuggor Felaktig självskuggning, ibland hackiga skuggkanter, kan missa små objekt eller delar av objekt Shadow silhouette map Hårda skuggor Felaktig självskuggning, hackiga skuggkanter i vissa områden, kan missa små objekt eller delar av objekt Penumbra map och smoothie Mjuka skuggor, yttre halvskuggområdet Single sample soft shadow Mjuka skuggor, hela halvskuggområdet Mjuka skuggor genom PCF Percentage closer soft shadows Mjuka skuggkanter genom att göra skuggkanterna suddigare Mjuka skuggor, hela halvskuggområdet Felaktig självskuggning, skarpa skuggkanter kan vara hackiga, kan missa små objekt eller delar av objekt Skarpa skuggkanter kan vara hackiga, kan missa små objekt eller delar av objekt Felaktig självskuggning, kan missa små objekt eller delar av objekt Felaktig självskuggning, skarpa skuggkanter kan vara hackiga, kan missa små objekt eller delar av objekt Skuggtextur Hårda skuggor Hackiga skuggkanter, kan missa små objekt eller delar av objekt Objektidentifikation Hårda skuggor Hackiga skuggkanter, kan missa små objekt eller delar av objekt Shadow map - skuggvolym hybrid Occlusion interval maps Precomputed radiance transfer Hårda skuggor Mjuka skuggor i riktning parallell med ljuskällans bana Mjuka skuggor Kan missa små objekt eller delar av objekt Skarpa skuggkanter kan vara hackiga Inga skarpa skuggkanter kan återges Skuggfält Mjuka skuggor Inga skarpa skuggkanter kan återges 49

56 Utvärdering och jämförelse Tabell 5: Denna tabell sammanfattar skuggalgoritmernas förmåga att hantera objekt, självskuggning och ljuskällor. Algoritm Objekt som hanteras Självskuggning Ljuskällor Skuggvolym - Crow Skuggvolym på GPU - Everitt Skuggvolym på GPU - Brabec och Seidel CC skuggvolym Skuggvolym för mjuka skuggor Shadow map Perspective-, light space perspectiveoch trapezoidal shadow map Shadow silhouette map Penumbra map och smoothie Single sample soft shadow Mjuka skuggor genom PCF Percentage closer soft shadows Skuggtextur Objektidentifikati on Shadow map - skuggvolym hybrid Occlusion interval maps Precomputed radiance transfer Objekt uppbyggda av polygoner Endast begränsade objekt uppbyggda av polygoner Endast begränsade objekt uppbyggda av polygoner Objekt uppbyggda av polygoner Objekt uppbyggda av polygoner Objekt som kan renderas till en z-buffert Objekt som kan renderas till en z-buffert Objekt uppbyggda av polygoner Objekt uppbyggda av polygoner Objekt som kan renderas till en z-buffert Objekt som kan renderas till en z-buffert Objekt som kan renderas till en z-buffert Objekt som kan renderas Objekt som kan renderas till en z-buffert Objekt uppbyggda av polygoner Godtyckliga objekt, statisk scen Godtyckliga objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar endast andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar endast andra objekt Skuggar endast andra objekt Skuggar sig själv och andra objekt Skuggar sig själv och andra objekt Skuggar endast sig själv Skuggfält Godtyckliga objekt Skuggar sig själv och andra objekt Hanterar ljuskällor som sprider ljus i samtliga riktningar Hanterar ljuskällor som sprider ljus i samtliga riktningar Hanterar ljuskällor som sprider ljus i samtliga riktningar CC skuggvolymer skapas endast inom en begränsad sektor runt ljuskällan Hanterar ljuskällor som sprider ljus i samtliga riktningar Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor För varje enskilt objekt hanteras endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar endast ljuskällor som sprider ljus inom en begränsad sektor Hanterar ljuskällor som rör sig i en bestämd bana Hanterar ljuskällor som sprider ljus i samtliga riktningar, hanterar även belysning beskrivet av en environment map Hanterar ljuskällor som sprider ljus i samtliga riktningar, hanterar även belysning beskrivet av en environment map 50

57 Rekommenderade algoritmer Rekommenderade algoritmer I detta kapitel kommer jag att presentera de algoritmer jag rekommenderar uppdragsgivaren Scalo AB att använda i deras VR-applikation. Scalo AB har redan en existerande VRapplikation i vilken de vill implementera stöd för skuggor. Detta innebär att denna applikation måste undersökas för att se vilka objekt och ljuskällor som måste stödjas. Vidare är det bra att veta om applikationen sätter stopp för vissa algoritmer genom att t.ex. sakna stöd för vertexoch pixel shaders, rendera till textur-funktionalitet osv. Nedan kommer jag därför att kort beskriva den existerande VR-applikationen. Därefter ger jag förslag på de algoritmer jag anser passa applikationen bäst. Virtual terrain project Uppdragsgivaren Scalo AB bygger sin programvara på en öppen mjukvara som heter Virtual terrain project (VTP). VTP består av en samling verktyg som kan användas för att konstruera och visa upp virtuella 3D-världar. Ett av dessa verktyg är Enviro, vilket är en VR-applikation för att visa upp dessa virtuella 3D-världar. Det är denna applikation som skall utvidgas med stöd för skuggor för de 3D-objekt som läggs in i 3D-världarna. De miljöer som används i VTP är utomhusmiljöer där solen är den enda ljuskällan. Detta innebär att ljuskällan endast sprider ljus inom en begränsad sektor. När det gäller de objekt som läggs in i 3D-världen används tekniken med genomskinliga polygoner, som beskrivits ovan, för att skapa vägräcken och dylikt. För rendering av 3D-miljöerna använder VTP i sin tur en annan öppen mjukvara, nämligen OpenSceneGraph (OSG). OSG är en avancerad scengraf som bygger på OpenGL. Den har stöd för många av de funktioner som modern grafikhårdvara tillhandahåller, t.ex. vertex- och pixel shaders och rendera till textur-funktionalitet. Möjligheten att rendera till en flyttalstextur verkar dock inte fungera fullt ut än. Men att döma av alla förfrågningar av denna funktion på deras e-postlista, bör även stödet för denna funktion vidareutvecklas inom en snar framtid. Existerande algoritm Från ovan kan fastslås att det är viktigt att skuggalgoritmen kan hantera genomskinliga polygoner. Vad gäller ljuskällor krävs endast av algoritmen att den hanterar ljuskällor som sprider ljus i en begränsad sektor, vilket samtliga ovannämnda algoritmer klarar av. Att objekten kan skugga sig själva är viktigt eftersom Scalo AB använder sig av ett fåtal stora objekt i sina miljöer. Självskuggning utgör här en stor del av skuggeffekterna. Andra önskvärda egenskaper av algoritmen är lågt resursutnyttjande. Speciellt önskvärt är lågt utnyttjande av centralprocessorn, då denna redan används i VTP för att skapa 3D-landskapen. Inför framtiden kan det även vara önskvärt att algoritmen hanterar dynamiska miljöer. Detta kan användas för att t.ex. skapa skuggor för fordon i 3D-miljöerna. Utvärderingen ovan kan nu användas för att ge förslag på algoritmer. Det viktiga är att algoritmerna kan hantera genomskinliga polygoner och självskuggning. Nedan kommer jag att diskutera de algoritmer som uppfyller dessa krav. Skuggfält och PRT-algoritmen uppfyller kraven. Dessa algoritmer lider dock av problemet att de skuggor som skapas alltid är mjuka. Även om mjuka skuggor är att föredra för att skapa realistiska bilder, bör skuggornas mjukhet avspegla arean på ljuskällan. I utomhusmiljöer där solen utgör ljuskällan är arean liten och skuggorna bör därför inte vara för mjuka. Occlusion interval maps är en annan algoritm som passar bra med de villkor som gäller. En nackdel med denna algoritm är att en applikation som implementerar försteget måste skapas. Detta kan vara en ganska omfattande uppgift. Vidare utnyttjar algoritmen mycket grafikminne och den hanterar inte dynamiska miljöer. 51

58 Rekommenderade algoritmer De algoritmer som återstår är shadow map-algoritmen och dess modifieringar. Den ursprungliga shadow map-algoritmen lämpar sig dock inte speciellt bra eftersom de scener som skall hanteras är stora utomhusscener. Detta innebär att z-bufferten måste täcka in ett stort område vilket ökar risken för aliasing effekter. Detta gäller även för algoritmer som PCSS då de mjuka skuggkanterna inte klarar av att dölja för grova aliasing effekter. Vad som återstår är då perspective-, light space perspective- och trapezoidal shadow mapalgoritmerna. Dessa algoritmer fungerar bra i stora utomhusscener eftersom de förvränger scenerna och därmed samplar objekten nära kameran bättre, detta resulterar i att z-bufferten utnyttjas bättre. Av de tre algoritmerna är trapezoidal shadow map-algoritmen att föredra av framför allt två anledningar. För det första belastar algoritmen inte centralprocessorn lika mycket som de andra algoritmerna. För det andra håller skuggorna en jämnare kvalitet. Kom ihåg att i perspective- och light space perspective shadow map algoritmerna kan skuggkvaliteten ändras drastiskt när ett skuggkastande objekt hamnar bakom kameran. Trapezoidal shadow map-algoritmen är därför den algoritm jag rekommenderar. Trapezoidal shadow map-algoritmen, och även perspective- och light space perspective shadow map-algoritmerna, har dock en gemensam nackdel: algoritmerna skapar endast hårda skuggor. Jag har därför utarbetat en ny algoritm för att skapa suddiga, och mjuka, skuggor i stora utomhusmiljöer. Denna algoritm beskrivs i nästa avsnitt. Det bör även nämnas att trapezoidal shadow map-algoritmen är patenterad, vilket komplicerar integreringen i en kommersiell produkt. Ny algoritm Bakgrund Som beskrivits ovan kan trapezoidal-, perspective- och light space perspective shadow mapalgoritmerna användas för att generera skuggor för generella objekt i stora utomhusmiljöer. Dessa algoritmer används dock för att skapa hårda skuggor. Detta är problematiskt av två anledningar. För det första återfinns vissa aliasing-effekter även för dessa algoritmer. Dessa aliasingeffekter uppträder som hackiga skuggkanter när hårda skuggor genereras. För det andra kan skuggor med hårda skuggkanter i vissa fall uppfattas som detaljer på ytan av ett objekt i stället för skuggor [Aken02]. Om skuggkanterna kunde göras suddiga skulle aliasing-effekterna döljas och skuggorna skulle smälta in i scenen. Ovan har beskrivits hur PCF kan användas för att åstadkomma just detta. PCF kan dock inte direkt användas i samband med trapezoidal-, perspective- och light space perspective shadow map-algoritmerna. Problemet ligger här i att dessa algoritmer applicerar en transformationsmatris på scenen innan den samplas. Denna transformationsmatris förstorar objekt som befinner sig nära kameran, och förminskar objekt som befinner sig långt ifrån kameran. Den transformerade scenen renderas sedan med kameran placerad på ljuskällans position. Figur 26 ovan illustrerar detta förfarande, och figur 26b visar hur ljuskällan ser scenen. Stora objekt nära kameran kommer att uppta ett stort antal pixlar, medan små objekt långt ifrån kameran endast kommer att uppta ett fåtal pixlar. Vid PCF används ett lika stort filter för samtliga punkter som renderas, vilket leder till problem. För objekt nära kameran innebär detta att de suddiga skuggkanterna kommer att bli små i förhållande till objektens storlek. För objekt långt ifrån kameran kommer de suddiga skuggkanterna däremot att bli stora i förhållande till objektens storlek. Figur 30a illustrerar hur ett filter appliceras på den samplade transformerade scenen för att skapa suddiga skuggkanter. Figur 30b visar dessa skuggors utseende i den ursprungliga scenen. För PCSS-algoritmen, som bygger på PCF, kommer halvskuggområdenas storlek på samma sätt att variera med objektens avstånd från kameran, vilket inte är korrekt. 52

59 Rekommenderade algoritmer a) b) Figur 30 a): Om ett filter appliceras på den samplade scenen görs de skarpa kanterna suddiga. b): Skuggornas utseende om filtret i a) används. Notera att de suddiga skuggkanterna har olika storlek. Vad som behövs för att skapa lika stora halvskuggområden för alla objekt är ett filter vars storlek varierar med avståndet från kameran. Detta skulle innebära att filtrets storlek och form skulle behöva beräknas för varje pixel som renderas. För att undgå dyra beräkningar per pixel valde jag ett annat angreppssätt. Vad som i praktiken händer när ovanstående transformationsmatris appliceras på scenen är att samplingstätheten av scenen varierar kontinuerligt med avståndet från kameran. Denna kontinuerliga variation innebär att filtrets storlek måste bestämmas för varje pixel. Mitt förslag är att i stället endast använda ett fåtal samplingstätheter. Med endast ett fåtal samplingstätheter behövs endast ett fåtal filterstorlekar. En pixel shader kan då användas för att snabbt välja vilken av dessa filterstorlekar som skall användas när en pixel renderas. Metoden För att åstadkomma denna diskreta uppdelning i samplingtätheter använder jag flera z- buffertar. Användningen av flera z-buffertar har även föreslagits av andra författare [Game05, Happy04]. Varje z-buffert samplar här scenen enhetligt, olika z-buffertar samplar dock olika stora delar av scenen. Den första z-bufferten samplar endast ett litet område nära kameran. Nästa z-buffert samplar ett större område och så vidare. Figur 31 illustrerar en scen som samplas med tre stycken z-buffertar. Figur 35a visar den resulterande scenen innehållande skuggor. Användningen av flera z-buffertar på detta sätt får en liknande effekt som samplingen i trapezoidal-, perspective- och light space perspective shadow map-algoritmerna. Objekt som befinner sig nära kameran kommer att samplas noggrannare och uppta fler pixlar i z-bufferten än objekt som befinner lång ifrån kameran. Vid rendering till z-buffertarna måste varje buffert ha två matriser, en vymatris och en projektionsmatris, som beskriver hur kameran skall placeras i scenen och vilka delar som skall samplas. När vymatrisen skapas är det viktigt att se till att de områden av scenen som samplas motsvarar de områden användaren beskådar. Den metod jag använder för att åstadkomma detta är att projicera ner användarkamerans position på markplanet. Därefter samplas området framför denna punkt, se figur

60 Rekommenderade algoritmer Första z-bufferten Andra z-bufferten Tredje z-bufferten a) b) c) d) Figur 31 a): Bilden visar hur de olika z-buffertarna samplar scenen. b): Bilden visar hur scenen renderas med vy- och projektionsmatriserna för första z-bufferten applicerade. c) och d) visar på motsvarande sätt hur scenen renderas med vy- och projektionsmatriser för den andra respektive den tredje z-bufferten. Kamera Område som samplas av första z-bufferten Område som samplas av andra z-bufferten Område som samplas av tredje z-bufferten Figur 32: Figuren visar hur de olika z-buffertarna samplar scenen. Projektionsmatrisen avgör hur stor del av scenen som samplas. Här använder jag en ortografisk projektion, där bredden på projektionen är en användarparameter. Som figur 33 visar måste hänsyn tas till vinkeln mellan det infallande ljuset och markplanet när projektionsmatrisen skapas, detta för att det område som samplas skall vara lika stort oberoende av hur ljuset infaller. För att åstadkomma detta måste höjden på projektionen minskas när vinkeln minskar. Figur 34 visar sambandet mellan storleken på det område som samplas och höjden på projektionen. Om x sätts till samma värde som bredden på projektionen, vilket innebär att ett kvadratiskt område kommer att samplas, kan följande formel användas för att beräkna höjden på projektionen: h = sin(α ) x. 54

61 Rekommenderade algoritmer Vy-volym Vy-volym Område som samplas Figur 33: När vinkeln mellan det infallande ljuset och markplanet är liten (till höger) kommer ett större område att samplas än om ljuset infaller vinkelrätt mot markplanet (till vänster). h α x Figur 34: Figuren illustrerar sambandet mellan höjden på projektionen (h), storleken på det område som samplas (x) och vinkeln mellan det infallande ljuset och markplanet (α). Vid generering av skuggorna krävs uppslagningar i en z-buffert. Här används den första z- buffert vars samplingsområde omsluter den punkt som renderas. Likt steg 2 i shadow mapalgoritmen beräknas screen space-koordinaterna för den renderade punkten när scenen beskådas ur ljuskällans synvinkel. Eftersom olika vyer används för de olika z-buffertarna måste screen space-koordinater beräknas för varje vy. En pixel shader använder sedan dessa screen space koordinater för att välja vilken z-buffert som skall användas. Denna pixel shader bestämmer även vilken filterstorlek som skall användas när PCF utförs. Min implementering använder tre z-buffertar, där varje z-buffert samplar ett fyra gånger så stort område som föregående z-buffert. För varje ökat samplingsområde minskas även filterstorleken med en fjärdedel. Resultatet av detta är att storleken på de suddiga skuggkanterna kommer att vara konstant i hela scenen, detta är precis vad som eftersträvas. De suddiga skuggkanterna hjälper även till att dölja skarvarna mellan de olika z-buffertarna. En fördel denna algoritm har i förhållande till trapezoidal-, light space perspective- och perspective shadow map-algoritmerna är att skuggornas kvalitet inte är beroende av hur kameran riktas. I light space perspective- och perspective shadow map-algoritmerna kan skuggornas kvalitet drastiskt ändras när ett skuggkastande objekt hamnar bakom kameran. Även i trapezoidal shadow map-algoritmen kan skuggkvaliteten ändras, här sker dock inga 55

62 Rekommenderade algoritmer drastiska förändringar. I min algoritm har samplingsområdena lika stor yta oberoende av hur kameran är riktad, vilket innebär att skuggkvaliteten inte ändras. Vid uppdateringen av de olika z-buffertarna måste scenen renderas flera gånger. Även om själva uppdateringen av en z-buffert inte är speciellt dyr, kan transporten av scendata över PCI express-bussen begränsa algoritmens prestanda. För att minska denna kommunikation har jag valt att uppdatera z-buffertarna med olika intervaller. Den första z-bufferten uppdateras vid varje renderad bild, den andra z-bufferten uppdateras vid varannan renderad bild och den tredje z-bufferten uppdateras vid var tredje renderad bild. Genom att uppdatera z-buffertarna på detta vis kan algoritmens prestanda ökas. Tester har visat att prestandaökningen är som störst när ett litet filter används vid PCF. När ett stort filter används begränsas prestanda i stället av minnestrafiken som genereras vid texturuppslagningarna. Utvärdering När det gäller algoritmens resursutnyttjande finns många likheter med shadow mapalgoritmen när ett stort filter används. Centralprocessorn används endast för att beräkna vyoch projektionsmatriserna för de olika z-buffertarna. Algoritmen kräver mer minnesutrymme än shadow map-algoritm för att lagra z-buffertarna. Minnestrafiken ändras dock inte mycket eftersom samma texturuppslagningar fortfarande äger rum. Algoritmen kräver modern grafikhårdvara med stöd för ps 2.x för att hantera stora filterstorlekar. Stöd för villkorlig exekvering kan även öka prestanda, då pixlar som använder de senare z-buffertarna använder ett mindre filter. Om mindre filter används och algoritmen implementeras genom att rendera scenen i flera pass bör även äldre grafikhårdvara med stöd för ps 2.0 kunna användas. De objekt och ljuskällor som stöds är samma som i shadow map-algoritmen. Vidare kan problemet med felaktig självskuggning fortfarande uppstå. De skuggor som skapas har samma karaktär som hårda skuggor, men skuggkanterna är suddiga vilket gör att skuggorna mer realistiskt smälter in i scenen. Algoritmen kan dock utvidgas till att använda PCSSalgoritmen för att skapa mer realistiska mjuka skuggor. Detta åstadkoms genom att variera storleken på sökområdet i PCSS-algoritmen på samma sätt som filterstorleken vid PCF. Figur 35 visar scenen i figur 31 renderad genom att använda PCF och PCSS. Skuggorna i figur 35b anses vara mer realistiska än skuggorna i figur 35a eftersom halvskuggområdets storlek varierar med avståndet mellan skuggat och skuggkastande objekt. En nackdel med denna algoritm är att den inte är garanterad att täcka in hela det område som kameran ser. Detta kan innebära att objekt som befinner sig långt bort inte skuggas. När kameran befinner sig nära marken är detta oftast inget problem, då andra objekt som t.ex. träd skymmer avlägsna objekt. När kameran flyttas högt över marken för att ge en överblicksbild märks dock att skuggor endast genereras för objekt nära kameran. Jag har på grund av detta implementerat en modifikation av algoritmen som ökar storleken på de områden som samplas (figur 32) när kamerans avstånd från marken ökar. Fler avlägsna objekt kommer då att generera skuggor. En nackdel med denna modifikation är att skuggornas kvalitet nu kan ändras när kameran förflyttar sig. Eftersom kameran rör sig bort ifrån skuggorna uppfattas mindre detaljer i skuggkanterna vilket leder till att användaren oftast inte märker av kvalitetsändringen. Algoritmen fungerar bäst i plana landskap. I kuperade landskap eller landskap där objekt befinner sig högt över marken kan vissa skuggor saknas. Detta inträffar speciellt när vinkeln mellan det infallande ljuset och markplanet är liten, och beror på att z-buffertarna riktas in på markplanet. Slutligen har algoritmen problem att hänga med i applikationer innehållande hastiga rörelser. Detta beror på att de stora uppdateringsintervallerna för vissa z-buffertar kan leda till att skuggornas rörelse uppträder hackigt när ljuskällan eller objekten i scenen hastigt förflyttar sig. Genom att uppdatera alla z-buffertar för varje renderad bild uppstår inte detta problem, detta genererar emellertid aningen mer minnestrafik. 56

63 Rekommenderade algoritmer a) b) Figur 35 a): Scenen i figur 31 renderad med PCF. b): Samma scen som i a) renderad med PCSS, notera att halvskuggans storlek ökar när avståndet mellan marken och pelaren ökar. 57

64 Rekommenderade algoritmer Figur 36 visar skuggalgoritmen när den används i VTP för att skapa skuggor i ett projekt av Scalo AB. a) b) Figur 36 a): En scen från VTP vid en tidpunkt mitt på dagen. b): Samma scen som i a) vid en tidpunkt på morgonen då solen inte står lika högt. 58

Shaders. Renderingssystem. Renderingssystem. Renderingssystem. Hårdvara för 3D-rendering. Hårdvara för 3D-rendering

Shaders. Renderingssystem. Renderingssystem. Renderingssystem. Hårdvara för 3D-rendering. Hårdvara för 3D-rendering Shaders Renderingssystem Applikation Geometri Rastrering Martin Fitger d00-mfi@d.kth.se VT 2008, DH2323 / DH2640 / NA8740 Renderingssystem Renderingssystem Applikation Per-vertex operationer Geometri Rastrering

Läs mer

PROCEDUELL TERRÄNG. Proceduella metoder för bilder (TNM084) Jimmy Liikala Institutionen för teknik och naturvetenskap

PROCEDUELL TERRÄNG. Proceduella metoder för bilder (TNM084) Jimmy Liikala Institutionen för teknik och naturvetenskap PROCEDUELL TERRÄNG Proceduella metoder för bilder (TNM084) Jimmy Liikala (jimli570@student.liu.se) Institutionen för teknik och naturvetenskap Sammanfattning Rapporten beskriver hur en proceduell terräng

Läs mer

Grafiska pipelinens funktion

Grafiska pipelinens funktion LUNDS TEKNISKA HÖGSKOLA CAMPUS HELSINGBORG Grafiska pipelinens funktion Ludvig von Sydow EDT62, HT17 Datorarkitekturer med Operativsystem Sammanfattning Denna rapport syftar till att beskriva hur en graphics

Läs mer

Shaders. Gustav Taxén

Shaders. Gustav Taxén Shaders Gustav Taxén gustavt@csc.kth.se 2D1640 Grafik och Interaktionsprogrammering VT 2007 Shading l 2 P l 1 n v Givet en punkt P på en yta, en normal n, riktningsvektorer l i mot ljuskällor och en kamerariktning

Läs mer

Grafiska pipelinen. Edvin Fischer

Grafiska pipelinen. Edvin Fischer Grafiska pipelinen Edvin Fischer Sammanfattning Rapporten behandlar den grafiska pipelinen och dess steg, vilka stegen är och hur de funkar. Inledning Rapporten har till syfte att beskriva hur den grafiska

Läs mer

Avalanche Studios. OpenGL. Vår teknik. Våra spel. Lite inspiration... Stora, öppna spelvärldar. Sandbox-gameplay. Hög audiovisuell standard

Avalanche Studios. OpenGL. Vår teknik. Våra spel. Lite inspiration... Stora, öppna spelvärldar. Sandbox-gameplay. Hög audiovisuell standard OpenGL Avalanche Studios Sveriges ledande oberoende spelutvecklare Fokus på egenutvecklade IPn Finns på Söder i Stockholm ~6 anställda Just Cause för PS2, PC, XBox, och XBox 36 släpptes 26 Gustav Taxén

Läs mer

Procedurell Terräng med LOD i OpenGL 4

Procedurell Terräng med LOD i OpenGL 4 Procedurell Terräng med LOD i OpenGL 4 TNM084: Proceduella metoder för bilder ITN, Linköpings universitet Lucas Correia, lucco863@student.liu.se Bakgrund Terräng är ett tydligt exempel där procedurella

Läs mer

Procedurell 3D-eld på grafikkortet

Procedurell 3D-eld på grafikkortet Procedurell 3D-eld på grafikkortet TNM084 Procedurella metoder för bilder Anders Hedblom, andhe893@student.liu.se 2012-04-04 1. Bakgrund 1.1. Procedurella metoder Procedurella metoder har ett stort användningsområde

Läs mer

LUNDS UNIVERSITET. Parallell exekvering av Float32 och INT32 operationer

LUNDS UNIVERSITET. Parallell exekvering av Float32 och INT32 operationer LUNDS UNIVERSITET Parallell exekvering av Float32 och INT32 operationer Samuel Molin Kursansvarig: Erik Larsson Datum 2018-12-05 Referat Grafikkort utför många liknande instruktioner parallellt då typiska

Läs mer

Tentamen TNM061, 3D-grafik och animering för MT2. Tisdag 3/ kl 8-12 TP51, TP52, TP54, TP56, TP41, TP43. Inga hjälpmedel

Tentamen TNM061, 3D-grafik och animering för MT2. Tisdag 3/ kl 8-12 TP51, TP52, TP54, TP56, TP41, TP43. Inga hjälpmedel Tentamen TNM061, 3D-grafik och animering för MT2 Tisdag 3/6 2014 kl 8-12 TP51, TP52, TP54, TP56, TP41, TP43 Inga hjälpmedel Tentamen innehåller 8 uppgifter, vilka tillsammans kan ge maximalt 50 poäng.

Läs mer

Grafik raytracing. Mattias Axblom.

Grafik raytracing. Mattias Axblom. Grafik raytracing Mattias Axblom mam11003@student.mdh.se 1 SAMMANFATTNING Raytracing, strålföljning eller strålspårning är en metod för att rendera realistiska bilder, film och i framtiden spel. Grundidén

Läs mer

Realtidsalgoritmer för ljusets spridning och absorption mot partiklar i luften P E T E R L Ö N N Q U I S T

Realtidsalgoritmer för ljusets spridning och absorption mot partiklar i luften P E T E R L Ö N N Q U I S T Realtidsalgoritmer för ljusets spridning och absorption mot partiklar i luften P E T E R L Ö N N Q U I S T Examensarbete Stockholm, Sverige 2006 Realtidsalgoritmer för ljusets spridning och absorption

Läs mer

Procedurell renderingsmotor i Javascript och HTML5

Procedurell renderingsmotor i Javascript och HTML5 Procedurell renderingsmotor i Javascript och HTML5 TNM084 Procedurella Metoder för bilder Gustav Strömberg - gusst250@student.liu.se http://gustavstromberg.se/sandbox/html5/shademe/texture_stop_final.html

Läs mer

Tentamen TNM061, 3D-grafik och animering för MT2. Onsdag 20/ kl SP71. Inga hjälpmedel

Tentamen TNM061, 3D-grafik och animering för MT2. Onsdag 20/ kl SP71. Inga hjälpmedel Tentamen TNM061, 3D-grafik och animering för MT2 Onsdag 20/8 2014 kl 14-18 SP71 Inga hjälpmedel Tentamen innehåller 7 uppgifter, vilka tillsammans kan ge maximalt 50 poäng. För betyg G (registreras som

Läs mer

Rastrering och displayalgoritmer. Gustav Taxén

Rastrering och displayalgoritmer. Gustav Taxén Rastrering och displayalgoritmer Gustav Taxén gustavt@csc.kth.se 2D1640 Grafik och Interaktionsprogrammering VT 2007 Klippning Man vill undvika att rastrera de primitiver som hamnar utanför fönstret. Man

Läs mer

Information Coding / Computer Graphics, ISY, LiTH

Information Coding / Computer Graphics, ISY, LiTH 12(73) Shadow maps/skuggmappning Mycket populär skuggningsmetod Två renderingar av scenen Beräkning för beslut i fragmentshader Mycket beräkningar (filter) för god kvalitet Fördel: Behöver ingen kunskap

Läs mer

OpenGL AGI HT05. Gustav Taxén

OpenGL AGI HT05. Gustav Taxén OpenGL AGI HT05 Gustav Taxén gustavt@nada.kth.se OpenGL-översikt Geometri Operationer på hörn Rastrering Operationer på fragment Bilddata Operationer på bildelement Texturminne Framebuffert (bildbuffert

Läs mer

Procedurell grottgenerator och eld i GLSL. Marcus Widegren

Procedurell grottgenerator och eld i GLSL. Marcus Widegren Procedurell grottgenerator och eld i GLSL Marcus Widegren 14 januari 2012 Innehåll 2 Sammanfattning Jag har gjort en enkel procedurell grottgenerator i GLSL och C++. För belysning används en fackla, som

Läs mer

Omtentamen TNM077, 3D datorgrafik och animering (samt även TNM008, 3D datorgrafik och VR)

Omtentamen TNM077, 3D datorgrafik och animering (samt även TNM008, 3D datorgrafik och VR) Omtentamen TNM077, 3D datorgrafik och animering (samt även TNM008, 3D datorgrafik och VR) Grupp: MT2 och NO2MT Datum: Fredagen den 23 april 2004 Tid: 14.00-18.00 Hjälpmedel: inga Ansvarig lärare: Stefan

Läs mer

Umeå universitet 4 februari 2004 Institutionen för datavetenskap David Olsson

Umeå universitet 4 februari 2004 Institutionen för datavetenskap David Olsson Umeå universitet 4 februari 2004 Institutionen för datavetenskap "! # $&%(')+*-,/.0))-132+$-.547698;:-.=-.@?BADCE2+2F$-.G4.H:()-1I6J4K, Handledare: Anders Backman (andersb@cs.umu.se) Christopher Holmberg

Läs mer

I rastergrafikens barndom...gjorde man grafik genom att skriva i ett videominne. Operationer på buffert och pixlar. Idag... Varför grafikkort?

I rastergrafikens barndom...gjorde man grafik genom att skriva i ett videominne. Operationer på buffert och pixlar. Idag... Varför grafikkort? Operationer på buffert och pixlar I rastergrafikens barndom......gjorde man grafik genom att skriva i ett videominne. Lapped textures Emil Praun et al., SIGGRAPH 2000. Gustav Taxén CID gustavt@nada.kth.se

Läs mer

Inledning. Kapitel 1. 1.1 Bakgrund. 1.2 Syfte

Inledning. Kapitel 1. 1.1 Bakgrund. 1.2 Syfte Sammanfattning Vi har i kursen Modelleringsprojekt TNM085 valt att simulera ett geléobjekt i form av en kub. Denna består av masspunkter som är sammankopplade med tre olika typer av fjädrar med olika parametrar.

Läs mer

Kort introduktion till POV-Ray, del 1

Kort introduktion till POV-Ray, del 1 Kort introduktion till POV-Ray, del 1 Kjell Y Svensson, 2004-02-02,2007-03-13 Denna serie av artiklar ger en grundläggande introduktion och förhoppningsvis en förståelse för hur man skapar realistiska

Läs mer

Spelutveckling 3d-grafik och modellering. Grunder för 3d-grafik Blender Animering

Spelutveckling 3d-grafik och modellering. Grunder för 3d-grafik Blender Animering Spelutveckling 3d-grafik och modellering Grunder för 3d-grafik Blender Animering Grunderna för 3d-grafik Positionering, transformationer Projektion, kameran Objekt i en 3d-värld Ljusmodeller för 3d-grafik

Läs mer

Borttagning av skymda ytor Painter s Algorithm och Z-buffering. MICHAEL HJORTHOLT och ANDREAS PAULSSON

Borttagning av skymda ytor Painter s Algorithm och Z-buffering. MICHAEL HJORTHOLT och ANDREAS PAULSSON Borttagning av skymda ytor Painter s Algorithm och Z-buffering MICHAEL HJORTHOLT och ANDREAS PAULSSON Examensarbete Stockholm, Sverige 2010 Borttagning av skymda ytor Painter s Algorithm och Z-buffering

Läs mer

Realtids-strålföljning med geometriska primitiver på programmerbara grafikprocessorer (HS-IDA-EA )

Realtids-strålföljning med geometriska primitiver på programmerbara grafikprocessorer (HS-IDA-EA ) Realtids-strålföljning med geometriska primitiver på programmerbara grafikprocessorer (HS-IDA-EA-03-114) Peter Mattsson (a00petma@student.his.se) Institutionen för datavetenskap Högskolan i Skövde, Box

Läs mer

Spelutveckling - Scenegrafer. Scenegrafer Optimeringar Culling

Spelutveckling - Scenegrafer. Scenegrafer Optimeringar Culling Spelutveckling - Scenegrafer Scenegrafer Optimeringar Culling Scenegraf vad och varför? En hierkisk representation av en 3d-värld Directed acyclic Graph (DAG) Består av noder med med barn/föräldrar Gör

Läs mer

TNM022 Proceduella Bilder Rendering av proceduell päls i realtid

TNM022 Proceduella Bilder Rendering av proceduell päls i realtid TNM022 Proceduella Bilder Rendering av proceduell päls i realtid Jonas Nilsson jonni957@student.liu.se Sammanfattning Jag har undersökt och experimenterat med möjligheterna att rendera päls i realtid med

Läs mer

Procedurella Grottor TNM084. Sammanfattning. Alexander Steen

Procedurella Grottor TNM084. Sammanfattning. Alexander Steen Procedurella Grottor TNM084 Alexander Steen alest849@student.liu.se 13-01-12 Sammanfattning Denna rapport beskriver en metod för att skapa procedurella grottor. Grottorna består utav sammanlänkade rum

Läs mer

Föreläsning 2. Operativsystem och programmering

Föreläsning 2. Operativsystem och programmering Föreläsning 2 Operativsystem och programmering Behov av operativsystem En dator så som beskriven i förra föreläsningen är nästan oanvändbar. Processorn kan bara ges enkla instruktioner såsom hämta data

Läs mer

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga. Tentamen Programmeringsteknik II 2014-0-27 Skrivtid: 0800 100 Tänk på följande Skriv läsligt! Använd inte rödpenna! Skriv bara på framsidan av varje papper. Börja alltid ny uppgift på nytt papper. Lägg

Läs mer

Lunds Tekniska Högskola Datorarkitektur med operativsystem EITF60. Superscalar vs VLIW. Cornelia Kloth IDA2. Inlämningsdatum:

Lunds Tekniska Högskola Datorarkitektur med operativsystem EITF60. Superscalar vs VLIW. Cornelia Kloth IDA2. Inlämningsdatum: Lunds Tekniska Högskola Datorarkitektur med operativsystem EITF60 Superscalar vs VLIW Cornelia Kloth IDA2 Inlämningsdatum: 2018-12-05 Abstract Rapporten handlar om två tekniker inom multiple issue processorer

Läs mer

Robin Wahlstedt Datavetenskap / Spel Vetenskapsmetodik rwt07001@student.mdh.se. Datorgrafik i spel

Robin Wahlstedt Datavetenskap / Spel Vetenskapsmetodik rwt07001@student.mdh.se. Datorgrafik i spel Robin Wahlstedt Datavetenskap / Spel Vetenskapsmetodik rwt07001@student.mdh.se Datorgrafik i spel 1 Sammanfattning Dator grafik kan delas in i fyra olika områden: information, design, simuleringar och

Läs mer

Designing a Shading System. David Larsson

Designing a Shading System. David Larsson Designing a Shading System David Larsson Överblick Genomgång av rendering och shading Designval Implementationsdetaljer Rendering Omvandla en konceptuell 3d-värld till en bild Geometri Kamera Något saknas?

Läs mer

HAND TRACKING MED DJUPKAMERA

HAND TRACKING MED DJUPKAMERA HAND TRACKING MED DJUPKAMERA ETT PROJEKT I TNM090 - SOFTWARE ENGINEERING Rasmus KARLSSON Per JOHANSSON Erik HAMMARLUND raska293@student.liu.se perjo020@student.liu.se eriha891@student.liu.se 2014-01-14

Läs mer

Laboration 1: Figurer i hierarki

Laboration 1: Figurer i hierarki Laboration 1: Figurer i hierarki Bakgrund Två grundläggande tekniker i objektorienterad konstruktion är arv och komposition. Mål Laborationen har flera avsikter: 1. Ge kunskaper i hur program kan organiseras

Läs mer

Laboration - Shaders

Laboration - Shaders DH2640/2D2323/DOA, VT 2009 2009-03-06 Laboration - Shaders Martin Fitger, d00-mfi@d.kth.se Version 1.4 Syfte Att erbjuda studenterna möjlighet att få lära sig om olika shaderkoncept och renderingsalgoritmer

Läs mer

Geometry shaders! och Tesselation shaders!

Geometry shaders! och Tesselation shaders! 5(91) Information Coding / Computer Graphics, ISY, LiTH Geometry shaders och Tesselation shaders Ytterligare shadersteg i geometristeget i OpenGLpipelinen Kan modifiera, lägga till och ta bort geometri

Läs mer

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p Skriven av Michael Andersson Introduktion Programmering I högnivåspråk fokuserar på själv problemet (algoritmen) istället

Läs mer

LABORATION 1 AVBILDNING OCH FÖRSTORING

LABORATION 1 AVBILDNING OCH FÖRSTORING LABORATION 1 AVBILDNING OCH FÖRSTORING Personnummer Namn Laborationen godkänd Datum Labhandledare 1 (6) LABORATION 1: AVBILDNING OCH FÖRSTORING Att läsa före lab: Vad är en bild och hur uppstår den? Se

Läs mer

A comparison study between OpenGL 4.3, OpenGL ES 3.0 and WebGL 1.0 With focus on rendering pipeline and texture handling

A comparison study between OpenGL 4.3, OpenGL ES 3.0 and WebGL 1.0 With focus on rendering pipeline and texture handling Sammanfattning OpenGL är ett standardiserat API som används för att hantera 3D-grafik på desktop-datorer. Även då OpenGL är oberoende av specialanpassad hårdvara så passar det inte till alla sorter av

Läs mer

DGI/SUDOA Den historiska utvecklingen. Globala - lokala belysningsmodeller. Lokala belysningsmodeller. Rendering equation

DGI/SUDOA Den historiska utvecklingen. Globala - lokala belysningsmodeller. Lokala belysningsmodeller. Rendering equation DGI/SUDOA - 060329 Rendering equation Belysningsmodeller (lokala och globala) Kort om texturer Den historiska utvecklingen 1. Enkla modeller som utvärderades genom att göra enkla bedömningar 2. Mera sofistikerade

Läs mer

F5: Högnivåprogrammering

F5: Högnivåprogrammering F5: Högnivåprogrammering Parameteröverföring Koppling mellan låg- och högnivåprogrammering Lokala variabler Heapen Datatyper 1 Subrutin, parameteröverföring: 1(3) Via register genom värde Skicka data via

Läs mer

Geometry shaders! och Tesselation shaders!

Geometry shaders! och Tesselation shaders! 6(87) Geometry shaders och Tesselation shaders Ytterligare shadersteg i geometristeget i OpenGLpipelinen Kan modifiera, lägga till och ta bort geometri Kan mata ut andra sorters geometri än vad som matas

Läs mer

F5: Högnivåprogrammering

F5: Högnivåprogrammering 1 F5: Högnivåprogrammering Parameteröverföring Koppling mellan låg- och högnivåprogrammering Lokala variabler Heapen Datatyper 1 Subrutin, parameteröverföring: 1(3) Via register genom värde Skicka data

Läs mer

Koordinatsystem och Navigation

Koordinatsystem och Navigation 2D vs 3D VS Skillnaden mellan 2D och 3D må verka ganska självklar men ibland kan det uppkomma missförstånd kring detta. Vi refererar oftast på 3D som datorgenererad grafik (CG=Computer Graphics) vilket

Läs mer

Bézierkurvor och parametriska objektrepresentationer

Bézierkurvor och parametriska objektrepresentationer Sidan 1 av 11 Inledning Detta är en kort sammanfattning av teorimaterialet som år 2004 ingår i examinationen i kursen TNM077 3D-grafik och animering som ges vid Linköpings tekniska universitet på Campus

Läs mer

Försättsblad till skriftlig tentamen vid Linköpings Universitet

Försättsblad till skriftlig tentamen vid Linköpings Universitet Försättsblad till skriftlig tentamen vid Linköpings Universitet (fylls i av ansvarig) Datum för tentamen Sal Tid Kurskod Provkod Kursnamn/benämning Institution Antal uppgifter i tentamen Antal sidor på

Läs mer

Den tekniska utvecklingen av hårdvara och mjukvara för realtidsgrafik

Den tekniska utvecklingen av hårdvara och mjukvara för realtidsgrafik Den tekniska utvecklingen av hårdvara och mjukvara för realtidsgrafik Anders Andersson aaa99005@student.mdh.se CD5420 - Vetenskap inom dataområdet, 2002-10-15 1 Sammanfattning Rapporten har en fokusering

Läs mer

Datorgrafik Ray tracing. Mattias Ekström, Västerås,

Datorgrafik Ray tracing. Mattias Ekström, Västerås, Datorgrafik Ray tracing Mattias Ekström, Västerås, 2010-03-05 1 SAMMANFATTNING Ray tracing är en teknik för att skapa bilder digitalt. Den används komersiellt främst inom film- och spelindustrin. Metoden

Läs mer

Rendera med mental ray

Rendera med mental ray Rendera med mental ray Rendera med mental ray Hittills har vi enbart använt den enklaste formen av rendering i 3dsmax., den inbyggda och något föråldrade scanline-renderaren. Nu ska vi byta till mental

Läs mer

Bemästra verktyget TriBall

Bemästra verktyget TriBall Bemästra verktyget TriBall I IRONCAD finns ett patenterat verktyg för 3D-positionering av objekt, kallat TriBall. Hyllad av en del som "Det mest användbara verktyget i CAD-historien". TriBall är otroligt

Läs mer

TAIU07 Matematiska beräkningar med Matlab

TAIU07 Matematiska beräkningar med Matlab TAIU07 Matematiska beräkningar med Matlab Laboration 3. Linjär algebra Namn: Personnummer: Epost: Namn: Personnummer: Epost: Godkänd den: Sign: Retur: 1 Introduktion 2 En Komet Kometer rör sig enligt ellipsformade

Läs mer

Här är ett väldigt bra tidpunkt att spara scenen. Jag har valt att bygga ett litet pyramidtorn.

Här är ett väldigt bra tidpunkt att spara scenen. Jag har valt att bygga ett litet pyramidtorn. Man kan i 3dsmax 2011 som standard välja mellan två olika renderare. Dels den inbyggda och något föråldrade scanline-renderaren samt "mental ray" som är lite mer avancerad och har mer möjligheter men också

Läs mer

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY Grunderna i C++ ARK 385: Virtuella Verktyg i en Materiell värld AT Arkitektur & Teknik Chalmers Tekniska Högskola 2009 - Kursen skapades (3 förel.) 2010-6 förel. + 2 projekt 2011-8 förel. Helt omarbetade

Läs mer

OpenGL, Maya och specialeffekter

OpenGL, Maya och specialeffekter OpenGL, Maya och specialeffekter Gustav Taxén, gustavt@nada.kth.se Introduktion OpenGL är ett användbart API för att rendera grafik i realtid (om man har det rätta hårdvarustödet). Du har på tidigare kurser

Läs mer

Forskning och utveckling inom språkteknologi Uppgift 3: Projektförslag Parallelliserad dependensparsning i CUDA

Forskning och utveckling inom språkteknologi Uppgift 3: Projektförslag Parallelliserad dependensparsning i CUDA Forskning och utveckling inom språkteknologi Uppgift 3: Projektförslag Parallelliserad dependensparsning i CUDA Evelina Andersson 18 maj 2011 1 Introduktion Att träna mycket för att bli duktig på ett språk

Läs mer

Arv och polymorfism i Java

Arv och polymorfism i Java 1 (5) Arv och polymorfism i Java Objektorienterad programmering 5 Syfte Att ge en introduktion till arvsmekanismen i Java. Mål Efter övningen skall du kunna definiera klasser med arv i Java. förstå hur

Läs mer

Pressrelease Artes Industriambassadör 031115. Mer realistiska skuggor i datorspel och virtual reality-applikationer

Pressrelease Artes Industriambassadör 031115. Mer realistiska skuggor i datorspel och virtual reality-applikationer Anita Andler Pressrelease Artes Industriambassadör 031115 Mer realistiska skuggor i datorspel och virtual reality-applikationer Ulf Assarsson, doktorand vid Chalmers tekniska högskola lade den 10 oktober

Läs mer

Repetition + lite av varje. Ulf Assarsson Department of Computer Engineering Chalmers University of Technology

Repetition + lite av varje. Ulf Assarsson Department of Computer Engineering Chalmers University of Technology Repetition + lite av varje Ulf Assarsson Department of Computer Engineering Chalmers University of Technology Tävlingen Tävling: 22:a maj 15:00-17:00 i sal EA Anmäl ert lag om ni vill vara med. Skicka

Läs mer

Histogram över kanter i bilder

Histogram över kanter i bilder Histogram över kanter i bilder Metod Både den svartvita kanstdetekteringen och detekteringen av färgkanter följer samma metod. Först görs en sobelfiltrering i både vertikal och horisontell led. De pixlar

Läs mer

Programmering II (ID1019) :00-11:00

Programmering II (ID1019) :00-11:00 ID1019 Johan Montelius Programmering II (ID1019) 2015-06-11 08:00-11:00 Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten. Svaren

Läs mer

Parallellism i NVIDIAs Fermi GPU

Parallellism i NVIDIAs Fermi GPU Parallellism i NVIDIAs Fermi GPU Thien Lai Phu IDA2 Abstract This report investigates what kind of computer architecture, based on Flynn s taxonomy, is used on NVIDIAs Fermi-based GPU to achieve parallellism

Läs mer

Programmering = modellering

Programmering = modellering Programmering = modellering Ett datorprogram är en modell av en verklig eller tänkt värld. Ofta är det komplexa system som skall modelleras I objektorienterad programmering består denna värld av ett antal

Läs mer

CDC en jämförelse mellan superskalära processorer. EDT621 Campus Helsingborg av: Marcus Karlsson IDA

CDC en jämförelse mellan superskalära processorer. EDT621 Campus Helsingborg av: Marcus Karlsson IDA CDC6600 - en jämförelse mellan superskalära processorer av: Marcus Karlsson Sammanfattning I denna rapport visas konkret information om hur den första superskalära processorn såg ut och hur den använde

Läs mer

BACHELOR THESIS. Efficient Optimizations Inside the Digital Advertise Production Pipeline. Michal Marcinkowski Mehmet Özdemir

BACHELOR THESIS. Efficient Optimizations Inside the Digital Advertise Production Pipeline. Michal Marcinkowski Mehmet Özdemir BACHELOR THESIS 2008:234 Efficient Optimizations Inside the Digital Advertise Production Pipeline Michal Marcinkowski Mehmet Özdemir Luleå University of Technology Bachelor thesis Computer graphics Department

Läs mer

Per Holm Lågnivåprogrammering 2014/15 24 / 177. int och double = = 2, 147, 483, 647

Per Holm Lågnivåprogrammering 2014/15 24 / 177. int och double = = 2, 147, 483, 647 Lågnivåprogrammering Föreläsning 2 Lågnivåprogrammering Förberedelse inför laboration 2. Maskinspråk, assemblerspråk Talrepresentation En enkel dator, komponenter Instruktionsformat, instruktionscykel

Läs mer

Teknik för avancerade datorspel!

Teknik för avancerade datorspel! 1(84) Information Coding / Computer Graphics, ISY, LiTH TSBK 03 Teknik för avancerade datorspel Ingemar Ragnemalm, ISY Fysik Datorgrafik Spelmekanismer AI Animation 1(84) Föreläsning 5 GPU computing GPU

Läs mer

Ansiktsigenkänning med MATLAB

Ansiktsigenkänning med MATLAB Ansiktsigenkänning med MATLAB Avancerad bildbehandling Christoffer Dahl, Johannes Dahlgren, Semone Kallin Clarke, Michaela Ulvhammar 12/2/2012 Sammanfattning Uppgiften som gavs var att skapa ett system

Läs mer

Universe Engine Rapport

Universe Engine Rapport 1 Universe Engine Rapport Alexander Mennborg 2017-05-08 2 Inledning I denna rapport diskuteras utvecklingsprocessen till projektet Universe Engine. Denna diskussion omfattar hela utveckling från starten

Läs mer

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Tentamen i TDP004 Objektorienterad Programmering Praktisk del Tentamen i TDP004 Objektorienterad Programmering Praktisk del Datum: 2010-04-07 Tid: 8-12 Plats: SU-salar i B-huset. Jour: Per-Magnus Olsson, tel 285607 Jourhavande kommer att besöka skrivsalarna ungefär

Läs mer

VRay för Max Camilla Ravenna / André Ravenna Alto Punto 2012 Alto Punto Askims Stationsväg 21 436 40 Askim

VRay för Max Camilla Ravenna / André Ravenna Alto Punto 2012 Alto Punto Askims Stationsväg 21 436 40 Askim VRay för Max Camilla Ravenna / André Ravenna Alto Punto 2012 Alto Punto Askims Stationsväg 21 436 40 Askim ISBN 978-91-637-2533-3 Innehåll 1: Kom igång 5 2: Nödvändiga inställningar 6 2.1: V-Ray fliken

Läs mer

Linköpings Tekniska Högskola Instutitionen för Datavetenskap (IDA) Torbjörn Jonsson, Erik Nilsson Lab 2: Underprogram

Linköpings Tekniska Högskola Instutitionen för Datavetenskap (IDA) Torbjörn Jonsson, Erik Nilsson Lab 2: Underprogram Mål Lab 2: Underprogram Följande laboration introducerar underprogram; procedurer, funktioner och operatorer. I denna laboration kommer du att lära dig: Hur man skriver underprogram och hur dessa anropas.

Läs mer

Lagermask och urklippsmask

Lagermask och urklippsmask Lagermask och urklippsmask Lagermasken En lagermask används för att på olika sätt frilägga eller ta bort saker i en bild och ändå bevara det borttagna ifall man vill återanvända detaljerna man tagit bort.

Läs mer

TENTAMEN. Matematik 1 Kurskod HF1903 Skrivtid 13:15-17:15 Onsdagen 25 september 2013 Tentamen består av 3 sidor

TENTAMEN. Matematik 1 Kurskod HF1903 Skrivtid 13:15-17:15 Onsdagen 25 september 2013 Tentamen består av 3 sidor TENTAMEN Matematik Kurskod HF903 Skrivtid 3:5-7:5 Onsdagen 5 september 03 Tentamen består av 3 sidor Hjälpmedel: Utdelat formelblad. Räknedosa ej tillåten. Tentamen består av 3 uppgifter som totalt kan

Läs mer

Bemästra verktyget TriBall

Bemästra verktyget TriBall Bemästra verktyget TriBall I IRONCAD finns ett patenterat verktyg för 3D-positionering av objekt, kallat TriBall. Hyllad av en del som "Det mest användbara verktyget i CAD-historien" TriBall är otroligt

Läs mer

Vektorgeometri för gymnasister

Vektorgeometri för gymnasister Vektorgeometri för gymnasister Per-Anders Svensson http://homepage.lnu.se/staff/psvmsi/vektorgeometri/gymnasiet.html Fakulteten för teknik Linnéuniversitetet Linjära avbildningar I Innehåll En liten tillbakablick:

Läs mer

Innehåll. Kamerabaserad interaktion Del 3 3D och AR. Världen genom datorn. Vad är AR? AR vs. VR. Potential

Innehåll. Kamerabaserad interaktion Del 3 3D och AR. Världen genom datorn. Vad är AR? AR vs. VR. Potential Innehåll Kamerabaserad interaktion Del 3 3D och AR Anders Henrysson Augmented Reality Introduktion Displayer Tracking Kamerabaserad tracking och interaktion AR på mobiltelefoner CMAR Vad är AR? Förstärkning/utökning

Läs mer

SNABBGUIDE för studenter windows. Utskriftshantering, Kopiering och Scanning

SNABBGUIDE för studenter windows. Utskriftshantering, Kopiering och Scanning SNABBGUIDE för studenter windows Utskriftshantering, Kopiering och Scanning Installation av klient på din privata dator Installation av klient För att kommunicera med utskriftssystemet behöver varje dator

Läs mer

Digitala projekt rapport

Digitala projekt rapport Digitala projekt rapport Alexander Westrup, d04aw@student.lth.se Martin Sandgren, d04ms@student.lth.se 4 december 2007 Innehåll 1 Abstract 1 2 Inledning 1 3 Arbetsgång 1 4 Hårdvara 1 4.1 Processor...............................

Läs mer

Displaysystem. Hans Brandtberg Saab Avitronics SAAB AVITRONICS 03-10-06

Displaysystem. Hans Brandtberg Saab Avitronics SAAB AVITRONICS 03-10-06 Displaysystem Hans Brandtberg Saab Avitronics Applikation Drivrutiner (OpenGL) Displaysystem Människa-maskin egenskaper -Kunna förstå och arbeta med information -Kunne se och uppfatta det som visas

Läs mer

TBSK 03 Teknik för Advancerade Datorspel

TBSK 03 Teknik för Advancerade Datorspel TBSK 03 Teknik för Advancerade Datorspel Översikt 3D och Stereoskopi Introduktion Bildskärmsteknik Depth Cues Limiteringar Design-riktlinjer Texturkompression Introduktion Algoritmer & Standarder (DXT,

Läs mer

Grafik. För enklare datorsystem

Grafik. För enklare datorsystem Grafik För enklare datorsystem Grafik förr VGA-signalen Direktdriven grafik eller bildminne Bitmap-grafik Tile/teckenbaserad grafik Spritebaserad grafik Kollisionskontroll Rörelse : Hastighet / riktning

Läs mer

Transparens i en deferred pipeline Stefan Hanna

Transparens i en deferred pipeline Stefan Hanna Institutionen för kommunikation och information Transparens i en deferred pipeline Stefan Hanna Examensarbete i datalogi med inriktning mot dataspelsutveckling 30 hp C-nivå, vårterminen 2010 Transparens

Läs mer

Datastrukturer och Algoritmer D0041D

Datastrukturer och Algoritmer D0041D Luleå Tekniska Universitet 19 mars 2014 Laborationsrapport Laboration 3 Datastrukturer och Algoritmer D0041D Primms Algoritm Namn E-mail Magnus Björk magbjr-3@ltu.student.se Handledare Felix Hansson Primms

Läs mer

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning. Programmering med Java Programmering med Java Programspråket Java Källkodsexempel Källkod Java API-exempel In- och utmatning Grunderna Ann Pan panda@nada.kth.se Rum 1445, plan 4 på Nada 08-7909690 Game.java

Läs mer

Högskolan Dalarna sid 1 av 7 DI-institutionen Hans-Edy Mårtensson Sten Sundin

Högskolan Dalarna sid 1 av 7 DI-institutionen Hans-Edy Mårtensson Sten Sundin Högskolan Dalarna sid 1 av 7 DI-institutionen Hans-Edy Mårtensson Sten Sundin TENTAMEN I IKB007 INTERNETPROGRAMMERING MED JAVA, 5p för SY2 2001-03-16, kl 14.00-18.00 Hjälpmedel: Inga hjälpmedel är tillåtna

Läs mer

Lågnivåprogrammering. Föreläsning 2 Lågnivåprogrammering. Binära tal. En enkel modell av datorns inre

Lågnivåprogrammering. Föreläsning 2 Lågnivåprogrammering. Binära tal. En enkel modell av datorns inre Lågnivåprogrammering Föreläsning 2 Lågnivåprogrammering Förberedelse inför laboration 2. Maskinspråk, assemblerspråk Talrepresentation En enkel dator, komponenter Instruktionsformat, instruktionscykel

Läs mer

Inledande programmering med C# (1DV402) Introduktion till C#

Inledande programmering med C# (1DV402) Introduktion till C# Introduktion till C# Upphovsrätt för detta verk Detta verk är framtaget i anslutning till kursen Inledande programmering med C# vid Linnéuniversitetet. Du får använda detta verk så här: Allt innehåll i

Läs mer

Titel Mall för Examensarbeten (Arial 28/30 point size, bold)

Titel Mall för Examensarbeten (Arial 28/30 point size, bold) Titel Mall för Examensarbeten (Arial 28/30 point size, bold) SUBTITLE - Arial 16 / 19 pt FÖRFATTARE FÖRNAMN OCH EFTERNAMN - Arial 16 / 19 pt KTH ROYAL INSTITUTE OF TECHNOLOGY ELEKTROTEKNIK OCH DATAVETENSKAP

Läs mer

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng TENTAMEN I PROGRAMMERING Ansvarig: Jan Skansholm, tel 7721012 Betygsgränser: Hjälpmedel: Sammanlagt maximalt 60 poäng. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng Skansholm,

Läs mer

Anpassningsbar applikationsstruktur för flerpunktsskärmar

Anpassningsbar applikationsstruktur för flerpunktsskärmar Datavetenskap Opponent(er): Rikard Boström Lars-Olof Moilanen Respondent(er): Mathias Andersson Henrik Bäck Anpassningsbar applikationsstruktur för flerpunktsskärmar Oppositionsrapport, C/D-nivå 2005:xx

Läs mer

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Tentamen i TDP004 Objektorienterad Programmering Praktisk del Tentamen i TDP004 Objektorienterad Programmering Praktisk del Datum: 2011-04-28 Tid: 08-12 Plats: SU-salar i B-huset. Jour: Per-Magnus Olsson, tel 281456 Jourhavande kommer att besöka skrivsalarna ungefär

Läs mer

Snake. Digitala Projekt (EITF11) Fredrik Jansson, I-12 Lunds Tekniska Högskola,

Snake. Digitala Projekt (EITF11) Fredrik Jansson, I-12 Lunds Tekniska Högskola, Snake Digitala Projekt (EITF11) Fredrik Jansson, I-12 Lunds Tekniska Högskola, 2015-05-18 Oskar Petersen, I-12 Handledare: Bertil Lindvall Abstract Denna rapport beskriver ett projekt där ett klassiskt

Läs mer

JavaScript del 5 Funktioner

JavaScript del 5 Funktioner JavaScript del 5 Funktioner När man skriver JavaScriptkod eller program i andra programmeringsspråk för den delen så kan det finnas anledningar till att man vill dela upp sitt stora program i flera mindre

Läs mer

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt Programmeringsteknik II - HT18 Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt 18-09-28 1 Förra gången: Arv och klasshierarkier Vi såg hur

Läs mer

Teknik för avancerade datorspel!

Teknik för avancerade datorspel! 1(83) Information Coding / Computer Graphics, ISY, LiTH TSBK 03 Teknik för avancerade datorspel Ingemar Ragnemalm, ISY Fysik Datorgrafik Spelmekanismer AI Animation 1(83) Föreläsning 5 GPU computing GPU

Läs mer

Tor Sterner-Johansson Thomas Johansson Daniel Henriksson

Tor Sterner-Johansson Thomas Johansson Daniel Henriksson Lab 4: Anti Tower Defence Oskar Mothander Alan Mendez Larsson dit06omr dit06mln Lärare: Handledare: Johan Eliasson Johan Granberg Tor Sterner-Johansson Thomas Johansson Daniel Henriksson Innehåll 1. Problemspecifikation...

Läs mer

Föreläsning 1: Intro till kursen och programmering

Föreläsning 1: Intro till kursen och programmering Föreläsning 1: Intro till kursen och programmering Kursens hemsida http:www.it.uu.se/edu/course/homepage/prog1/vt11 Studentportalen http://www.studentportalen.uu.se Lärare: Tom Smedsaas, Tom.Smedsaas@it.uu.se

Läs mer

Projekt i TNM084, Procedurella bilder

Projekt i TNM084, Procedurella bilder Projekt i TNM084, Procedurella bilder Inledning Kursen TNM084, Procedurella Bilder innehåller ett examinerande projekt. Målet med projektet är att utöka förståelsen för hur man kan producera syntetiska

Läs mer