Registriert: Do Mär 06, 2003 15:27 Beiträge: 281 Wohnort: Bochum
also, ich habe mir schon einige tutorials über stencil shadows durchgelesen, und bin nun irgendwie verwirrt! Wenn ich das Prinzip richtig verstanden habe,
muss mann für jedes Schattenwerfende Objekt noch eine spezielle geometry struktur haben , die angibt ob ein Primitive noch einen Nachbar hat und um dann prüfen zu können ob dieser sichbar ist. wenn dieser nich sichbar ist, haben wir es mit einem Schattenwerfenden Primitive zu tun und nehmen uns die Kante und verlängern diese in die gegenrichtung des eintreffenden lichtes...das entstehende primitive wird in den stencilbuffer gerendert. und hinterher wird ein schattenrechteck über den screen gezogen und nur an den stellen gerendert wo was im stencilbuffer steht!
weiß jemand ob ich das richtig verstanden habe ?
weitere frage, werden die berechnungen net sehr aufwendig, da sie für jede weitere lichtquelle neu berechnet werden müssen ?
Registriert: Do Mär 06, 2003 15:27 Beiträge: 281 Wohnort: Bochum
Schade das keiner antwortet, aber mir fällt noch ne andere frage ein, wie wird denn in recht komplexen spielen (z.b doom3) der echtzeitschatten realisiert, also der schatten der von sich ständig bewegenden meshes???arbeiten die auch mit stencilshadow-volumes?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Da ich mit volumetrischen Stencilshadows selbst noch nicht gearbeitet (nur mit Shadowmapping und planaren Schatten im Stencilbuffer) hab,kann ich auf deine erste Frage leider keine Antwort geben.
Es gibt allerdings verschiedene Schattentechniken die in modernen Spielen verwendet werden, darunter auch Stencilschatten in Doom3.Half Life 2 z.B. nutzt hingegen Lightmaps (+statische Schatten) und Shadowmapping (wie auch z.B. die aktuelle Unrealengine).Jede dieser Techniken hat natürlich ihre Vor- und Nachteile, die ich hier im Forum allerdings bereits mehrere Male offengelegt hat (benutz dazu mal die Suchfunktion).
Meiner Meinung nach sind momentan allerdings projezierte Shadowmaps und statische Schatten in Lightmaps aufgrund von Hardwarelimitationen die bessere Wahl.Stencilshatten brauchen oft sehr viele Renderpasses,verbraten recht viel Füllrate und haben scharfe Kanten (lässt sich zwar durch Jittering umgehen, allerdings nicht auf aktueller Hardware die damit überfordert wäre).
muss mann für jedes Schattenwerfende Objekt noch eine spezielle geometry struktur haben , die angibt ob ein Primitive noch einen Nachbar hat und um dann prüfen zu können ob dieser sichbar ist
Hmm, nicht wirklich. Du brauchst allerdings Zugriff auf die Geometriedaten deiner Objekte, dann kannst du die Schattenvolumen in Echtzeit generieren (indem du die Silhouette von der Lichtquelle aus gesehen verlängerst). Interessant ist Carmacks Reverse, da dabei auch der Beobachter im Schatten stehen darf (bei "normalen" Schattenvolumen müsste man zuerst berechnen, ob man "innerhalb" des Schattenvolumens steht - und dann die Logik umkehren - was relativ umständlich zu implementieren ist). Carmacks Reverse ist allerdings Füllratenintensiver (in Mcad bzw. Ogl stehen deshalb auch beide Schattentechniken zur Auswahl - für Top-Down Spiele sind "normale" Schattenvolumes ja völlig ausreichend) Den NVidia Trick Schattenvolumen mit der w-Koordinate ins Unendliche zu projizieren, kann ich übrigens nicht empfehlen - auf ATI Karten (zumindest meiner Radeon 9000) bremst die zusätzliche Geometrie viel mehr, als die Berechnung von Schattenvolumen mit fester Länge (ausserdem hat man dann mehr Kontrolle, wie weit ein Objekt überhaupt Schatten werfen darf).
Zitat:
wie wird denn in recht komplexen spielen (z.b doom3) der echtzeitschatten realisiert, also der schatten der von sich ständig bewegenden meshes???arbeiten die auch mit stencilshadow-volumes?
Ja. Ich habe übrigens in der Projektesektion unter Mcad ein Demo eines animierten Stencilshadowvolumes (Doom 3 ist es halt nicht gerade ). Kannst es dir ja mal ansehen, es ist der vollständige Source dabei (allerdings habe ich die Ogl Schattentechnik inzwischen um einiges optimiert). Eigentlich sind Stencilshadows sogar sehr einfach, wenn man mal das Prinzip verstanden hat (ok, das trifft eigentlich auf fast alles zu).
Zitat:
weitere frage, werden die berechnungen net sehr aufwendig, da sie für jede weitere lichtquelle neu berechnet werden müssen ?
Nicht wirklich. Berechnet werden ja nur die Schattenvolumen der schattenwerfenden Objekte - wenn man sich die Implementation etwas überlegt (also nicht grad die Schattenvolumes in dynamischen Variablen berechnet, die bei jedem Berechnung die Größe ändern), geht es wirklich sehr schnell (solange die Berechnung nur einen Bruchteil der Füllratenzeit ausmacht, ist alles im grünen Bereich).
Aufwendiger wird es, wenn man tatsächlich für jede Lichtquelle den ganzen Framebuffer neu berechnet und die Ergebnisse überblendet - ich sehe allerdings keinen Riesenunterschied zu der Technik, den Framebufferteil im Schatten einfach ein wenig abzudunkeln - was sogar den Vorteil hat, dass man Schattenfarben definieren kann.
Beim Doom3 wird nicht ein Quad über den Bildschirm gezeichnet um abzudunkeln, sondern es wird da wo Schatten ist eben kein Licht addiert. Das mit dem Abdunkeln geht nur bei einer Lichtquelle korrekt. Für jede Lichtquelle muß der Schatten einzeln berechet werden und danach an den Stellen,die nicht im Schatten liegen, daß gebumpmapte Licht hinzugefügt werden. Daher hängt die Geschwindigkeit sehr von der Anzahl der Lichtquellen ab. Auf einer GF4 sind aber 2-3 gleichzeitig sichtbare Lichter von der Geschwindigkeit her akzeptabel. Die spezielle Struktur mit den Ecken ist daher sinnvoll, damit man eben schnell weiß, wo eine Kante des Volumen entstehen soll. Das ist immer der Fall wenn von zwei verbundenen Dreiecken eins zum Licht hin und das andere vom Licht abgewandt ist. Man kann auch die Volumen im Vertex Programm extruhieren lassen. Dafür muß man aber an jeder Kante degenerierte Dreiecke einfügen, die dann extruhiert werden. Da sich die Dreiecksanzahl verdreifacht, lohnt sich diese Technik nicht wirklich. Die Sache mit Stencil Schatten ist, daß sie wirklich geometrisch korrekten Schatten liefen. Wenn man den Schatten ,wie SoS angesprochen hat, durch Jittering weich macht, hat man tatsächlich korrekten Halb und Kernschatten. Die Weichheit des Schattens hängt auch von der Entfernung von der Lichtquelle ab. Es ist also alles ziemlich exakt. Es reichen für schon 16 versetzte Lichtquellen aus, damit der Schatten halbwegs weich wirkt. Optimal wären natürlich noch mehr, aber so teuer ist das nicht, weil man ja für jede der 16 Einzellichter nicht Bumpmapping berechnen muß, sondern nur die Helligkeit in den Alpha Buffer addieren kann. Auf der GF4 ging gerademal ein Licht mit dieser Qualität. Aber auf neuerer Hardware könnte man es eventuell schon flüssig hinbekommen. Wenn man z.B. von einer Figur Schatten auf die Landschaft wirft, dann ist ja eh nicht so viel von den Volumen zu sehen, so daß ich das dort durchaus mal probieren würde. Der weiche Stencil Schatten hat eine änliche Qualität wie weichgezeichnete Lightmaps mit einer extrem hohen Auflösung.
Da ich nicht wusste, ob ich in noeskas Thread auch was schreiben darf :
Also ich hab diese ganze Geschichte mit Kanten, Silhouette und extrudieren jetzt durch, aber weil ich mich mit dem Stencil Puffer wohl nicht so auskenne, komm ich hier nicht weiter. So siehts grad bei mir aus:
Code:
//== Stencil Puffer löschen
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);
//== Ambienten Durchgang
glColor3f(0.1,0.1,0.1);
drawmap;
glDepthMask(FALSE);
glEnable(GL_STENCIL_TEST);
//== Hab ich von der Delphi3D Demo, keine Ahnung warum $FFFFFFFF ?!?!
//== Rückseiten: Stencil Puffer verringern um nicht auch den \"Schattenstrahl\" als Schatten zu zeichnen
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, GL_KEEP, gl_decr_wrap);
drawshadows;
//== Jetzt wieder zurücksetzen und nur was durchlassen, was 0 ist
glStencilFunc(GL_EQUAL,0,$FFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);//= Den Stencil Puffer nicht verändern
//== Alles wieder zurücksetzen, zum zeichnen der Szene bereit machen
glCullFace(GL_BACK);
glColorMask(TRUE,TRUE,TRUE,TRUE);
glDepthMask(TRUE);
//== Überblenden
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
//== Szene da zeichnen, wo kein Schatten ist
glcolor3f(1,1,1);
drawmap;
gldisable(gl_blend);
gldisable(gl_stencil_test);
So, wie gesagt, so ganz klar ist mir das mit dem $FFF und so noch nicht ... Die Schattenvolumen funktionieren eigentlich. Beim zeichnen ohne Stencil Puffer sehen die ja auch so aus, wie es sein sollte. Nur jetzt sieht man gar nichts, nur die Szene zweimal aufeinandergeblendet. Im Create Teil setze ich den Clear Wert für den Stencil Puffer auf 0.
Ich hab schon ein bisschen mit den Funktionen herumgespielt (glstencilfunc, parameter ändern und so...) aber das hat nichts genützt... Wär sehr freundlich, wenn mir jemand zeigen könnte, was falsch gemacht wurde
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Der Code sieht i.O. aus (ohne Garantie), aber du hast vergessen die Stencilmaske auf $FF (=255) zu setzen, was wohl dein Fehler sein dürfte. Also am vorm Rendern in den Stencilpuffer glStencilMask($FF);!
P.S. : Dass was du machst nennt sich übrigens "zPass" und funzt nur, solange du dich nicht in einem Schattenvolumen befindets. Also nicht über Fehldarstellungen wundern, wenn du ein Schattenvolumen betrittst. Wenn du das umgehen willst, musst du auf "zFail" umsteigen. Dazu muss man die Schattenvolumen aber mit Deckeln (vorne und hinten) versehen und idealerweise auch ins Unendliche extrudieren.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Zeig mal nen Screenshot von deiner Szene auf dem man auch die extruhierten Volumen sieht. Evtl. lässt sich da dein Problem erkenne. Ich gehe aber mal davon aus dass alle deine Objekte geschlossen sind, oder?
Ja, die Objekte sind geschlossen, zumindest das, was Schatten werfen soll. Eigentlich besteht die Szene nur aus einem Großen Würfel mit Polygonen die nach innen zeigen (der Raum), und einen Kleinen in dem großen, der Schatten werfen soll.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Wie sieht denn dein Tiefentest aus? Und bist du sicher das dein Face-Winding auch korrekt ist? Und ein Pixelformat mit Stencil-Bits hast du sicherlich angefordert, oder?
Also falls du mit Face-Winding meinst, wie rum die Quads der Stencil Volumen gedreht sind, also cw oder ccw, da bin ich mir sicher, das hab ich extra nochmal überprüft. Und falls du mit "und ein Pixelformat mit Stencil-Bits hast du sicherlich angefordert, oder?" das meinst:
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT); dann hab ich das getan und ich hab glclearstencil vorher auf 0 gesetzt. Und der Tiefentest, fallst du das meinst: ( ) der ist GL_LEQUAL.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Nein, mit "und ein Pixelformat mit Stencil-Bits hast du sicherlich angefordert, oder?" habe ich gemeint ob dein Pixelformat Stencilbits hat (siehe CreateRenderingContext). Wenn da nämlich 0 Stencilbits drinstehen, kann der Stencil ja nicht gehen. Da solltest du mal zur Sicherheit nachsene. Im Normalfall bekommt man zwar wenn man 24 Bit Tiefe anfordert (und man im 32-Bit Modus) ist bei fast allen Karten 8 Bit Stencil (auch wenn man nicht anfordert), aber Nummer sicher kann nicht schaden.
Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.