ich versuche gerade einen Szene mittels Deferred Shading zu beleuchten. Dafür sind ja 3 Texturen (Normal-, Vertex- und Colortexture) nötig, die dann an einen 2D - Shader weitergegeben werden. Das Problem liegt beim Erstellen der Vertex - Texture, diese wird nicht korrekt erstellt. Ich verwende folgenden Shader für die Vertex - Texture:
Ich vermute auch woran es liegt: Daran, dass die Farben die man an "gl_FragColor" gegeben hat, nachträglich verändert wird. Ich habe auch schon versucht den Wert dess Vektors unterhalb von 1.0 zu bekommen (/ 1000.0), aber das ändert leider nichts... Ist es irgentwie möglich die Position in die Textur zu schreiben und diese dann auch gültig wieder auszulesen?
1) 8 bit werden für eine Vertextextur wohl zu wenig sein. Mehr bit nehmen und gut ist (möglicherweise)
2) in der Vertextextur speicherst du doch grundsätzlich daten, die du doch eigentlich bereits durch die xy koordinaten des Pixels und den Wert im Tiefenpuffer hast. Projektion rückgängig machen, und du hast auch wieder deine Werte. (Also anstelle von auslesen der Vertextextur)
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
(hier war doch vorhin noch… verwirrt…)
Ja, mehr Bits und vorallem eine Floattextur für die Vertex- und Normalendaten bietet sich an. Und was sharkman in Punkt zwei anspricht ist auch richtig. Du brauchst keine Vertextextur in dem Sinne. Projektion zurückrollen anhand von xy und z des Ausgabevertex sollte reichen.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Das Problem an der Sache ist das du mittels FramebufferObject und MRT nicht verschiedene Datentypen schreiben kannst. Also wenn du eine Float-Textur verwendest, dann muss alles Float sein, also auch Farben und Normale. Falls du eine Float-Textur möchtest, dann benutze GL_RGBA32F_ARB oder GL_RGB32F_ARB als internes Format für alle deine Texturen für den Deferred Shader.
Wenn du aber die Vertexposition wie von meinen Vorrednern beschrieben rekonstruierst kannst du dir das sparen. Die Normale müsste sich auch in 4x8bit kodieren lassen und Farben natürlich sowieso. Z.B. zwei Achsen der Normale (z.B. X und Y) in je zwei der Farbkanäle packen. Also den Bereich -1...1 auf den Bereich 0...65535 mappen und das auf zwei Farbkanäle (z.B. R und G) verteilen. (*) Die dritte Achse ergibt sich automatisch daraus, dass die Länge der Normale 1 sein muss. Was noch fehlt ist das Vorzeichen der Z-Achse. Dieses könntest du vielleicht in den Alpha-Kanal der Farbtextur packen, falls dieser nicht anderweitig benötigt wird. Letztlich benötigst du nur 1 Bit dafür.
Hinweis: Das ist jetzt eine spontane Überlegung...also ich hab nicht ausprobiert ob das funktioniert bzw. sinnvoll ist. Wenn du des einfacher möchtest kannst du natürlich auch einfach die Normale auf drei 8bit Farbkanäle verteilen.
Edit: (*) Shader-Output muss immer zwischen 0 und 1 liegen, also jeden Farbkanal einzeln nochmal durch 255 teilen.
Nein, sollte eigentlich nicht noch fehlen. Sinnvoller weise hat man nämlich eh BackfaceCulling an, und sieht nur die Vorderseite der Primitive. Und dort zeigt dann auch die Normale hin (normalerweise, bzw ich wüsste nicht, wieso man es beim Deferred Shading anders machen sollte). Daraus ergibt sich, dass die Normale eigentlich immer zum Betrachter zeigt.
Natürlich ist es auch möglich, dass man Normalen braucht, die vom Betrachter wegzeigen (zB bei transparenten Objekten möglich, für den Fall dass hier noch eine Erweiterung auf Inferred Lighting geplant ist), dann muss man das natürlich irgendwie speichern.
Nein, sollte eigentlich nicht noch fehlen. Sinnvoller weise hat man nämlich eh BackfaceCulling an, und sieht nur die Vorderseite der Primitive.
Es geht um das Vorzeichen des Z-Achse, nicht um das der gesamten Normale. Hier zeigen z.B. beide Normalen in Richtung Kamera:
Dateianhang:
Normale.png [ 6.63 KiB | 8839-mal betrachtet ]
Ich muss allerdings zugeben, dass ich auch eine Weile gebraucht habe bis ich realisiert hatte. Ich dachte auch erst man würde das Vorzeichen nicht brauchen und hatte dann eine lang und breite Erklärung geschrieben wieso und warum....bis ich feststellte das es Unsinn ist [/Unsinn]
_________________ Yeah!
Zuletzt geändert von Coolcat am Mi Feb 09, 2011 12:57, insgesamt 3-mal geändert.
Ähm, wie kann die Kamera in Richtung x Achse schauen (so interpretiere ich zumindest dein Bild)? Soweit ich weiß sind da die Normalen nach der Transformation durch die NormalMatrix interessant (liegt hier mein Denkfehler?).
1) 8 bit werden für eine Vertextextur wohl zu wenig sein. Mehr bit nehmen und gut ist (möglicherweise)
8Bit? Ich dachte immer das wären 32Bit.... Na dann erklärt sich ja vieles von selbst.
Zitat:
2) in der Vertextextur speicherst du doch grundsätzlich daten, die du doch eigentlich bereits durch die xy koordinaten des Pixels und den Wert im Tiefenpuffer hast. Projektion rückgängig machen, und du hast auch wieder deine Werte. (Also anstelle von auslesen der Vertextextur)
Stimmt, dadurch spare ich sogar einen Renderpass. Habs gerade so versucht, aber so wies aussieht funktionierts net richtig.
Das Problem an der Sache ist das du mittels FramebufferObject und MRT nicht verschiedene Datentypen schreiben kannst. Also wenn du eine Float-Textur verwendest, dann muss alles Float sein, also auch Farben und Normale. Falls du eine Float-Textur möchtest, dann benutze GL_RGBA32F_ARB oder GL_RGB32F_ARB als internes Format für alle deine Texturen für den Deferred Shader.
Ich verwende normale Texturen, also keine Framebuffer. Aber ich glaube das ist egal. Das mit der Float-Textur muss ich mal ausprobieren, thx .
Ich verwende normale Texturen, also keine Framebuffer.
Ein FramebufferObject (FBO) verwendet ebenfalls "normale" Texturen. Der Vorteil ist aber das du direkt in die Textur rendern kannst. Ansonsten renderst du nämlich erst in einen Framebuffer und musst dann die Daten nochmal extra in eine Textur kopieren.
Des weiteren kannst du mittels FBO in mehrere Texturen gleichzeitig rendern. Stichwort: MultipleRenderTargets (MRT). Im Fragmentshader benutzt du dann statt gl_FragColor einfach gl_FragData[0], gl_FragData[1] usw... Ist auch im FBO Tutorial erklärt. Mit dem Deferred Shading willst du ja vermutlich Performance rausholen, also die Szene nicht öfter als notwendig rendern
Mit dem Deferred Shading willst du ja vermutlich Performance rausholen, also die Szene nicht öfter als notwendig rendern
Richtig, aber ich habe erstmal keine FrameBuffer verwendet, weil das ganze auch auf älterer Hardware laufen soll. Aber ich werde noch alle 2 Varianten einbaun, also falls die Hardware FrameBuffer unterstützt, werden die genutzt, ansonsten wird so gerendert wie ichs momentan mach.
Das mit der Float-Textur geht glaub ich nicht, liegts an der Initialisierung?
glCopyTexImage2D kopiert aus dem primären Framebuffer. Dieser ist immer 8bit RGB oder 8bit RGBA. Selbst wenn also glCopyTexImage2D in der Lage wäre das in Float umzuwandeln, das wird dir nichts bringen da zwischen durch immer in 8bit umgewandelt wird.
=> Wenn du in Float-Texturen rendern möchtest musst du ein FramebufferObject benutzen. Des weiteren solltest du testen ob deine Hardware das überhaupt kann, d.h. die Extension GL_ARB_texture_float muss verfügbar sein. Wenn du davon ausgehst das deine User nicht mal Support für FBOs haben, kannst du die Nutzung von Float-Texturen vermutlich vergessen.
Bei glCopyTexImage2D mit GL_DEPTH_COMPONENT könnte es ein ähnliches Problem geben. Bin ich mir aber nicht sicher. Jedenfalls ist GL_DEPTH_COMPONENT im Wiki nicht als mögliches Argument aufgezählt.
Ok, bin jetzt doch auf Framebuffer umgestiegen und jetzt funktionierts auch endlich . Aber die Performance hat sich dadurch nicht verbessert, im Gegenteil sie hat sich verschlechtert. Wenn ich die Auflösung auf 1024x768 lasse hab ich 60 FPS (mehr geht nicht, kann VSync zurzeit komischerweise nicht abschalten). Wechsel ich die Auflösung auf 1680x1050 fällt die Framerate auf 40 - 45 FPS, was sich auch beim Rotieren der Kamera bemerkbar macht (wirkt unflüssig). Dabei besteht die Szene nur aus 2426 Vertices.
Ich verwende 4 Float-Texturen (Normal-, Vertex-, Color-, und Speculartexture). Jede dieser Texturen wird so initialisiert:
Du benutzt RGBA32F Texturen und davon 4 Stück, richtig? Dann ist jedes Fragment 64 Byte groß. Bei dieser Bildschirmauflösung erzeugst du so also 107 MB Daten. Das ganze kaust in jedem Frame zweimal durch (einmal schreiben, einmal lesen). Bei 45 fps erzeugst du also 9.4 GB/sek Speicherzugriffe. Ich hoffe das ist dir klar...
=> Versuche die Daten zu komprimieren! Tipps:
Brauchst du die Vertex-Textur oder reicht die Tiefe und errechnest dann später daraus die Position. Die Vertex-Position war der einzige Grund für 32bit Floats, oder?
Kannst du die Normale komprimieren wie oben beschrieben?
Brauchst du wirklich den Alpha-Kanal bei der Farbe?
Brauchst du wirklich die Specular-Farbe? Reicht vielleicht auch ein Graustufenwert oder ist die gar immer nur weiß?
Brauchst du den Shininess-Parameter?
Welche der obigen Werte müssen eigentlich Floats sein? Du kannst bis zu drei 8bit-Werte in einen 32bit Float packen! Werte zwischen 0 und 2^24 lassen sich verlustfrei in einem Float darstellen.
Zitat:
Dabei besteht die Szene nur aus 2426 Vertices.
Deferred Shading ist dafür gedacht wenn du komplexe Geometrie und gleichzeitig mehr Lichtquellen hast als du in einem Pass verarbeiten könntest. Die Idee ist das du nicht für jeden Pass die komplette Geometrie verarbeiten musst. Da deine Szene aber nun mit 2000 Vertices nicht wirklich komplex ist der Deferred Shading Ansatz natürlich eher kontraproduktiv.
Mitglieder in diesem Forum: 0 Mitglieder und 22 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.