CARL VON OSSIETZKY Projection Shadows Johannes Diemke Übung im Modul OpenGL mit Java Wintersemester 2010/2011 Projection Shadows Motivation I Schatten sind ein wichtiger Grundbestandteil beim Erzeugen realistischer Bilder I Geben dem Betrachter Hinweise über die Platzierung und Ausdehnung von Objekten I Die wichtigsten Verfahren für Echtzeit sind: Projection Shadows Shadow Volumes Shadow Map Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 2/28 Projection Shadows FIFA International Soccer (1994) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 3/28 Projection Shadows Nascar Racing (1995) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 4/28 Projection Shadows Tomb Raider (1996) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 5/28 Projection Shadows Doom 3 (2004) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 6/28 Projection Shadows Planare Schatten I Einfacher Spezialfall bei dem Schatten auf eine planare Fläche geworfen wird I Im Folgenden ausschließlich Betrachtung dieses Spezialfalls I Verwendete Terminologie: Occluder sind Objekte die Schatten auf Receiver werfen Punktlichtquellen erzeugen nur Hard Shadows (scharfe Konturen) Flächenlichtquellen dagegen Soft Shadows Es wird zwischen Kernschatten und Halbschatten unterschieden Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 7/28 Projection Shadows Terminologie Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 8/28 Projection Shadows Projection Shadows I Verfahren zur Darstellung von planaren Schatten I Berechnet Schatten automatisch aus den schattenwerfenden Occludern Um den Schatten zu erzeugen wird das dreidimensionale Objekt ein zweites Mal gerendert Eine Matrix wird hergeleitet um die Raumkoordinaten eines Objektes auf eine Ebene zu projizieren I Zunächst die Herleitung für planare Schatten auf der Ebene y = 0 Idee: Zwei ähnliche Dreiecke haben gleiche Seitenverhältnisse Projektion für die x- und y-Koordinate finden Für y gilt immer y = 0 Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 9/28 Projection Shadows Herleitung der Projektion für die x-Koordinate ly ly vx − lx vy px − lx = ⇐⇒ px = vx − lx ly − vy ly − vy Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 10/28 Projection Shadows Herleitung für die Projektion auf die Ebene y = 0 I Analog zu px ergibt sich pz , so dass wir insgesamt die folgenden Gleichungen erhalten: px = ly vx − lx vy ly − vy py = 0 pz = Johannes Diemke ly vz − lz vy ly − vy OpenGL mit Java WiSe 2010 / 2011 11/28 Projection Shadows Herleitung für die Projektion auf die Ebene y = 0 I Die Gleichungen können jetzt in eine Projektions-Matrix M überführt werden: ly 0 M= 0 0 −lx 0 −lz −1 0 0 ly 0 0 0 0 ly I Es lässt sich einfach zeigen, dass Mv = p tatsächlich gilt Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 12/28 Projection Shadows Verallgemeinerung für beliebige Ebenen I Im Allgemeinen soll Schatten auf eine beliebige Ebene π : n · x + d = 0 geworfen werden I Ebene liegt hier in Normalform vor n ist ein beliebiger Normalenvektor der Ebene d ist ein Skalar, das den negativen Abstand entlang des Normalenvektors ausgehende vom Ursprung n zur Ebene angibt Ist ein beliebiger Punkt p der Ebene sowie ein beliebiger Normalenvektor n der Ebene gegeben, so ergibt sich d durch: d = −n · p Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 13/28 Projection Shadows Projektion auf eine beliebige Ebene π :n·x+d =0 Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 14/28 Projection Shadows Herleitung der Projektion auf eine Ebene π : n · x + d = 0 I Die Gerade r ausgehend von der Lichtquelle l durch den Punkt v ist gegeben durch: r : l + γ(v − l) I Weiterhin ist die Ebene π auf die der Schatten projiziert werden soll gegeben durch: π :n·x+d =0 Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 15/28 Projection Shadows Herleitung der Projektion auf eine Ebene π : n · x + d = 0 I Durch Einsetzen der Geradengleichung r in die Ebenengleichung lässt sich ein γ finden für das die Gerade die Ebene schneidet: n · (l + γ(v − l)) + d = 0 ˙ − l) + d = 0 n · l + γn(v γn · (v − l) = −d − n · l −d − n · l γ = n · (v − l) I Durch Einsetzen von γ in die Geradengleichung r ergibt sich der Schnittpunkt p: −d − n · l p = l+ (v − l) n · (v − l) d +n·l = l− (v − l) n · (v − l) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 16/28 Projection Shadows Projektion auf eine Ebene π : n · x + d = 0 I Der Strahl ausgehend von l durch den Punkt v schneidet die Ebene π I Dies führt zu dem projizierten Punkt p: p=l− d +n·l (v − l) n · (v − l) I Die Gleichung kann jetzt wieder in eine Projektions-Matrix M überführt werden: n · l + d − lx nx −ly nx M= −lz nx −nx Johannes Diemke −lx ny n · l + d − ly ny −lz ny −ny OpenGL mit Java −lx nz −ly nz n · l + d − lz nz −nz −lx d −ly d −lz d n·l WiSe 2010 / 2011 17/28 Projection Shadows Umsetzung des Verfahrens I Um Schatten darzustellen, muss die Matrix M auf die Objekte, die Schatten werfen sollen, angewendet werden I Die projizierten Objekte sollten mit einer dunklen Farbe gerendert werden I Z-Fighting Probleme, die durch die Projektion auf die Ebene enstehen, müssen berücksichtigt werden: Versatz der Projektions-Ebene zur Fläche, so dass der Schatten immer vor der Fläche gerendert wird Alternativ: projizierte Objekte mit ausgeschaltetem Z-Buffer zeichnen I Der Stencil-Buffer wird benötigt um den Schattenwurf auf die Fläche zu beschränken Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 18/28 Projection Shadows Umsetzung in OpenGL I Im Folgenden wird zunächst d und n · l berechnet um dann M t zu konstruieren: public PhotekProjectionShadows(PhotekVector3D lightPosition, PhotekPlane plane) { shadowMatrix_ = new float[16]; lightPosition_ = lightPosition; plane_ = plane; } public void constructShadowMatrix() { float NdotL, d; d = -plane_.point_.dot(plane_.normal_); NdotL = plane_.normal_.x * lightPosition_.x + plane_.normal_.y * lightPosition_.y + plane_.normal_.z * lightPosition_.z; Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 19/28 Projection Shadows Umsetzung in OpenGL shadowMatrix_[0 shadowMatrix_[1 shadowMatrix_[2 shadowMatrix_[3 ] ] ] ] = NdotL + d - lightPosition_.x * = - lightPosition_.x * = - lightPosition_.x * = - lightPosition_.x * plane_.normal_.x; plane_.normal_.y; plane_.normal_.z; d ; shadowMatrix_[4 shadowMatrix_[5 shadowMatrix_[6 shadowMatrix_[7 ] ] ] ] = - lightPosition_.y = NdotL + d - lightPosition_.y = - lightPosition_.y = - lightPosition_.y * * * * plane_.normal_.x; plane_.normal_.y; plane_.normal_.z; d ; shadowMatrix_[8 ] shadowMatrix_[9 ] shadowMatrix_[10] shadowMatrix_[11] = = = NdotL + d = - * * * * plane_.normal_.x; plane_.normal_.y; plane_.normal_.z; d ; shadowMatrix_[12] shadowMatrix_[13] shadowMatrix_[14] shadowMatrix_[15] = = = = lightPosition_.z lightPosition_.z lightPosition_.z lightPosition_.z - plane_.normal_.x; - plane_.normal_.y; - plane_.normal_.z; NdotL; } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 20/28 Projection Shadows Umsetzung in OpenGL I Mit der Methode applyShadowMatrix(GL gl) wird die Projektions-Matrix angewendet: public void applyShadowMatrix(GL gl) { gl.glMultTransposeMatrixf(shadowMatrix_, 0); } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 21/28 Projection Shadows Umsetzung in OpenGL I Zunächst das Objekt und daraufhin den Schatten rendern: model.draw(gl); shadows.applyShadowMatrix(gl); // Den Schatten nicht mehrfach transparent uebereinander rendern gl.glEnable(GL.GL_STENCIL_TEST); gl.glStencilFunc(GL.GL_EQUAL, 0, 0xFFFFFFFF); gl.glStencilOp(GL.GL_KEEP,GL.GL_KEEP,GL.GL_INCR); gl.glDisable(GL.GL_LIGHTING); gl.glEnable(GL.GL_BLEND); gl.glColor4f(0,0,0,0.7f); model.draw(gl); gl.glDisable(GL.GL_STENCIL_TEST); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 22/28 Projection Shadows Umsetzung in OpenGL Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 23/28 Projection Shadows Auftretende Probleme I Die beiden genannten Projektions-Matrizen führen nicht in jedem Fall zum gewünschten Verhalten Ist die Lichtquelle unter der obersten Raumkoordinate eines Objektes, werden Anti-Shadows generiert Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 24/28 Projection Shadows Nachteile I Schatten nur auf planaren Flächen möglich I Soft Shadows sollten Hard Shadows vorgezogen werden Schatten mit scharfen Konturen können teilweise als geometrische Beschaffenheit fehlintepretiert werden (bspw. als Falten in Oberflächen) Hard Shadows sehen in vielen Szenarien unnatürlich aus Existieren ideale Punktlichtquellen in der Realität? I Aufwand des Verfahrens hängt von der Komplexität der Szene ab Objekte, die Schatten werfen sollen, müssen ein zweites Mal gerendert werden I Anti-Shadows und False-Shadows möglich Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 25/28 Projection Shadows Vorteile I Verfahren ist sehr einfach zu implementieren I Wichtiger als schöner und naturgetreuer Schatten ist es überhaupt Schatten zu haben (Bsp. Blob Shadows) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 26/28 Literatur und Links Mason Woo, Jackie Neider, Tom Davis and Dave Shreiner OpenGL Programming Guide http://www.opengl.org/documentation/red book/ Randi J. Rost OpenGL Shading Language http://www.3dshaders.com/ Richard S. Wright and Michael Sweet OpenGL SuperBible http://www.starstonesoftware.com/OpenGL/ Tomas Möller and Eric Haines Real-Time Rendering http://www.realtimerendering.com/ Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 27/28 Literatur und Links Fletcher Dunn and Ian Parberry 3D Math Primer For Graphics and Game Development http://www.gamemath.com/ Khronos Group OpenGL Homepage http://www.opengl.org/ Game Technology Group at Sun Microsystems JOGL API Project https://jogl.dev.java.net/ Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 28/28