PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fragen zu FBOs und RBOs


Asmodeus
2005-12-09, 07:12:44
Im Umgang mit FBOs und RBOs ist mir einiges noch nicht ganz klar.

1. Sehe ich es richtig, dass ein RBO immer nur entweder ein ColorBuffer oder ein DepthBuffer oder ein StencilBuffer sein kann, aber keine Kombinationen davon möglich sind? Dafür soll man dann mehrere Texturen als logische Buffer in einem FrameBuffer kombinieren?

2. Ich lege ein FBO an und erstelle zwei Texturen (einmal RGBA und einmal DEPTH_COMPONENT). Beide Texturen ordne ich dem FBO zu (COLOR_ATTACHMENT0 und DEPTH_ATTACHMENT). Das funktioniert auch ohne Probleme. Auch die einzelne Zuordnung der RGBA Textur funktioniert ohne Probleme. Nur wenn ich versuche nur die DEPTH_COMPONENT Textur als einzige Textur dem FBO zuzuordnen, dann erhalte ich bei glCheckFramebufferStatusEXT() immer den Status GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT. Woran liegt das?

Gruss, Carsten.

Demirug
2005-12-09, 08:15:32
Ich habe jetzt selbst noch nichts mit FBOs gemacht aber auch bei D3D ist es so das man nur mit einer "DEPTH_COMPONENT" nicht rendern kann. Man muss immer noch eine "RGBA_COMPONENT" dazu haben. Wahrscheinlich wird im Treiber der Render2Texture Code von D3D nun auch für die FBOs benutzt.

Corrail
2005-12-09, 11:11:56
1. Sehe ich es richtig, dass ein RBO immer nur entweder ein ColorBuffer oder ein DepthBuffer oder ein StencilBuffer sein kann, aber keine Kombinationen davon möglich sind? Dafür soll man dann mehrere Texturen als logische Buffer in einem FrameBuffer kombinieren?

Doch, es gibt [URL=http://oss.sgi.com/projects/ogl-sample/registry/EXT/packed_depth_stencil.txt]EXT_packed_depth_stencil[/URL, was einen gemischten Depth/Stencil Buffer anbietet. Da kann man in einem Renderbuffer sowohl Depth als auch Stencil haben.
Ansonsten ist die Philisophie eher die, dass eine Textur einen Buffer repräsentiert, entweder den DepthBuffer, den StencilBuffer oder einen Color Buffer.

2. Ich lege ein FBO an und erstelle zwei Texturen (einmal RGBA und einmal DEPTH_COMPONENT). Beide Texturen ordne ich dem FBO zu (COLOR_ATTACHMENT0 und DEPTH_ATTACHMENT). Das funktioniert auch ohne Probleme. Auch die einzelne Zuordnung der RGBA Textur funktioniert ohne Probleme. Nur wenn ich versuche nur die DEPTH_COMPONENT Textur als einzige Textur dem FBO zuzuordnen, dann erhalte ich bei glCheckFramebufferStatusEXT() immer den Status GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT. Woran liegt das?

Also erstmal ist es nicht so, wie Demirug gesagt hat. Die Spezifikation sieht auch FBOs mit nur einem Depth Buffer vor. Da musst du dann allerdings die Write Mask vom Color Buffer auf 0 setzen und den Read Buffer auf NONE. Probier das mal

Demirug
2005-12-09, 11:18:52
Also erstmal ist es nicht so, wie Demirug gesagt hat. Die Spezifikation sieht auch FBOs mit nur einem Depth Buffer vor. Da musst du dann allerdings die Write Mask vom Color Buffer auf 0 setzen und den Read Buffer auf NONE. Probier das mal

In der Spezifikation steht viel von dem nVidia mehr oder weniger öffentlich zugibt das es die Treiber (noch) nicht können.

Corrail
2005-12-09, 11:32:55
In der Spezifikation steht viel von dem nVidia mehr oder weniger öffentlich zugibt das es die Treiber (noch) nicht können.

Das mag schon sein. Aber ich bilde mir ein im OpenGL Forum mal wo gelesen zu haben, dass es auch schon funktioniert. Man muss aber wir schon gesagt die Write Mask auschalten und den Read Buffer auf NONE setzen (deshalb auch der Fehler GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT).

Asmodeus
2005-12-09, 12:28:50
Das mag schon sein. Aber ich bilde mir ein im OpenGL Forum mal wo gelesen zu haben, dass es auch schon funktioniert. Man muss aber wir schon gesagt die Write Mask auschalten und den Read Buffer auf NONE setzen (deshalb auch der Fehler GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT).

Also die ColorMask hatte ich schon auf Null gesetzt. Nur jetzt muss ich mal ganz blöd fragen, was meinst Du genau mit ReadBuffer auf NONE setzen?

Gruss, Carsten.

Simon
2005-12-09, 12:53:09
Also die ColorMask hatte ich schon auf Null gesetzt. Nur jetzt muss ich mal ganz blöd fragen, was meinst Du genau mit ReadBuffer auf NONE setzen?
Du mußt folgendes machen (direkt aus der Spec:

(7) Render to depth texture with no color attachments

// Given: depth_tex - TEXTURE_2D depth texture object
// fb - framebuffer object

// Enable render-to-texture
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

// Set up depth_tex for render-to-texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_DEPTH_ATTACHMENT_EXT,
GL_TEXTURE_2D, depth_tex, 0);

// No color buffer to draw to or read from
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();

<draw something>

// Re-enable rendering to the window
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glBindTexture(GL_TEXTURE_2D, depth_tex);
<draw to the window, reading from the depth_tex>

Asmodeus
2005-12-09, 12:58:38
Vielen Dank Simon. Ich hätte mich einfach mal an den alten Grundsatz erinnern sollen "Papier ist geduldig". Meine ausgedruckten Specs sind Revision 107 vom 17.1.2005. Und da gab es Beispiel Nummer 7 einfach noch gar nicht. *g*

Gruss, Carsten.

Asmodeus
2005-12-16, 09:46:28
Mit Schrecken habe ich jetzt festgestellt, dass die Geometrie in mein FBO irgendwie nur mit deaktiviertem DepthTest gerendert wird. Das Endergebnis in der Textur sieht jedenfalls sehr danach aus. Muss man da noch irgend etwas spezielles beachten, oder habe ich wieder was übersehen?

Gruss, Carsten.

zeckensack
2005-12-16, 10:37:05
Mit Schrecken habe ich jetzt festgestellt, dass die Geometrie in mein FBO irgendwie nur mit deaktiviertem DepthTest gerendert wird. Das Endergebnis in der Textur sieht jedenfalls sehr danach aus. Muss man da noch irgend etwas spezielles beachten, oder habe ich wieder was übersehen?

Gruss, Carsten.Jedes FBO braucht einen gültigen Depth Buffer, sonst gibt's keinen Depth Test. Entweder eine Textur oder vorzugsweise (wenn du keine Textur benötigst) einen "Render Buffer".

Beispiel 3:glGenFramebuffersEXT(1, &fb);
glGenTextures(1, &color_tex);
glGenRenderbuffersEXT(1, &depth_rb);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

// initialize color texture
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
GL_RGB, GL_INT, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, color_tex, 0);

// initialize depth renderbuffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_rb);

Asmodeus
2005-12-16, 10:52:51
Jedes FBO braucht einen gültigen Depth Buffer, sonst gibt's keinen Depth Test. Entweder eine Textur oder vorzugsweise (wenn du keine Textur benötigst) einen "Render Buffer".
...


Jepp, daran lag es. Obwohl ich noch nicht ganz verstehe, warum folgendes Szenario nicht richtig funktioniert: Ich verwende für das FBO eine Color-Textur und eine Depth-Textur. Und nun lege ich dafür auch noch ein Depth-RBO an (was zwar überflüssig ist, aber egal). Und dann steht in meiner Depth-Textur nur noch Mist drin. Wenn ich das RBO weglasse, dann stimmt der Inhalt der Depth-Textur wieder. Und eigentlich dürfte das RBO doch darauf keine Auswirkungen haben, oder?

Gruss, Carsten.

ScottManDeath
2005-12-16, 11:23:56
Musst mal in der spec nachsehen, was passiert, wenn mehrere Objekte, sei es Tex oder RBO für das selbe attachment gebunden sind. Sollte eigentlich undefined sein und glCheckFramebufferStatus sollte bumm machen.

zeckensack
2005-12-16, 11:31:30
Jepp, daran lag es. Obwohl ich noch nicht ganz verstehe, warum folgendes Szenario nicht richtig funktioniert: Ich verwende für das FBO eine Color-Textur und eine Depth-Textur. Und nun lege ich dafür auch noch ein Depth-RBO an (was zwar überflüssig ist, aber egal). Und dann steht in meiner Depth-Textur nur noch Mist drin. Wenn ich das RBO weglasse, dann stimmt der Inhalt der Depth-Textur wieder. Und eigentlich dürfte das RBO doch darauf keine Auswirkungen haben, oder?

Gruss, Carsten.Ähhhh ... da bin ich jetzt überfragt. Kannst du ein Schaubild malen? :D

Depth-Textur und Depth-RB gleichzeitig solltest du wirklich nicht brauchen. Ich wüßte auch nicht, wie man beides gleichzeitig in ein FBO kriegt, und was es den Treiber kümmern sollte :|
Benutzt du die gleiche Textur und/oder den gleichen RB in mehreren FBOs?
Treiber-Bug, evtl?

Asmodeus
2005-12-16, 12:17:32
Also in Pseudocode sieht die Sache etwa so aus:

GeneriereRBO-ID;
GeneriereFBO-ID;

BindeRBO;
SetzeStorageRBO auf GL_DEPTH_COMPONENT;

BindeFBO;
AttachColorTexturFBO;
AttachDepthTexturFBO;
AttachRBOzuFBO;

CheckFrameBufferStatus;

Der FrameBufferStatus ist dann COMPLETE, es funktioniert also. Wenn ich nach dem Rendern dann die Color-Textur auslese, dann ist der Inhalt auch korrekt. In der Depth-Textur stehen aber nur noch Nullen drin. Ohne AttachRBOzuFBO ist der Inhalt der Depth-Textur jedoch korrekt.

EDIT: Alles natürlich unter dem Vorbehalt, dass diese Kombination aus Depth-Textur und Depth-RBO eigentlich total überflüssig ist.

Gruss, Carsten.

zeckensack
2005-12-16, 12:32:15
Also in Pseudocode sieht die Sache etwa so aus:

GeneriereRBO-ID;
GeneriereFBO-ID;

BindeRBO;
SetzeStorageRBO auf GL_DEPTH_COMPONENT;

BindeFBO;
AttachColorTexturFBO;
AttachDepthTexturFBO;
AttachRBOzuFBO;Die letzte Zeile macht die vorletzte überflüssig. Du kannst nur ein Depth-Attachment haben. In dem Moment wo du einen RB an Depth bindest, fliegt die Depth Texture wieder raus. Das erklärt einiges ...Wenn ich nach dem Rendern dann die Color-Textur auslese, dann ist der Inhalt auch korrekt. In der Depth-Textur stehen aber nur noch Nullen drin.... zB das. Die DT war am Render-Vorgang schlicht und ergreifend nie beteiligt.
Ohne AttachRBOzuFBO ist der Inhalt der Depth-Textur jedoch korrekt.Was zu erwarten war. Aber dann ist die Farb-Textur im Eimer, was nicht zu erwarten war ...

Was mich jetzt doch sehr irritiert ist dein Startposting hier im Thread. Das las sich so, als hättest du mit gleichzeitigem RTT für Farbe und D keinerlei Probleme.

edit:
Hab's kapiert :redface:

Asmodeus
2005-12-16, 13:25:01
...
Was mich jetzt doch sehr irritiert ist dein Startposting hier im Thread. Das las sich so, als hättest du mit gleichzeitigem RTT für Farbe und D keinerlei Probleme.

Jetzt bin ich auch etwas durcheinander und verstehe nicht ganz, was Du damit meinst? Wenn ich gleichzeitig RTT für Farbe und D verwende, dann gibt es auch keine Probleme. Mein Problem war ja, dass ich D beim RTT vergessen hatte und deswegen dann auch die Farbtextur falsch war.

Gruss, Carsten.

zeckensack
2005-12-16, 13:46:31
Ich meinte dieses Problem:Mit Schrecken habe ich jetzt festgestellt, dass die Geometrie in mein FBO irgendwie nur mit deaktiviertem DepthTest gerendert wird. Das Endergebnis in der Textur sieht jedenfalls sehr danach aus. Muss man da noch irgend etwas spezielles beachten, oder habe ich wieder was übersehen?Ich musste mir dann überlegen was du gemacht haben könntest, weil die Fehlerbeschreibung nicht präzise war :)
Nur mit einer Depth Texture hättest du ein solches Problem IMO nicht haben können (einen konformen Treiber vorausgesetzt). Depth Texture und gleichzeitig Farbtextur rendern ging bei dir ebenfalls schon (Eingangsposting).

... und bin zu dem Schluss gekommen, dass du die Depth Texture weggelassen hast, weil du in diesem Fall nur an der Farbtextur interessiert warst.

Ich ging nun davon aus dass das "Endergebnis in der Textur" eine falsch bis garnicht tiefensortierte Farbtextur ist. Das war das einzige was mir in dem Moment logisch erschien.

Ganz ohne irgendeinen "Depth Buffer" (sei es nun eine Textur oder ein RB) an das FBO zu binden, ist es nicht möglich den Depth Test zu nutzen. So weit hielt ich das für einen ausgezeichneten Plan :D

So richtig aus der Bahn geworfen hat mich dann das:Und dann steht in meiner Depth-Textur nur noch Mist drin.Das las sich dann wieder so, als ob du nun doch am korrekten Inhalt der Depth Texture interessiert wärst, was wiederum hätte heißen müssen, dass du eben eine solche schon die ganze Zeit verwendet hast. Jedenfalls hatte ich das so interpretiert. Und so.

Aber ich glaube ich hab's mittlerweile begriffen :)

Asmodeus
2005-12-16, 14:24:33
Prima, dann wären ja wieder auf allen Seiten alle Unklarheiten und Fragen beseitigt. :)

Gruss, Carsten.

Expandable
2006-03-14, 17:50:17
Update: Simpler Treiberbug. Ein Treiberupdate von 77.72 auf 84.20 hat das Problem behoben.

Hallo,

ich hätte auch mal eine Frage zu FBOs: Ich erstelle zwei Stück davon und 4 Texturen. Die Texturen sind (haben übrigens Fenstergröße, also non-power-of-two):
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_winWidth, m_winHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_winWidth, m_winHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); (2 mal)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, m_winWidth, m_winHeight, 0, GL_RGBA, GL_FLOAT, 0);

Als ColorBuffer1 und 2 erhält das erste FBO die beiden RGBA8-Texturen. Beide FBOs erhalten die Depthtextur (wobei das eventuell noch durch ein RBO ersetzt wird). Die Float-Textur kommt an den 2. FBO als ColorAttachment0.

1.) Unterstützt eine GF6800GT keine GL_RGBA32F_ARB-Texturen? (es wird so langsam, dass das wahrscheinlich in Software gerechnet wird)

2.) Ich rendere meine Szene mit dem 2. FBO aktiv. Dabei wird in die Float-Textur die Positionen der Vertices der Szene reingeschrieben. Dafür braucht man ja Floats aus Genauigkeitsgründen.

3.) Ich rendere meine Szene mit dem 1. FBO aktiv. Dabei werden die Normalen und die Diffus-Werte der Szene in die beiden Colorbuffer geschrieben.

Das funktioniert einwandfrei, ich kann mir die Szene hinterher anzeigen lassen. Normalen und Diffuswerte werden korrekt berechnet (Positionen lassen sich nicht richtig anzeigen, scheinen aber zu stimmen, wie mir meine erfolgreichen Lichtberechnungen sagen).

Das Problem sind die Diffuswerte. Das sind ja ursprünglich alles ganz normale .tga-Texturen (in GL_RGB8 oder GL_RGBA8). Wenn ich diese über ein FBO in eine GL_RGBA8-Textur rechne, wird die Textur korrekt dargestellt. Wenn ich sie in eine GL_RGBA16F_ARB Textur rechne, habe ich einen starken Qualitätsverlust (wieso? 16 bit Floating Point pro Kanal müsste doch genauer sein als 8 Bit Fix Point pro Kanal?).

Aus diesem Grund habe ich aus einem FBO, wo also Position, Normalen und Diffuswerte gleichzeitig berechnet werden, in zwei getrennt, wie oben beschrieben. Doch sobald ich die "Positions-Textur" zu GL_RGBA16F_ARB mache, ist der starke Qualitätsverlust der Diffuswerte wieder da, obwohl diese in eine GL_RGBA8 FBO gerendert werden - und noch dazu ist es ein völlig anderer FBO!

Hat das jetzt jemand verstanden? ;o) Wäre für Tipps dankbar.

Expandable
2006-03-15, 16:15:53
Tja, wie's aussieht hat sich das Problem doch nicht ganz gelöst.

Also, ich habe einen Deferred Shading Algorithmus. Im ersten Pass werden nur Z-Werte geschrieben (Early Z Culling). Im zweiten Pass wird ein Framebuffer-Object mit drei GL_COLOR_ATTACHMENTS geschrieben, wobei alles drei Texturen im GL_RGBA16F_ARB-Format sind. In ATTACHMENT0 sind die Vertexpositionen, in ATTACHMENT1 sind die Diffus-Werte, in ATTACHMENT2 sind die Normalen (in Eyespace-Coordinates).

Die Diffus-Werte und die Normalen sind in Ordnung. Siehe folgende Screenshots:

http://img117.imageshack.us/img117/3283/diffuse5gu.jpg

http://img116.imageshack.us/img116/732/normals3qn.jpg

Doch nach den Lightpasses (wobei bislang noch alle Lichter einer Area auf dem kompletten Bildschirm "geshadert" werden) sieht das ganze dann ziemlich hässlich aus (nicht immer, aber an manchen Stellen). Es gibt so eine "Blockbildung". Warum? Es wird nur ein ein GL_QUAD gezeichnet in Bildschirmgröße, wobei die Farbwerte aufgrund der Werte im FBO ermittelt werden (und aufgrund der Lichtfarbe und -position natürlich). Die einzelnen Lichter werden per Blending (mit glBlendFunc(GL_ONE, GL_ONE)) geblendet. Zum Vergleich ein Multipass-Screenshot, wo das Problem nicht auftaucht!

http://img153.imageshack.us/img153/5021/multipass5dl.jpg

http://img116.imageshack.us/img116/7536/deferred6eu.jpg

Woran könnte das denn liegen? Die neusten Treiber (84.20, GF6800GT) sind drauf! ;) Danke schonmal...

ScottManDeath
2006-03-15, 21:38:12
Kannst Du mal ohne Texturen, diffuse lighting only und specular lighting only rendern?

Hast Du beim Lesen aus der Textur auch den 0.5 Texel Offset mit einbezogen, so dass ein Texel genau auf einem Pixel liegt?

Expandable
2006-03-16, 01:06:16
Hallo, hier der Screenshot mit Diffuse-Lighting ausschließlich (wobei ich die Normalmap zugrunde legen musste, weil ich keine andere Normale mehr habe, daher die Oberflächenstruktur). Auch hier ist das Problem deutlich zu erkennen. Specular wird im Deferred Modus noch nicht verwendet.

http://img520.imageshack.us/img520/6503/diffuseonly2um.jpg

Was für einen Texel Offset meinst Du? Seit wann braucht man beim Lesen aus einer Textur einen Texel Offset?

Interessant ist übrigens, dass das nicht bei allen Lichtern auftaucht. Könnte es etwas damit zu tun haben, wie oft der Bildschirm überzeichnet wird (je mehr Lichter, desto öfter wird der komplette Schirm überzeichnet momentan noch). Aber das würde doch nicht solche Artefakte verursachen, oder?

PS: Ich habe jetzt mal Vertex Buffer Objects integriert. In obiger Szene stiegen die FPS im Deferred Modus um + 1 und im Multipass Modus auf fast das 3fache!! Allerdings ist der Deferred Modus trotzdem meistens noch schneller (es sei denn, es gibt nicht viel zu tun, dann kommt man im Multiplass locker auf 300fps, im Deferred ist bei 100 Schluss... )

Nachtrag: An dieser Stelle wird der Bildschirm 38 mal überblendet. Hmm... an anderen Stellen mit nur 5 Überblendungen gibt's das Problem auch... in einem anderen Level mit 5 Überblendungen allerdings nicht... wobei an dem Level eigentlich nix anders ist (außer, dass ersteres wesentlich größer ist)...

Chris Lux
2006-03-16, 08:34:18
hi,
versuch doch mal die targets mit fp32 zu benutzen, da du keinen filter auf den texturen brauchst (ich meine die fullscreen quads) müsste das gehen. so kannst du testen, ob dir die genauigkeit ausgeht bei den vielen pässen.

mich würde auch interessieren, woran das liegt.

edit: bei opengl brauchst du dir keine sorge machen um die 0.5 texteloffset, bei dem fullscreenquad fällt die textelmitte genau auf die pixelmitte. also kein problem.

nop
2006-03-16, 11:09:49
Meine erste Vermutung ist, das die Normal-Textur eine kleinere Auflösung hat als das gerenderte Bild. Scheint mir aber zu offensichtlich, also ignorier mich (bitte, bitte)!

Chris Lux
2006-03-16, 11:17:22
Meine erste Vermutung ist, das die Normal-Textur eine kleinere Auflösung hat als das gerenderte Bild. Scheint mir aber zu offensichtlich, also ignorier mich (bitte, bitte)!
hmm habe ich auch vermutet, doch dann wären die kleinen features nicht so deutlich sichtbar (dh sie sind korrekt beleuchtet).

bewegt sich das block muster mit den oberflächen mit, oder ist es statisch am screen fest (dh die blöcke sind immer an der selben stelle am bildschirm)?

nop
2006-03-16, 11:41:26
Lux, stimmt auch wieder. Das Bild sieht allerdings eh falsch aus, weil die Normalen der Pannels ausser den Detals nicht identisch sind (die Flächen also nicht coplanar). Und warum gibt es Banding (Jpeg-Kompression)?

nop
2006-03-16, 11:47:50
Und warum gibt es Banding (Jpeg-Kompression)?
Meinte nicht wirklich Banding, aber die Helligkeit variiert an den Blockgrenzen stärker als das Auge interpretieren könnte. Die Normalen-Textur scheint gekachelt, obwohl das auf dem Falschfarbenbild nicht zu erkennen ist.

Chris Lux
2006-03-16, 11:56:08
Meinte nicht wirklich Banding, aber die Helligkeit variiert an den Blockgrenzen stärker als das Auge interpretieren könnte. Die Normalen-Textur scheint gekachelt, obwohl das auf dem Falschfarbenbild nicht zu erkennen ist.
also die normalen sehen für mich ok aus. ich würde aber bisher auf ein precission problem tippen (nachdem er 38mal überblendet).

meinst du mit 38mal überblenden raster operationen oder meinst du ping pong shader operationen in ein fp rendertarget?

Expandable
2006-03-16, 12:30:36
Also die Normalen scheinen in Ordnung zu sein, siehe Bild auf der vorherigen Seite.

Das Blockmuster ist fest und beweget sich keinen Millimeter wenn man durch die Gegend fliegt.

Bzgl. des Überblendens: Sowohl im Multipass als auch Deferred-Modus wird die Szene 38 mal gerendert. D.h., im Multipass wird 38 mal die gesamte Geometrie (mit Vertex und Pixel Shadern) für jedes Licht ausgeführt und dann ins Bild geblendet. Im Deferred Modus wird die Geometrie einmal gesendet, Positionen, Diffuswerte und Normalen gespeichert und dann 38 mal ein Fullscreenquad gerendert, dessen Farbwerte sich aus den gespeicherten Informationen des ersten Passes zusammensetzen.

"versuch doch mal die targets mit fp32 zu benutzen, da du keinen filter auf den texturen brauchst (ich meine die fullscreen quads) müsste das gehen. so kannst du testen, ob dir die genauigkeit ausgeht bei den vielen pässen."

Was soll ich in fp32 rendern? Also wenn ich die COLOR_ATTACHMENTS des FBO auf GL_RGBA32F_ARB setze, bekomme ich eine Access Violation bei meinen Vertex Buffer Objects (hä?). Und das Fullscreenquad hat ja nicht wirklich eine "Textur".

Aber es kann fast kein Precission Problem sein. Ich habe eben mal ein wesentlich kleineres Level (sollte es daran liegen?) erstellt und 22 Lichter in einen Raum eingefügt. Drei Stück davon waren direkt an der Wand, die Wand wurde insgesamt 22 mal überblendet. Funktioniert aber hier einwandfrei!

http://img72.imageshack.us/img72/5415/richtig8jp.jpg

Chris Lux
2006-03-16, 13:23:16
Was soll ich in fp32 rendern? Also wenn ich die COLOR_ATTACHMENTS des FBO auf GL_RGBA32F_ARB setze, bekomme ich eine Access Violation bei meinen Vertex Buffer Objects (hä?). Und das Fullscreenquad hat ja nicht wirklich eine "Textur".machst du das blending der 38 pässe im framebuffer oder in einem fp fbo?

weil 38mal in den 8bit unsigned int pro kanal framebuffer, das schreit nach präzisionsproblem. das sollte dann aber anders aussehen als dein problem. ehrlich gesagt habe ich keine ahnung wieso das an einer stelle passiert und an anderer nicht...

Expandable
2006-03-16, 13:34:12
Im Framebuffer. Ich hab's jetzt mal umgeschrieben und die Pässe in einem FBO gemacht - es ändert sich gar nichts. Wenn ich 32bit einstelle, passiert allerdings gar nichts mehr (hört einfach auf zu rendern). Das ist doch so aber richtig, oder:


glGenFramebuffersEXT(1, &m_lastBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_lastBuffer);

glBindTexture(GL_TEXTURE_2D, m_textures[4]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// funktioniert, aber gleiches Problem
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, m_winWidth, m_winHeight, 0, GL_RGBA, GL_FLOAT, 0);
// hört auf zu rendern
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, m_winWidth, m_winHeight, 0, GL_RGBA, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_textures[4], 0);

Chris Lux
2006-03-16, 14:06:32
Im Framebuffer. Ich hab's jetzt mal umgeschrieben und die Pässe in einem FBO gemacht - es ändert sich gar nichts. Wenn ich 32bit einstelle, passiert allerdings gar nichts mehr (hört einfach auf zu rendern). Das ist doch so aber richtig, oder:


glGenFramebuffersEXT(1, &m_lastBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_lastBuffer);

glBindTexture(GL_TEXTURE_2D, m_textures[4]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// funktioniert, aber gleiches Problem
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, m_winWidth, m_winHeight, 0, GL_RGBA, GL_FLOAT, 0);
// hört auf zu rendern
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, m_winWidth, m_winHeight, 0, GL_RGBA, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_textures[4], 0);

sieht ok aus.

kannst du den fall, wo es bei 5 pässen auch passiert mal schritt für schritt visualisieren (dh die zwischenergebnisse anzeigen) und schauen bei welchem schritt es auftritt. dann mal die eingaben zu diesem pass (dh die texturen) und den shader untersuchen. (wenns nix geheimes ist können wir ja auch hier einen blick darauf werfen)

Expandable
2006-03-16, 14:56:48
Hab ich gemacht (okay, war 'ne Stelle mit 24 Pässen, aber ist eh egal).

Diffusetextur:
http://img104.imageshack.us/img104/6686/diffuse5xu.jpg

Normalentextur:
http://img104.imageshack.us/img104/4853/normals4qd.jpg

Und nach dem ersten (!!!!) Pass:
http://img95.imageshack.us/img95/852/1stpass5rz.jpg

Geometrie Pass C++-Code:

m_shader_geometry->Enable();

GLuint diffuseMap = m_shader_geometry->GetUniformLocation("diffuseMap");
GLuint normalMap = m_shader_geometry->GetUniformLocation("normalMap");
GLuint specularMap = m_shader_geometry->GetUniformLocation("specularMap");

m_shader_geometry->SetUniform(diffuseMap, 0);
m_shader_geometry->SetUniform(normalMap, 1);
m_shader_geometry->SetUniform(specularMap, 2);

for (GLuint i = 0; i < *m_numAreaIndices; ++i)
m_areas[m_areaIndices[i]].DrawTextured();


Lighting-Pass C++-Code:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_lastBuffer);
glClear(GL_COLOR_BUFFER_BIT);
glDrawBuffers(1, m_colorBuffers);

glDisable(GL_DEPTH_TEST);
m_shader_lighting->Enable();

Set2DProjection();

GLuint lightRadius = m_shader_lighting->GetUniformLocation("lightRadius");
GLuint lightColor = m_shader_lighting->GetUniformLocation("lightColor");
GLuint lightPosition = m_shader_lighting->GetUniformLocation("lightPosition");
GLuint position = m_shader_lighting->GetUniformLocation("position");
GLuint diffuseColors = m_shader_lighting->GetUniformLocation("diffuseColors");
GLuint normals = m_shader_lighting->GetUniformLocation("normals");
//GLuint camPos = m_shader_lighting->GetUniformLocation("camPos");

m_shader_lighting->SetUniform(position, 0);
m_shader_lighting->SetUniform(diffuseColors, 1);
m_shader_lighting->SetUniform(normals, 2);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_textures[1]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, m_textures[2]);

glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);

// Draw all visible lights
Entity_Light *light = 0;
for (GLuint i = 0; i < *m_numLightIndices; ++i)
{
light = m_lights[m_lightIndices[i]];

m_shader_lighting->SetUniform(lightRadius, light->GetRadius());
m_shader_lighting->SetUniform(lightColor, light->GetColor());
m_shader_lighting->SetUniform(lightPosition, light->GetPosition());

DrawScreenRectangle();
}

glDisable(GL_BLEND);

// Draw to framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textures[4]);

glUseProgram(0);
DrawScreenRectangle();

Set3DProjection();


Geometry-Shader:

[Vertex Shader]
#version 110

// gl_MultiTexCoord0 = texture coordinates
// gl_MultiTexCoord1 = tangent
// gl_MultiTexCoord2 = bitangent

varying vec3 tangent;
varying vec3 bitangent;
varying vec3 position;
varying vec2 texCoords;
varying vec3 vertexNormal;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
position = gl_Vertex.xyz;

texCoords = gl_MultiTexCoord0.st;
tangent = gl_MultiTexCoord1.xyz;
bitangent = gl_MultiTexCoord2.xyz;

vertexNormal = gl_Normal;
}

[Fragment Shader]
#version 110

varying vec3 tangent;
varying vec3 bitangent;
varying vec3 position;
varying vec2 texCoords;
varying vec3 vertexNormal;

uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
uniform sampler2D specularMap;

void main()
{
mat3 textureSpaceMatrix = mat3(tangent, bitangent, vertexNormal);
vec3 fragmentNormal = texture2D(normalMap, texCoords).xyz;

fragmentNormal = 2.0 * fragmentNormal - 1.0;
fragmentNormal = normalize(textureSpaceMatrix * fragmentNormal);
fragmentNormal = 0.5 * fragmentNormal + 0.5;

gl_FragData[0] = vec4(position, 1.0); // 4th slot unused
gl_FragData[1] = texture2D(diffuseMap, texCoords); // 4th slot unused
gl_FragData[2] = vec4(fragmentNormal, 1.0); // 4th slot unused
}


Lighting-Shader:

[Vertex Shader]
#version 110

varying vec2 screenCoords;

uniform vec3 camPos;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
screenCoords = gl_MultiTexCoord0.st;
}

[Fragment Shader]
#version 110

uniform sampler2D position;
uniform sampler2D diffuseColors;
uniform sampler2D normals;
uniform float lightRadius;
uniform vec3 lightColor;
uniform vec3 lightPosition;

varying vec2 screenCoords;

void main()
{
vec3 position3d = texture2D(position, screenCoords).xyz;
vec3 diffuseColor = texture2D(diffuseColors, screenCoords).xyz;

vec3 normal = texture2D(normals, screenCoords).xyz;
normal = 2.0 * normal - 1.0;

vec3 lightVector = lightPosition - position3d;
float lightDistance = length(lightVector);

float attenuation = max((lightRadius - lightDistance) / lightDistance, 0.0);

float diffuseLight = max(dot(normal, normalize(lightVector)), 0.0);

gl_FragColor = vec4((diffuseLight * diffuseColor) * attenuation * lightColor, 1.0);
}

nop
2006-03-16, 15:50:04
Ohne wirklich Ahnung zu haben (heute ist unbekümmerter Blamiertag):
- Die weisse Fläche im Bild ist komplett überstrahlt, Weiss also massiv geclamped. Und das bereits bei einer Lichtquelle!
- Muss die Normale nicht normalisiert sein, oder ist sie das?
normal = 2.0 * normal - 1.0;
float diffuseLight = max(dot(normal, normalize(lightVector)), 0.0);

nop
2006-03-16, 16:08:20
Um mich für heute abzumelden, sowas kann doch gar nicht normalisiert sein (ohne es nachzurechnen):
fragmentNormal = 0.5 * fragmentNormal + 0.5;

Chris Lux
2006-03-16, 19:07:26
hi,
also ich würde an dieser stelle jetzt den finalen shader anweisung für anweisung testen. du hast doch fp targets für die einzelnen zwischenergebnisse (dh normale und diffuse usw), dann sollte es doch überflüssig sein die normale zu packen.

gib doch zum debuggen deine zwischenergebnisse des finalen shaders als farbe aus um zu sehen wo die blöcke hier eingeführt werden:

dh aus folgendem mal der reihe nach: normal, attenuation, diffuseLight als farbe rausgeben. ehrlich gesagt sehe ich in diesem shader keinen fehler der dies verursachen sollte.

void main()
{
vec3 position3d = texture2D(position, screenCoords).xyz;
vec3 diffuseColor = texture2D(diffuseColors, screenCoords).xyz;

vec3 normal = texture2D(normals, screenCoords).xyz;
normal = 2.0 * normal - 1.0;

vec3 lightVector = lightPosition - position3d;
float lightDistance = length(lightVector);

float attenuation = max((lightRadius - lightDistance) / lightDistance, 0.0);

float diffuseLight = max(dot(normal, normalize(lightVector)), 0.0);

gl_FragColor = vec4((diffuseLight * diffuseColor) * attenuation * lightColor, 1.0);
}

Expandable
2006-03-16, 21:45:25
nop: Die Normalen werden ja im Geometry-Shader normalisiert und dann in das FBO gepackt, und im Lighting-Shader dann wieder aus dem FBO geholt. Dabei bleiben sie ja normalisiert. Dass das weiß total überblendet ist, sehe ich allerdings ein. Es erklärt aber nicht, warum der Fehler nur manchmal auftritt (andere überstrahlte Flächen sind nicht "geblockt" und im Multipass passiert's auch nicht, obwohl nur RGBA8 (Integer!)-Format).

Chris Lux: Stimmt, bei FP16-Rendertargets ist das Packen der Normalen überflüssig. Hmm, muss wohl noch aus der Zeit stammen, wo ich mit zwei FBOs (ein RGBA16F_ARB für die Positionen und einen RGBA8 für die Normalen/Diffus-Werte) experimentiert habe.

Gibt es eigentlich wirklich keinen vernünftigen Debugger für Shader? Könnte man sowas mit RenderMonkey debuggen?

Nachtrag: Tja... sobald ich mir die attenuation oder diffuseLight Variable anzeigen lasse (gl_FragColor = vec4(attenuation bzw. diffuseLight , 0, 0, 1);) tritt das Problem auf. Und was sagt uns das jetzt? Treiberproblem?

Und wieso zum Teufel geht eigentlich kein FP32 Rendertarget? Laut nVidia-Docs sollte das gehen. Aber er rendert einfach gar nix mehr, wenn ich GL_RGB32F_ARB als Texturformat einstelle...

Chris Lux
2006-03-17, 09:50:32
Nachtrag: Tja... sobald ich mir die attenuation oder diffuseLight Variable anzeigen lasse (gl_FragColor = vec4(attenuation bzw. diffuseLight , 0, 0, 1);) tritt das Problem auf. Und was sagt uns das jetzt? Treiberproblem?

Und wieso zum Teufel geht eigentlich kein FP32 Rendertarget? Laut nVidia-Docs sollte das gehen. Aber er rendert einfach gar nix mehr, wenn ich GL_RGB32F_ARB als Texturformat einstelle...
ok poste bitte mal ein bild von der position3d variable. ich habe da eine vermutung.

Expandable
2006-03-17, 13:16:08
Da gibt's nicht viel zu posten. Das ist einfach nur ein blaues Bild mit ein paar schwarzen Flecken manchmal. Wird wohl daran liegen, dass die Positionen nicht geclampt sind.

Was hast Du für eine Vermutung?

Chris Lux
2006-03-17, 15:12:32
Was hast Du für eine Vermutung?
ich sehe keine fehler in deinem code, aber der fehler kann nur durch entweder die position3d, die normale und diffuseColor entstehen. es tut mir leid, aber so aus der ferne is das echt schlecht diese kleinen sachen zu testen. versuch doch einfach mal einen super kleinen fall zu schaffen wo dies passiert und man auch aus den texturen verwertebare daten beziehen kann (gerade bei der position interessiert mich das jetzt). für die ausgabe kannst du ja einfach die position mal durch (hmm sagen wir mal) 1000 teilen um sichtbare ergebnisse zu bekommen. irgendwoher müssen die blöcke ja kommen. überprüfe auch nochmal die auflösung deiner fbos, dass da nichts schiefgeht usw.

wenn du sagst, dass es schon bei attenuation auftritt kann es ja nur an der position liegen.

nebenfrage, es ist richtig, dass position und normale im object space gespeichert sind?

Expandable
2006-03-17, 17:05:26
Hmm... eigentlich nicht... okay, Positionen und Normalen werden nun in Eye Space gespeichert... und siehe da... ES GEHT!!

http://img101.imageshack.us/img101/5282/deferredok9de.jpg

Andererseits... die groben Fehler sind jetzt weg... an dieser Stelle gibt's allerdings ein kleines Problemchen im Vergleich zu Multipass (gibt noch ein paar andere Stellen, ebenfalls weniger auffällig als zuvor):

http://img101.imageshack.us/img101/2698/multipassok2yu.jpg

http://img126.imageshack.us/img126/285/deferredfalsch0qy.jpg

Ich scheine da also tatsächlich gegen irgendein Genauigkeits-Limit zu laufen. Nur welches? Und warum? Und wie kann ich das gänzlich lösen? Und was ist an Object-Space schlimmer als an Eye-Space?

Hier nochmal die beiden (angepassten) Shader:


[Vertex Shader]
#version 110

// gl_MultiTexCoord0 = texture coordinates
// gl_MultiTexCoord1 = tangent
// gl_MultiTexCoord2 = bitangent

varying mat3 textureSpaceMatrix;
varying vec4 position;
varying vec2 texCoords;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
position = gl_ModelViewMatrix * gl_Vertex;
position /= position.w;

texCoords = gl_MultiTexCoord0.st;
textureSpaceMatrix = mat3(gl_NormalMatrix * gl_MultiTexCoord1.xyz, gl_NormalMatrix * gl_MultiTexCoord2.xyz, gl_NormalMatrix * gl_Normal);
}

[Fragment Shader]
#version 110

varying mat3 textureSpaceMatrix;
varying vec4 position;
varying vec2 texCoords;

uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
uniform sampler2D specularMap;

void main()
{
vec3 fragmentNormal = texture2D(normalMap, texCoords).xyz;
fragmentNormal = 2.0 * fragmentNormal - 1.0;
fragmentNormal = normalize(textureSpaceMatrix * fragmentNormal);

gl_FragData[0] = vec4(position);
gl_FragData[1] = texture2D(diffuseMap, texCoords); // 4th slot unused
gl_FragData[2] = vec4(fragmentNormal, 1.0); // 4th slot unused
gl_FragData[3] = texture2D(specularMap, texCoords); // 4th slot unused
}

[Vertex Shader]
#version 110

varying vec2 screenCoords;

uniform vec3 camPos;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
screenCoords = gl_MultiTexCoord0.st;
}

[Fragment Shader]
#version 110

uniform sampler2D position;
uniform sampler2D diffuseColors;
uniform sampler2D normals;
uniform sampler2D specularColors;
uniform float lightRadius;
uniform vec3 lightColor;
uniform vec3 lightPosition;

varying vec2 screenCoords;

void main()
{
vec3 position3d = texture2D(position, screenCoords).xyz;
vec3 diffuseColor = texture2D(diffuseColors, screenCoords).xyz;

vec3 normal = texture2D(normals, screenCoords).xyz;

vec3 lightVector = lightPosition - position3d;
float lightDistance = length(lightVector);

float attenuation = max((lightRadius - lightDistance) / lightDistance, 0.0);

float diffuseLight = clamp(dot(normal, normalize(lightVector)), 0.0, 1.0);

gl_FragColor = vec4((diffuseLight * diffuseColor) * attenuation * lightColor, 1.0);
//gl_FragColor = texture2D(normals, screenCoords);
}


Hier noch ein Bild der Positionen (position3d), durch 200 geteilt mit invertiertem (*= -1) z-Wert. Sieht soweit richtig aus. Das erste Bild ist von der Stelle, wo früher das Problem war, das zweite von obiger Stelle, mit dem aktuellen Problem...schaut aber okay aus...

http://img83.imageshack.us/img83/2313/posprobalt7wh.jpg

http://img69.imageshack.us/img69/3817/posprobneu9zv.jpg

Da werde ich dann wohl morgen auch mal alle einzelnen Schritte durchgehen und schaun, wo der Fehler diesmal herkommt...

Jedenfalls an dieser Stelle einmal vielen Dank für Deine Hilfe!!

Chris Lux
2006-03-17, 18:07:03
Hmm... eigentlich nicht... okay, Positionen und Normalen werden nun in Eye Space gespeichert... und siehe da... ES GEHT!!

Andererseits... die groben Fehler sind jetzt weg... an dieser Stelle gibt's allerdings ein kleines Problemchen im Vergleich zu Multipass (gibt noch ein paar andere Stellen, ebenfalls weniger auffällig als zuvor):
Ich scheine da also tatsächlich gegen irgendein Genauigkeits-Limit zu laufen. Nur welches? Und warum? Und wie kann ich das gänzlich lösen? Und was ist an Object-Space schlimmer als an Eye-Space?
es kann sein, dass im object space fp16 nicht ausgereicht hat, einfach durch zu große werte. das war meine vermutung. das zu verifizieren müsste man fp32 zum laufen bekommen. vielleicht mal in zwei drei tagen danach schauen, wenn sich die aufgestaute wut legt ;) (geht mir immer so bei solchen sachen)
Hier noch ein Bild der Positionen (position3d), durch 300 geteilt. Sieht soweit richtig aus, ich frage mich nur, warum links unten im Eck immer so ein schwarzes Quadrat ist -das ist da immer und bewegt sich mit der Kamerabewegung mit... hu?
unten links sind die werte negativ (x u y, z sowieso) und werden abgeschnitten.
Jedenfalls an dieser Stelle einmal vielen Dank für Deine Hilfe!!alles kein problem, interessiert mich selbst ;)

viel erfolg noch ;)

Expandable
2006-03-17, 18:11:29
Habe mein Post oben gerade editiert ;o)

Aber irgendwie glaube ich, dass die FBO-Extension noch sehr verbugt ist im aktuellen Treiber... FP32 geht gar nicht, wenn ich FP16 mit RGBA8 mische (zwei FOBs) kommt Schwachsinn raus.... Depthbuffer auslesen ging auch nicht... wobei das letzte auch meine Schuld gewesen sein kann ;) Jedenfalls sind die Werte in der Z-Buffer-Textur alle sehr, sehr nahe beieinander... zu funktionieren scheint's trotzdem irgendwie...

Nachtrag... okay, war wieder meine Dummheit... damit kann man sich z-Werte "sichtbar" machen:


vec3 float_to_color(in float f)
{
vec3 color;
f *= 256;
color.x = floor(f);
f = (f-color.x)*256;
color.y = floor(f);
color.z = f-color.y;
color.xy *= 0.00390625; // *= 1.0/256
return color;
}

Chris Lux
2006-03-18, 22:47:07
Habe mein Post oben gerade editiert ;o)

Aber irgendwie glaube ich, dass die FBO-Extension noch sehr verbugt ist im aktuellen Treiber... FP32 geht gar nicht, wenn ich FP16 mit RGBA8 mische (zwei FOBs) kommt Schwachsinn raus.... Depthbuffer auslesen ging auch nicht... wobei das letzte auch meine Schuld gewesen sein kann ;) Jedenfalls sind die Werte in der Z-Buffer-Textur alle sehr, sehr nahe beieinander... zu funktionieren scheint's trotzdem irgendwie...

dein aktuelles problem sieht danach aus, als wenn die vektoren für die lichtberechnung probleme machen in dieser situation (sichtpunkt sehr nahe an der lichtquelle zb), so kann zum beispiel der lightvector gleich der nullvektor sein usw. so entsteht das sicherlich. einfach mal die mathematik bemühen für diesen fall ;) sieht für mich jetzt nicht mehr wie ein fbo problem aus.

bei den fbos darauf achten, dass RGBA8 geclampte werte enrhält und fp16 und fp32 nicht diese limitierung haben. bei fp32 vor allem darauf achten, dass es zwar unterstützt wird, aber beispielsweise nur mit nearest neightbor filtering.

Nachtrag... okay, war wieder meine Dummheit... damit kann man sich z-Werte "sichtbar" machen:


vec3 float_to_color(in float f)
{
vec3 color;
f *= 256;
color.x = floor(f);
f = (f-color.x)*256;
color.y = floor(f);
color.z = f-color.y;
color.xy *= 0.00390625; // *= 1.0/256
return color;
}

z-werte sollten doch zwischen 0 und 1 liegen (nach der modelviewprojection multiplikation) also sollten einfach darstellbar sein.

Asmodeus
2006-03-20, 11:30:04
Habe mein Post oben gerade editiert ;o)

Aber irgendwie glaube ich, dass die FBO-Extension noch sehr verbugt ist im aktuellen Treiber... FP32 geht gar nicht, wenn ich FP16 mit RGBA8 mische (zwei FOBs) kommt Schwachsinn raus...


Momentan beobachte ich auch wieder ein etwas merkwürdiges Verhalten im Zusammenhang mit den FBOs. Eine meiner Applikationen rendert in einem Batchmodus mehrere hundert Texturen in FBOs. Diese Applikation habe ich zum einen auf einer 7800 GTX laufen lassen und zum anderen auf einer Quadro FX 4400. Auf der Quadro läuft der Batchmodus stundenlang ohne irgendwelche Probleme, mit gleichbleibender Geschwindigkeit. Auf der 7800 GTX läuft die Sache immer nur eine Weile gut, dann wird es extrem langsam und produziert irgendwann fehlerhafte Texturen. Sieht mir zumindest irgendwie auch nach einer Art Managementproblem im Treiber aus.

Gruss, Carsten.

Chris Lux
2006-03-20, 13:09:58
Momentan beobachte ich auch wieder ein etwas merkwürdiges Verhalten im Zusammenhang mit den FBOs. Eine meiner Applikationen rendert in einem Batchmodus mehrere hundert Texturen in FBOs. Diese Applikation habe ich zum einen auf einer 7800 GTX laufen lassen und zum anderen auf einer Quadro FX 4400. Auf der Quadro läuft der Batchmodus stundenlang ohne irgendwelche Probleme, mit gleichbleibender Geschwindigkeit. Auf der 7800 GTX läuft die Sache immer nur eine Weile gut, dann wird es extrem langsam und produziert irgendwann fehlerhafte Texturen. Sieht mir zumindest irgendwie auch nach einer Art Managementproblem im Treiber aus.
mit opengl an sich hat nvidia zuletzt so seine probleme. ich denke, es hängt mit der multicore optimierung zusammen. nachdem ich in der registry dieses deaktiviert habe liefen 99% aller sachen wieder wie erwartet. ich kann mir vorstellen, dass diese optimierung für die quadros default maßig ausgeschaltet sind.