2017-12-05 3 views
2

Also ich möchte mehrere Lichtquellen in meiner Szene haben. Der Grundgedanke ist, einfach eine Anordnung einer (einheitlichen) Struktur zu haben, die alle Eigenschaften von Licht hat, die Sie interessieren, wie Positionen, Farbe, Richtung, Schnitt und w/e, die Sie wünschen. Mein Problem ist, wie man darstellt, welche Lichter an/aus sind? Ich werde alle Möglichkeiten auflisten, die mir einfallen. PlWie man den Status von Lichtquellen in OpenGL darstellt

  • Haben Sie eine einheitliche Int pro Lichtstruktur um anzuzeigen, ob es an/aus ist.
  • Lassen Sie die Anzahl der hellen Strukturen mit Vielfachen von 2, 3 oder 4 übereinstimmen, so dass ich so viele Bool-Vektoren verwenden kann, um ihren Status anzuzeigen. Zum Beispiel 16 Lichter = 4x4 bvec4.
  • Statt viele Flaggen und Zweig der Verwendung, geht immer durch jedes einzelnes Licht, sondern mit den aus Einsen auf (0,0,0,0) für die Farb

Ich bin auf den letzten Optionen lehne als es wird keine Verzweigung haben ... aber ich habe bereits gelesen, dass moderne Grafikkarten jetzt besser mit Verzweigungen umgehen.

Antwort

2

Keine Ihrer Ideen ist wirklich gut, weil alle von ihnen verlangen, dass der Shader auswertet, welche Lichtquellen aktiv sind und welche nicht. Sie sollten auch unterscheiden zwischen Szeneninformationen (welche Lichter in der Szene vorhanden sind) und Daten, die zum Rendern benötigt werden (welche Lichter leuchten und die Szene beleuchten). Szeneninformationen sollten nicht in einem Shader gespeichert werden, da dies unnötig ist und den Shader nur verlangsamt.

Eine bessere Möglichkeit, in einer Szene mehrere Lichtquellen Handhabung und machen nur mit den Aktiven könnte wie folgt aussehen:

In jedem Frame:

  • auf CPU-Seite auswerten, die Lichter an sind . Übergeben Sie nur die Lichter, die an den Shader Uniformen sind zusammen mit der Gesamtzahl der aktiven Lichter. In Pseudo-Code:

    Shader:

    uniform lightsources active_lightsources[MAX_LIGHTS]; 
    uniform int light_count; 
    

    CPU:

    i = 0 
    foreach (light in lightsources) 
    { 
        if (light.state == ON) 
        { 
         set_uniform("active_lightsources[i]", light); 
         i++ 
        } 
    } 
    set_uniform("light_count", i); 
    
  • Wenn ein Fragment Beleuchten Folgendes tun im Shader

    Shader:

    for (int i = 0; i < light_count; i++) 
    { 
        //Calculate illumination from active_lightsources[i] 
    } 
    

Der Hauptvorteil dieses Ansatzes besteht darin, dass Sie weniger Lichter im Shader speichern und dass die Schleife innerhalb des Shaders nur die für das aktuelle Bild relevanten Lichtquellen überstreicht. Die Auswertung, welche Lichter relevant sind, erfolgt einmal pro Frame in der CPU und nicht einmal pro Vertex/Fragment im Shader.

+0

Ich dachte, Sie können nicht über dynamische Variable im Shader Schleife und auch Verzweigung ist teuer? – ChaoSXDemon

+0

light_count ist keine dynamische Variable. Looping über Uniformen war bereits in Glsl 120 möglich. Selbst das Umfahren dynamischer Ausdrücke ist heute kein Problem mehr. Verzweigung kann teuer sein, aber nicht so viel für einheitliche Bedingungen. Aber es gibt keine Verzweigung im vorgeschlagenen GPU-Code, Verzweigungen treten im CPU-Code auf (und nur einmal in jedem Frame). – BDL

+0

Der allgemeine Hinweis lautet: Berechne niemals etwas in einem Shader, das vor dem Shader-Aufruf vorberechnet werden kann. – BDL

Verwandte Themen