Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jun 21, 2025 09:06

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 34 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
BeitragVerfasst: Di Jul 31, 2012 17:51 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Ich habe das Gefühl das bei meiner Deferred Rendering implementierung was fehlt, denn sobald ich mehr als 5 Punkt-Lichtquellen habe, dann bricht die Framerate massiv ein. Ab 50 ist es eine Ruckel-orgie.

Also steh ich mal wieder vor dem Problem wie schon in meinem zig hunderten 3D Anwendungen bevor, das ich Licht nicht Performant rendern kann, egal wie hübsch es aussehen mag :(

Muss aber auch zugeben, es sind bisher null Optimierungen drinnen und ich mach das bisher alles straight-forward:

- GBuffer füllen mit bisher einem einzigen VBO Call (Sponza Mesh > 800k indices) (Position, Normal, Diffuse/Albedo)
- Akkumulieren von allen Licht-Quellen mit dem entsprechenden Point-Light oder Directional-Light Shader auf einem Fullscreen-Quad mit der Position -und Normaltexture vom GBuffer -> Das ergebnis in nen eigenes RGBA32F FBO Target gepackt. Licht-Eigenschaften wie Position/Radius/Farbe werden per Uniform an den Shader geschickt. Pro Licht ein Shaderwechsel was natürlich ansich schon unperformance ist, ich aber nicht denke das das mein Problem ist oder doch?

Was muss ich denn tun, damit ich Problemlos mehrere Lichtquellen Rendern kann?
Ich habe gelesen das man seine Lichtgeometrie beim Akkumulieren vom Licht Rendern soll, und mittels Frontface culling nicht sichtbare Lichter ausschliessen kann. Wenn ich das nach dem GBuffer pass machen würde, dann müsste ich ja irgendwie meinen Lichtgeometry-Vertex zu einer Texture-Koordinate umrechnen, was irgendwie keinen Sinn macht, denn die simple Licht-Geometry hat ja keine Texture-Koordinaten. Dann gibts noch ne möglichkeit das mit dem Stencil zu machen, aber damit habe ich noch nie was gemacht und verstehen tu ich das aktuell noch nicht.

Ich muss sagen, irgendwie bei dem Thema Optimierung stoß ich immer auf Probleme und Fragen, die ich selbst nach so vielen Jahren Programmiererfahrung nicht gelöst bekomme :(

Ich vermute stark das es einfacher ist, als ich denke... aber bisher ist mir noch keine Lösung dazu eingefallen.
Bitte erlöst mich jemand vom meinem Unwissen/Halbwissen.

Ich habe mal den code hochgeladen: http://pastebin.com/b90wrei8

Hier ist noch auch noch ne Binary (Win32 only): http://xenorate.com/tl_files/somekram/rps_deferred.zip
In dieser Binary habe ich 50 Punkt-Lichter definiert, also nicht wundern wenn ihr ne ruckel-orgie habt.
Mit Space könnt ihr das aktuelle Rendertarget das angezeigt werden soll umschalten.
Achja, nicht wundern, das als Albedo/Diffuse die Normalen angezeigt wird, das ist aktuell so gewollt, siehe Shader GBuffer_color.frag.
Habe weder Farben und Texturen für das Mesh definiert... das ist eh erstmal alles nur test...

Danke,
Final


Zuletzt geändert von Finalspace am So Aug 05, 2012 11:35, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 01, 2012 10:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Finalspace hat geschrieben:
Wenn ich das nach dem GBuffer pass machen würde, dann müsste ich ja irgendwie meinen Lichtgeometry-Vertex zu einer Texture-Koordinate umrechnen, was irgendwie keinen Sinn macht, denn die simple Licht-Geometry hat ja keine Texture-Koordinaten.

Die bekommst du aus den Fragmentkoordinaten. Wenn du da die Projektion auf den Schirm durchgeführt hast, _sind_ das deine Texturkoordinaten. Der GBuffer ist ja auch screenspace.

Ich würde als nächsten Schritt mehrere Lichter in einem Pass zusammenfassen, da du vermutlich an Füllratenlimits stößt… Aber das ist nur eine Vermutung.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 01, 2012 11:16 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Lord Horazont hat geschrieben:
Finalspace hat geschrieben:
Wenn ich das nach dem GBuffer pass machen würde, dann müsste ich ja irgendwie meinen Lichtgeometry-Vertex zu einer Texture-Koordinate umrechnen, was irgendwie keinen Sinn macht, denn die simple Licht-Geometry hat ja keine Texture-Koordinaten.

Die bekommst du aus den Fragmentkoordinaten. Wenn du da die Projektion auf den Schirm durchgeführt hast, _sind_ das deine Texturkoordinaten. Der GBuffer ist ja auch screenspace.

Ich würde als nächsten Schritt mehrere Lichter in einem Pass zusammenfassen, da du vermutlich an Füllratenlimits stößt… Aber das ist nur eine Vermutung.

grüße


Ach ist gl_FragCoord die aktuelle Texture-Koordinate für das viewport das im bereich 0-1 liegt? Wusste ich nicht, hab mich schon eh immer gefragt wofür das verwendet wird. Das erklärt einiges :)

Ok, wenn das so ist, dann könnte ich ja tatsächlich an die Texcoords kommen, das wäre ja super und über das Frustum Culling könnte ich schon von vorne rein entscheiden, ob das Licht im Frustum liegt oder nicht, oder soll man das im Shader prüfen?

Das mit den Multi-Passes hatte ich eh vor, aber wenn ich die Licht-Geometry rendere um das frontface cullng zu nutzen, dann müsste ich ja bei multipass bleiben :(

*Edit: Grad nachgelesen, FragCoord liefert die Screen-Koordinaten vom Viewport zurück, muss man also per Uniform die Viewport-Größe mitgeben.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 01, 2012 21:03 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Man kann auch gl_FragCoord direkt benutzen, wenn man texelFetch2D statt texture2D im Shader verwendet. Benötigt allerdings die GL_EXT_gpu_shader4.

Eine andere Optimierung wäre die Verwendung von glScissor um den Bereich einzuschränken, wenn das Licht nicht den gesamten Bildschirm füllen kann. Also für Punktlichter könnte man eine Boundingsphere um das Licht konstruieren, wenn das Licht nicht bis ins unendliche reicht. Für das normale OpenGL Licht wäre das zwar der Fall, aber irgendwann ist die Helligkeit so niedrig das es keine Rolle mehr spielt. Oder man denkt sich eine eigene Formel aus bei der die Helligkeit garantiert ab einer gewissen Distanz Null wird, um auf Nummer sicher zu gehen.

Außerdem gibt es noch eine Möglichkeit mit glDepthBoundsEXT für Lichter und Schattenvolumen. Dabei wird die bereits im Depthbuffer vorhandene Tiefe verwendet um zu entscheiden ob ein folgender Pixel berechnet werden soll oder nicht. Weil ein Licht im weiter Entfernung eine Fläche im Vordergrund nicht mehr beleuchten kann, wenn die Distanz zu groß ist, kann man sich damit die Berechnungen im Fragmentshader sparen. Umgedreht für ein Licht im Vordergrund gilt das natürlich auch. Das ist so ähnlich wie wenn man mit dem Stenciltest und der Boundingsphere die Pixel markiert, die berechnet werden sollen, und funktioniert deshalb auch nur für "endliche" Lichtquellen.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 01, 2012 23:03 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Zur Zeit zeichne ich sowohl für Punkt- als auch Spotlights einfach eine Boundingbox, also einen Würfel mit Frontface-Culling und deaktiviertem Tiefentest. Direktionales Licht wird in ein Fullscreen-Quad gezeichnet. Zugegeben bei einem Spotlight, dass nur einen sehr kleinen Kegel beleuchtet wird sehr viel Füllrate verbraten.
Im Shader kommen noch mehrerer discard zum Einsatz bei Überschreitet des Radius oder wenn der Pixel nicht in im Kegel des Spotlight liegt.

Es gibt zu jeder Lichtart einen Shader. Die Lichter werden nach Shader sortiert gezeichnet.

Es kommt natürlich ab und zu (je nach Position in der Szene) vor, dass aus den Boundingboxen quasi Fullscreen-Quads werden.

Insgesamt kann ich aber locker einige Dutzend (50-70) Lichter rendern ohne großartige Performanceverluste zu haben. Ich verteile lieber mehrere kleine Lichter, als einen Bereich mit nur einem Licht zu beleuchten. So hat man auch eine Art Ambient-Occlusion quasi gratis.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 02, 2012 06:58 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Vielen Dank für die Tips.

Ich denke ich habe nun eine gute Vorstellung, was ich alles machen kann und ich verstehe nun auch, warum die ganzen Lichtquellen nicht wirklich Performant laufen. Da ich ja bisher für jedes Licht ein Fullscreen Quad für den jeweiligen Licht-Shader rendere ob Sichtbar oder nicht, werden natürlich auch Pixel berechnet die gar nicht sichtbar sind. bzw. Fragmente werden halt nicht beleuchtet, bzw. mit Schwarz beleuchtet. Das geht natürlich auf die Fillrate.

Was ich nun tun werde, ist erstens mal für jedes Licht, Geometry Rendern - Spheres für Punkt-Lichter, Cones für Spots und Culle diese mit simplem Frustum-Culling.

Danach werde ich den Light-Accumulation-Buffer nicht mehr mit Fullscreen Quads Rendern, sondern mit der entsprechenden Licht-Geometry. Dadurch werden ja nur noch Fragmente beleuchtet, bei der auch wirklich die Geometrie sichtbar ist.

Der nächste Schritt wird aber etwas aufwendiger, denn ich will ja Transparente Objekte Deferred Rendern, inkl. Licht, ohne das ich einen seperaten Forward Rendering Pipeline brauche. Habe da auch dazu nen guten Artikel gefunden: http://www.john-chapman.net/content.php?id=13
Allerdings muss ich erstmal mit Stencil-Buffern rumspielen, damit ich ungefähr verstehe wie diese Funktionieren damit ich das überhaupt implementieren kann.

Mal schauen wann ich Zeit habe, da weiter zu machen, aktuell eher wenig... denn wir versuchen aktuell unsere Tochter an das Töpfchen zu gewöhnen.
Das ist leider net so einfach wie man denkt ^_^


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 02, 2012 21:04 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Habe nun das ganze mal geändert wie ich geschrieben habe, also Lichtgeometrie rendern anstatt nen Fullscreen Quad und mit FragCoord die Texture-Koordinaten errechnen, bei aktiviertem back face culling und tiefentest. Funktioniert, ist auch deutlich flotter aber die Licht-Geometry wird zu schnell gecullt. Die Lichter schalten sich je nach Kamera-Position an/aus, was nicht so gut ist...

Das culling passiert genau dann, wenn man mit der Kamera in einem Punkt-Licht ist, dieses ist dann schon gecullt.

Wie kann man das denn lösen, jemand ne idee?

Anwendung habe ich aktuallisiert und hochgeladen. Könnt es direkt mal ausprobieren.

Gruß,
Final


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 02, 2012 22:30 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Kann es sein das es am "back face culling" liegt, was eigentlich Frontface-Culling sein müsste, weil man sonst wenn man in der Kugel mit der Kamera ist, diese nicht mehr sehen kann?
Also innerhalb der Kugel (oder des Volumens allgemein) muss man Frontface-Culling ohne Tiefentest verwenden und außerhalb kann man Backfaceculling mit aktiviertem Tiefentest verwenden, dann spart man sich noch ein paar Pixel die eventuell durch den Vordergrund verdeckt werden.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 03, 2012 07:15 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Schläfer hat geschrieben:
Kann es sein das es am "back face culling" liegt, was eigentlich Frontface-Culling sein müsste, weil man sonst wenn man in der Kugel mit der Kamera ist, diese nicht mehr sehen kann?
Also innerhalb der Kugel (oder des Volumens allgemein) muss man Frontface-Culling ohne Tiefentest verwenden und außerhalb kann man Backfaceculling mit aktiviertem Tiefentest verwenden, dann spart man sich noch ein paar Pixel die eventuell durch den Vordergrund verdeckt werden.


Also muss ich per Code entscheiden, ob ich mich in einem Licht-Volumen befinde, wenn ja dann mach ich Frontface-Culling, ansonsten Backface-Culling? Hmmm, das sollte funktionieren.

Danke für den Tip.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 03, 2012 10:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Mach einfach immer Front-Face-Culling, da geht nix schief ;)

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 03, 2012 18:22 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Lord Horazont hat geschrieben:
Mach einfach immer Front-Face-Culling, da geht nix schief ;)

grüße


Jauuu, das hat einwandfrei funktioniert, allerdings nur richtig sobald ich den Tiefentest ausschalte und das schreiben in die Tiefenmaske.
Das hat richtig performance gebracht. Nun kommt gleich noch frustum culling dazu, dann passt das soweit.

Dann kann ich mich endlich an den Stencil Buffer und FBO wagen ^^


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Aug 04, 2012 09:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Japp, Tiefentest brauchst du ja auch nicht (der ist sogar Kontraproduktiv) und in den Tiefenpuffer schreiben willst du noch viel weniger. Sonst zerstörst du ja die Informationen aus der Szene.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 05, 2012 11:56 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Ich habe da noch ein Problem mit der Beleuchtung von meinem Deferred Rendering Programm.
Der Light-Accumulation-Buffer wird zwar sauber erzeugt, aber in dem Finalen Pass wenn ich diesen dann mit der Albedo Texture multipliziere, kommen falsche Licht-Pixel raus, bzw. die Lichtfarbe ist immer identisch mit der des Albedo Materials, außer das Albedo Material ist weiß.

Da stimmt was nicht und hätte gern ein paar Tips wie denn eine Korrekte Beleuchtung auszusehen hat.

Alle Beispiele mit GLSL beziehen sich immer auf diese OpenGL Licht-Informationen gl_FrontMaterial/gl_LightSource/gl_LightModel die ich aber nicht habe und auch nicht nutzen will, sondern erstmal verstehen will, wie setzt sich korrektes Per-Pixel-Licht zusammen.

Aktuell mach ich es auf jedenfall falsch, denn so sieht das aus:

lightColor wäre z.b. (1.0, 0.0, 0.0, 1.0).
Light-Accumulation-Pixel = (vec4(lightColor.xyz, 1.0) * (diffuse + specular) * attenuation) * lightColor.w;
Wenn ich den Licht-Alpha wert nicht dazu multipliziere, dann stimmt es überhaupt nicht und alles ist irgendwie zu hell.

Und den Finalen Pixel berechne ich dann so = texture2D(albedoTex, texcoord) * lightColor; (lightColor = Fragment vom Light Accumulation Buffer)

Alles falsch irgendwie... vor allem habe ich noch kein Ambient Lighting welches ich eigentlich auch noch einbauen wollte.

Hmm, da stellt sich für mich die Frage: Enthält den der Light-Accumulation nur die Licht-Intensität+Licht-Farbe oder Albedo * Licht-Inensität+Licht-Farbe ???

Hier ist mal nen Bild:
http://xenorate.com/tl_files/somekram/deferred%20rendering%20lights+albedo%20wrong.jpg

Links-Oben = Normals in 0 - 1
Rechts-Oben = Albedo (Habe aktuell noch keine Texturen verwendet, daher wollte ich es erst mit normalen farben machen)
Links-Unten = Light-Accumulation-Buffer
Rechts-Unten = Finales Bild (Falsch)


Hier sind die zwei shader:
Point Light:
Code:
  1.  
  2. uniform sampler2D normalTex;
  3. uniform sampler2D positionTex;
  4. uniform sampler2D diffuseTex;
  5. uniform vec4 lightColor;
  6. uniform float shininess;
  7. uniform vec3 lightPos;
  8. uniform float lightRadius;
  9. uniform float lightFalloff;
  10. uniform vec2 invViewport;
  11.  
  12. const int MATERIALFLAG_NOLIGHT = 1;
  13.  
  14. // Decodes normal from 0_1 to -1_1
  15. vec3 decodeNormal(vec3 n) {
  16.     return vec3((2.0 * n) - 1.0);
  17. }
  18.  
  19. void main (void)
  20. {
  21.     vec2 texcoord = vec2(gl_FragCoord.x * invViewport.x, gl_FragCoord.y * invViewport.y);
  22.     vec4 pos = texture2D(positionTex, texcoord);
  23.    
  24.     // Skip no lighting fragments
  25.     int materialValue = int(pos.w);
  26.     if ((materialValue & MATERIALFLAG_NOLIGHT) == MATERIALFLAG_NOLIGHT) {
  27.         discard;
  28.     }
  29.  
  30.     // Skip non-geometry fragments
  31.     vec3 vertex = pos.xyz;
  32.     if (vertex.x < -9999.0) {
  33.         discard;
  34.     }
  35.  
  36.     vec3 normal = decodeNormal(texture2D(normalTex, texcoord).xyz);
  37.     vec3 lightDir = lightPos - pos.xyz;
  38.     float distance = length(lightDir);
  39.     float attenuation = clamp(1.0 - distance / lightRadius, 0.0, 1.0);
  40.    
  41.     float diffuse = dot(lightDir / distance, normal);
  42.     float specular = 0.0;
  43.     if (diffuse > 0.0 && shininess > 0.0) {
  44.         vec3 posEye = -pos.xyz;
  45.         vec3 viewEye = normalize(-posEye);
  46.         vec3 halfVec = normalize(lightDir + viewEye);
  47.         specular = pow(max(0.0, dot(normal, halfVec)), shininess);
  48.     }
  49.     gl_FragData[3] = (vec4(lightColor.xyz, 1.0) * (diffuse + specular) * attenuation) * lightColor.w;
  50. }
  51.  


und der deferred renderer shader, der also den Light-Accumulation-Buffer mit dem albedo Multipliziert.

Code:
  1.  
  2. uniform sampler2D lightTex;
  3. uniform sampler2D diffuseTex;
  4. uniform sampler2D positionTex;
  5. varying vec2 texcoord;
  6.  
  7. const int MATERIALFLAG_NOLIGHT = 1;
  8.  
  9. void main() {
  10.     int materialValue = int(texture2D(positionTex, texcoord).w);
  11.     vec4 lightColor = vec4(0.0);
  12.     if ((materialValue & MATERIALFLAG_NOLIGHT) != MATERIALFLAG_NOLIGHT) {
  13.         lightColor = texture2D(lightTex, texcoord);
  14.     }
  15.     gl_FragColor = texture2D(diffuseTex, texcoord) * lightColor;
  16. }
  17.  


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 05, 2012 21:46 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Also ich habe nochmal rumprobiert aber habe es immer noch nicht hingekriegt :-(
Ambient-Lighting habe ich noch hinzufügen können, das war ne änderung im finalen shader:

Code:
  1. gl_FragColor = (diffuseColor * ambientColor) + (diffuseColor * lightColor);


Aber, der eigentliche Point-Light Shader der funktioniert für sich alleine irgendwie schon, aber in verbindung mit meinem finalem Shader leider nicht richtig :(

Ich habe mal versucht alles auseinander zunehmen und jeden einzelnen Part zu kommentieren, komme aber auf keinem grünen zweig.

Code:
  1. uniform sampler2D normalTex;
  2. uniform sampler2D positionTex;
  3. uniform sampler2D diffuseTex;
  4. uniform vec4 lightColor;
  5. uniform float shininess;
  6. uniform vec3 lightPos;
  7. uniform float lightRadius;
  8. uniform float lightFalloff;
  9. uniform vec2 invViewport;
  10.  
  11. const int MATERIALFLAG_NOLIGHT = 1;
  12.  
  13. // Konvertiert einen 0.0 - 1.0 vector in form -1.0 - 1.0
  14. vec3 decodeNormal(vec3 n) {
  15.     return vec3((2.0 * n) - 1.0);
  16. }
  17.  
  18. void main (void)
  19. {
  20.         // Berechne aktuelle texture koordinate
  21.     vec2 texcoord = vec2(gl_FragCoord.x * invViewport.x, gl_FragCoord.y * invViewport.y);
  22.  
  23.         // Lese aktuelle position aus (XYZ = World-Model-View-Position, W = Materialwert)
  24.     vec4 pos = texture2D(positionTex, texcoord);
  25.    
  26.     // Überspringe fragmente die nicht beleuchtet werden sollen
  27.     int materialValue = int(pos.w);
  28.     if ((materialValue & MATERIALFLAG_NOLIGHT) == MATERIALFLAG_NOLIGHT) {
  29.         discard;
  30.     }
  31.  
  32.     // Überspringe fragmente die überhaupt keine Geometry enthalten, also bei denen die Hintergrund-Farbe Rot -10000.0 ist.
  33.         // Wird im GBuffer pass gesetzt.
  34.     vec3 vertex = pos.xyz;
  35.     if (vertex.x < -9999.0) {
  36.         discard;
  37.     }
  38.  
  39.         // Hole aktuelle Normale und bringe diese in die richtige Form (Decode und Encode soll in der finalen version raus!)
  40.     vec3 normal = decodeNormal(texture2D(normalTex, texcoord).xyz);
  41.  
  42.         // Light vector = Light Position im World Space - Vertex Position im World Space
  43.     vec3 lightDir = lightPos - pos.xyz;
  44.  
  45.         // Berechne Distanz und Abschwäschung auf basis des Licht-Radius
  46.     float distance = length(lightDir);
  47.     float attenuation = clamp(1.0 - distance / lightRadius, 0.0, 1.0);
  48.  
  49.         // Berechne lambert-term N dot L, wobei L hier normalisiert wird.  
  50.     float diffuse = dot(normal, lightDir / distance);
  51.  
  52.         // Berechne Spekular-Faktor, sofern wir wirklich ein beleuchtetes Fragment haben
  53.     float specular = 0.0;
  54.     if (diffuse > 0.0) {
  55.                 // Augen position im View Space = Invertierte Vertex Position normalisiert
  56.         vec3 viewEye = normalize(-pos.xyz);
  57.  
  58.                 // Halben vector berechnen???
  59.         vec3 halfVec = normalize(lightDir + viewEye);
  60.  
  61.                 // Spekular faktor berechnen
  62.         specular = pow(max(0.0, dot(normal, halfVec)), shininess);
  63.     }
  64.  
  65.         // Finale Licht-Intensitätsfarbe und Stärke für dieses Licht (Multi-Pass blend(GL_ONE, GL_ONE));
  66.     gl_FragData[3] = (vec4(lightColor.xyz, 1.0) * (diffuse + specular) * attenuation) * lightColor.w;
  67. }


Habe die aktuelle Application mal hochgeladen mitsamt den Shadern.
Bitte probiert diese mal aus und schaut es euch mal live an.

Ob das ganze auf nicht NVIDIA-Karten läuft, kann ich nicht sagen, grad keine möglichkeit was anderes zu testen.

Es wäre wirklich super, wenn ihr mir da weiterhelfen könntet.

Ich habe schon echt viel versucht, vor allem wenn ich das Multiplizieren mit lightColor.w weglasse, welches effektiv immer 1.0 ist, dann stimmt nichts mehr. Wenn ich aber lightColor.w durch 1.0 ersetzte, dann spinnt alles :(

Hier der download-link: http://xenorate.com/tl_files/somekram/rps_deferred2.zip

Achja, bitte wundert euch nicht wieso die Albedo-Farbe/Diffuse die normale ist, das ist aktuell absicht, da ich erstmal mit normalen Farben testen wollte und die normalen sind ja ganz gut zum testen. Später soll das ja durch die jeweilige Texture ersetzt werden.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 05, 2012 22:13 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
setz gl_FragData[3].w explizit auf 1.0

bzw: wrappe alles in ein vec4:

Code:
  1. gl_FragData[3] = vec4(lightColor.xyz * (diffuse + specular) * attenuation, 1.0);


die Normale wird ja von 0..1 zu -1..1 konvertiert. Musst du die evtl noch normalisieren?

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 34 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.017s | 18 Queries | GZIP : On ]