Proceduell planet med atmosfär Toms Vulfs [email protected] Sammanfattning Rapporten beskriver hur en realistisk atmosfär genereras utifrån fysikaliska egenskaper hos ljus och luft partiklar i en atmosfär. Atmosfärisk ljusspridning förklaras samt tidigare arbeten inom området undersöks. En algoritm utvecklas ur teorin för att passa in i beräkningar på en GPU i form av vertex och pixel shaders. Andra proceduella metoder för att skapa ett visuellt tilltalande karaktär på planeten finns också beskrivna. 1. Inledning I utomhusscener i datorgrafik är det viktigt att beräkna atmosfärisk spridning av ljus för att åstadkomma en realistisk miljö. På dagtid upplever vi att himlen blir blå och vid solnedgång och soluppgång blir himlen gulaktig och röd. Dessa färger och ljusheten bestäms av ljusspridningen i atmosfären. Från rymden varierar färgen på atmosfären beroende på var åskådaren och solen befinner sig därav ser vi i satellitbilder att jorden är ”blå”. Vid kanten av skuggan på jorden blir atmosfären rödaktig även från rymden. Färgen på molnen varierar också beroende på var solen befinner sig. Färgen inifrån atmosfären varierar inte bara från solens position men även föroreningen, vädret och andra faktorer som förändrar partiklarna i luften gör att vi upplever utomhus färgerna olika. På planeter med olika gaser och partiklar i luften, jämfört med jordens, förändras dessa effekter avsevärt. 2. Tidigare arbete Tidigare inom datorgrafik har bilder på jorden gjorts utan att ta hänsyn till dom fysikaliska egenskaper av partiklarna i luften men i 1993 föreslog Nishita en metod där man beräknade dessa optiska effekter för att ta fram en mer realistisk bild på jorden. Dessa bilder tog mellan 4 – 12 minuter att generera på en IRIS Indigo dator med Elan grafik, som på den tiden var ganska bra men den saknade textur minne, och datorns processor på 150Mhz. I denna implementation en tvådimensionell uppslagstabell skapades för att beräkna den optiska längden för att accelerera renderingen. Senare vid 2001 föreslog Hoffman tillsammans med Preetham[2] ett effektivt sätt att beräkna atmosfärisk spridning för utomhusscener. Här beräknades både ut- och inljusspridning samt absorbering av ljus i partiklarna i luften. Det var alltså möjligt att rendera disig och förorenad atmosfär såsom klar och ren atmosfär. Spridningen av ljus beräknades också mot avlägsna objekt som berg. Ekvationerna implementerades i fragment och vertex shaders så att realtids rendering var möjlig. Denna implementation var dock enbart för låga kamera positioner dvs. kameran var placerad nära ytan detta gör att atmosfären kan antas ha konstant densitet över alla höjder och därför förenklar ekvationer introducerade från Nishita. Sean O'Neil, 2004 skrevs[3] det om implementation av de fullständiga ekvationer från Nishita. Även här användes det en förberäknad två dimensionell uppslagstabell med fyra kanaler för beräkning av färg för varje vertex. Denna implementation kördes på CPU för att vid den tidpunkt som atrikeln skrevs fanns det inga grafikkort som klarade av dessa beräkningar i shaders. I denna implementation kunde man dock flyga ut och in från atmosfären och få en korrekt visualisering då densiteten föll exponentiellt när höjden från ytan ökade. I denna rapport baseras implementationen på Sean O'Neil[4] förslag till lösning av atmosfärisk spriding på GPU med fragment och vertex shaders för att åstadkomma realtids rendering och interaktion. 3. Atmosfärisk ljusspridning Solljus som tränger sig genom atmosfären kan absorberas, spridas, reflekteras och brytas innan de når någon yta. Människor upplever olika starkt ljus och olika färg beroende på vilken våglängd de strålande ljuset är. Dämpningen av solljuset i atmosfären uppstår vid absorption och spridning och kan indelas i två olika effekter som antingen tar bort ljus eller lägger till ljus i observationsriktningen. Absorptionen i atmosfären kan försummas (förutom vid ozon-lagret) och därav kan den vara enbart ett spridnings medium. Spridning av solljus i atmosfären uppstår när ljuset träffar luftmolekyler eller större partiklar som finns i gaser. Ljusspridning på grund av molekyler i luften kallas Rayleigh ljusspridning som sprider ljuset kraftigt vid kortare våglängder. Himlen blir blå på dagen då de blåa ljuset studsar överallt och till slut når ögonen från alla håll medan. På kvällen blir himlen gul och rödaktig för att blå och gröna våglängder studsar iväg innan dom når ögat på grund av att ljuset färdas långt genom atmosfären. För de större partiklar sprids ljuset med Mie ljusspridning som sprider alla våglängder av ljus lika mycket. När mycket partiklar finns i atmosfären får solen en solgård. Med denna egenskap kan man göra många olika spännande effekter som regnbåge och simulera ljusspridning för små is partiklar i luften. 4. Teori Henyey-Greenstein funktionen är en välkänd fas-funktion som kan modifieras för ett rimligt fysikaliskt uttryck för karaktären av ljusspridningens riktning. Denna funktion beskriver hur mycket ljus som sprids mot åskådaren beroende på vinkeln mellan den och ljusets riktning samt en konstant g som påverkar spridningen symmetri. Det finns många olika varianter av fas funktioner, Nishita's[1] modifikation av denna fas-funktion är: 2 F , g = 2 3 1− g 1cos ∗ ∗ 2 2 g 2 1 g 2−2gcos 3 /2 (1) Om konstanten g sätts till noll kan Rayleigh ljusspridning approximeras med denna funktion vilket betyder att positiva och negativa vinklar ger samma svar i ekvation 1. Positiva värden på g sprider ljuset framåt medan negativa sprider ljuset bakåt och För Mie ljusspridning används värden mellan -0.75 och -0.99. Konceptet optisk djup används i samband med atmosfärisk ljusspridning. De optiska djupet för en given ljusväg kan beräknas som en integral för spridnings koefficienten över alla underelement ds på den givna ljusvägen gånger densitets förändringen av atmosfären: S t S , = ∫ s s ds = 0 4 K 4 S ∫ s ds (2) 0 −h s=exp H0 (3) Integral delen i ekvation 2 beräknar de optiska djupet för avståndet S. Spridnings koefficienten utvecklas i förändring av ljusets väg i förhållande till våglängden. Densitets beräkningen beskrivs med ekvation 3 där h är höjden av punkten där ljuset träffar en partikel och H0 är höjden där atmosfärens medel densitet ligger. Konstanten λ beskriver våglängden av ljuset och K är spridnings konstanten som är olika beroende på om de är Rayleigh eller Mie ljusspridning. Eftersom dessa ekvationer ska appliceras i datorgrafik kan åskådaren vara kameran och synfältet vara en stråle. Om en stråle börjar i kamerans position Pv och pekar mot planeten. Det finns två fall då strålen går bara genom atmosfären eller att strålen träffar planetens yta. I första fallet där strålen går bara genom atmosfären. Punkten P kan vara en punkt i atmosfären där ljuset sprids från partikeln och punkter Pa och Pb kan vara strålens närmsta respektive längsta skärningspunkt. Punkten Pc sätts till solstrålens skärningspunkt på atmosfären mot punkten P. Intensiteten av ljuset som har spridits i punkten P mot kamerans position måste beräknas. Det görs med intensiteten som anländer från solen till P genom att sätta integrations intervallet till PcP i ekvation 2 och multiplicera det med intensiteten från Rayleigh ljusspridningen. Avståndet till solen från atmosfären kan ses som en parallell balk därav kan spridnings vinkeln hos varje punkt längs med PaPb vara konstant. Detta medför att intensiteten som når kameran på Pv kan beräknas med att integrera de ljuset som spridits på grund av luft molekyler på PaPb med: I v = I s KF r 4 Pb ∫ e−t PPc , −t PPa , ds (4) Pa Is(λ) är intensiteten på solen. Ekvation 4 kallas också för inspridnings ekvationen samt ekvation 3 kallas för ut-spridnings ekvationen. I det andra fallet skär strålen, från kameran, planeten i punkten Pb. Intensiteten som har spridits på grund av molekylerna i luften beräknas på likadan sätt som i första fallet. När punkten P sammanfaller med punkten Pb beräknas ljuset med att lägga till de reflekterade ljuset från planetens yta till ljusets spridning på strålen PaPb. Alltså intensiteten som når kameran blir: ' I v = I v I e e −t PaPb , (5) I ekvation 5 är Iv de ljuset som spridits av ekvation 4 och Ie är de reflekterade ljuset från planeten alltså de omgivande ljuset av planeten och de direkta solljuset tillsammans. 5. Implementation Om ekvationerna från ovan skulle implementeras rakt av så skulle det krävas väldigt mycket beräkningar. Om ekvation 5 ska lösas så kan man komma upp till 3000 beräkningar per vertex och detta är ganska tungt om beräkningar ska ske på CPU. En två dimensionell tabell kan snabba på beräkningen genom att ersätta en av ut-spridnings integralerna med höjd och vinkel till solen i förhållande till en godtycklig punkt i atmosfären. Detta är möjligt med att solen befinner så pass långt bort att strålarna kan antas vara parallella. Med denna tabell kunde Nishita skära ner beräkningar till hälften. O'Neil 2004 introducerade en förbättrad version av tabellen med att eliminera den andra ut-spridnings beräkningen. Med denna nya tabell var det möjligt att förminska de 3000 beräkningar till 60 per vertex. Denna förbättrade metod gjorde det möjligt att köra atmosfärisk spridning i interaktiva hastigheter med 50-100 fps. Denna metod att lösa ekvationerna skulle kunna implementeras i shaders för att uppnå mer fps. I O'Neil 2005 gjordes det matematiska undersökningar av dessa ekvationer för att kunna lösa ekvationer med en annorlunda tillvägagångssätt. Genom att grafiskt undersöka uppslagstabellens resultat med partikel höjden på x-axeln och de optiska djupet på y-axeln såg grafen ut att minska exponentiellt då höjden gick från noll till ett men skalan på varje linje varierade avsevärt. Denna graf normaliserades och varje kurva fick likadana resultat nämligen exp(-4x). Denna resultat är logisk då höjden på atmosfärens medel densitet ligger på 0.25 i O'Neils implementering. Det fanns variationer på kurvorna som beror på att vinkeln från kamera strålen till partikeln i atmosfären varierar över 90 grader men dessa variationer är försumbara då strålen passerar genom planeten vid denna vinkel. Alltså är resultatet exp(-4x) ett bra resultat för att eliminera höjd beräkningen i uppslagstabellen. Efter att höjdens beräkning är ersatt måste man titta på vinkeln beräkning i tabellen. Delen som inte behandlas med exp(-4x) är skalan som används för att normalisera höjd beräkningen alltså värdet som de optiska djupet har när x=0. En Ny graf kan skapas med genom att undersöka vinkeln på x-axeln och skalan för varje vinkel på y-axeln. Det som visade sig vara en växande kurva som liknade en exponentiell kurva. Genom att skala upp grafens startvärde till ett och logaritmera kurvan kunde en annan växande kurva uppnås. Denna kurva krävde dock en mjukvara för att uppskatta och resultatet blev en polynomisk kurva som kan användas istället för uppslagstabellen. Detta medför också till att om höjden på atmosfärens medeldensitet ändras från att vara 0.25 till ett annat värde så måste en ny kurva uppskattas. Så länge som atmosfärens tjocklek är 2.5% av planetens radie och skalan på höjden är 25% av atmosfärens tjocklek kan planeten vara hur stor eller liten som helst. Med dessa approximationer kan man nu implementera atmosfärisk ljusspridning i fragment och vertex shaders. Programspråket C++ tillsammans med OpenGL används för att skapa en körbar demo tillsammans med GLSL shaders. Två stycken sfärer skapas med gluSphere() som representerar atmosfären och planeten. Shaders skapas för båda sfären när man är inne i atmosfären med kameran och när man befinner sig i rymden. De mesta av beräkningar för intensiteten mot kameran efter spridningen utförs i vertex shadern förutom fas funktionen då artefakter uppstår när fas funktionen beräknas per vertex. Fas funktionens beräkning hanteras av fragment shadern med de beräknade färgen från vertex shadern. HDR rendering används för att förbättra bilden då den kan vara för mörk eller för ljus utan det. HDR rendering används ofta tillsammans med en pixel-buffer som renderas på en textur för att kunna jämna ut färgen till en given skala. I denna implementation används dock en simpel exponerings ekvation i slutet av varje fragment shader som beräknar den slutgiltiga färgen. Exponerings konstanten fungerar som en bländare gör i kameror eller i pupillen. En generell implementering görs först med GLFW som hanterar OpenGL kontext, samt att biblioteket GLEW används för att hantera GLSL anknytning till OpenGL. Sedan flyttas implementeringen till wxWidgets för att kunna skapa ett användargränssnitt och kunna kontrollera vissa parametrar i realtid. För att förbättra utseendet på planeten används Perlin Noise implementerat i shaders[5] för att lägga till terräng och moln. Molnen implementeras med hjälp av metoden som introduceras av[6] där fraktal summor av noise används. En exponentiell funktion används för att kontrollera skärpa och fluffighet av molnen samt att en extra turbulens fraktal summa implementeras för att skapa större moln och icke moln områden. Denna shader appliceras på en sfär som har en radie större än planetens men mindre än atmosfärens radie. Ingen ljusspridning beräknas på molnen från rymden däremot vanlig diffus belysning och skuggning beräknas. När kameran befinner sig i atmosfären ökas moln fraktal frekvensen för att skapa en mer realistisk visuell karaktär. Terrängen är också implementerad med fraktal summor av noise i vertex shadern för att ändra på höjden av planetens yta. Ingen färgläggning eller texturering av marken utförs förutom den som ljusspridningen tillför med. 6. Resultat Programmeringen och demo körningen utfördes på en bärbar dator i linux operativ system med nvidia 330GT GPU, 2.13 Ghz intel core i3 CPU och 4 Gb ram. Implementation i GLFW utan användargränssnitt: 122fps, med terräng, med moln Figur 1. 99.5fps, kamera i rymden 305fps, utan terräng, utan moln Figur 2. 52.5fps, kamera i atmosfären Implementation I wxWidgets: 100fps, utan terräng, med moln 7. Diskussion 99.5fps, kamera i rymden Resultatet är ganska visuellt attraktiv och körs i rimlig fps, tillräckligt för att det inte ska uppkomma fördröjningar medan man interagerar med programmet. Genom att användaren kan ändra på de olika parametrar kan programmet upplevas som en spännande och underhållande program. Man kan ändra våglängderna så att planetens atmosfär ser ut som jorden både på dagen och vid solnedgång men även så att planeten ser ut som någon utomjordisk planet med olika färger på himlen. Texturer kan användas på planeten för att se hur spridningen av ljus påverkar till exempel texturen på jorden. Prodeduella sfärer skulle kunna användas tillsammans med LOD för att ge bättre upplösning på terrängen när kameran närmar sig planetens yta. Det finns många mer spännande saker man kan göra med terrängen bl. a. lägga till vatten med reflektioner. Molnen går att förbättra avsevärt med till exempel volymetriska moln eller använda ljusspridnings teorin på molnen som är redan implementerade för att åstadkomma mer realistiska färger vid solnedgång. Här kan man öka på antalet termer i fraktal summan för att åstadkomma bättre upplösning på molnen. Ett försök gjordes på att göra virvlar[9] av molnens fraktal summan men ett visuellt tilltalande resultat uppnåddes ej. Man kan också tillägga dis och annat väder för att förbättra atmosfärens känsla. Utöka skalningsfunktionen så att den inte bara beror på en viss höjd. Dela upp Rayleigh och Mie ljusspridning så att de har olika djup(hänger ihop med att göra dis). Denna implementation har gjorts med singel ljusspridning då förloras ljuset som har spridits bort från kamerans stråle därav kan man utöka den med multipel ljusspridning. Regnbågar[7] och åskväder[8] är också möjligt att tillägga. Vi upplever objekt som suddiga när dem ligger långt bort i atmosfären denna effekt skulle kunna läggas till i HDR renderingen. Ett försök gjordes också på att göra planetringar med point sprites tillsammans med shaders men det visade sig vara svårare än trott. Denna del är dock kvar i de slutgiltiga programmet då det ändå skapar en bra känsla för en planet i rymden, från längre håll. 8. Referenser [1] Nishita T., T. Sirai, K. Tadamura, and E. Nakamae. 1993. "Display of the Earth Taking into Account Atmospheric Scattering.", SIGGRAPH 93, pp. 175–182. http://nis-lab.is.s.u-tokyo.ac.jp/~nis/cdrom/sig93_nis.pdf [2] Hoffman, N. and A. J. Preetham. 2002. "Rendering Outdoor Scattering in Real Time." ATI Corporation. http://www.ati.com/developer/dx9/ATI-LightScattering.pdf [3] O'Neil, Sean. 2004. "Real-Time Atmospheric Scattering." GameDev.net. http://www.gamedev.net/columns/hardcore/atmscattering/ [4] O'Neil, Sean. 2005. GPU gems 2, ”Chapter 16. Accurate Atmospheric Scattering”. http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter1 6.html [5] Gustavson, Stefan. http://staffwww.itn.liu.se/~stegu/simplexnoise/ [6] Sazzad K., Mahmud H., and Emdad A. 2005.”Generating and Rendering Procedural Clouds in Real Time on Programmable 3D Graphics Hardware”. In Proceedings of 9th IEEE International Multi Topic Conference. http://paris.cs.wayne.edu/~ay2703/research/publications/getPDF2 INMIC2005.pdf [7] Brewer Clint. 2004. "Rainbows and Fogbows: Adding Natural Phenomena." NVIDIA Corporation. SDK white paper. http://download.nvidia.com/developer/SDK/Individual_Samples/ DEMOS/Direct3D9/src/HLSL_RainbowFogbow/docs/RainbowFo gbow.pdf [8] Dobashi Y., T. Yamamoto, and T. Nishita. 2001. "Efficient Rendering of Lightning Taking into Account Scattering Effects due to Clouds and Atmospheric Particles." http://nis-lab.is.s.utokyo.ac.jp/~nis/cdrom/pg/pg01_lightning.pdf [9] Texturing and Modeling: A Procedural Approach (third edition) Ebert, Musgrave, Peachey, Perlin, Worley Morgan Kaufmann Publishers, 2003 ISBN 1-55860-848-6