var: WebGL - Default-Einstellungen und Shader-Programme

Beitrag lesen

Hallo miteinander!

Ich arbeite nun schon seit einiger Zeit an einem Framework für WebGL, und mein größtes Problem ist dabei im Moment, dass ich mich nicht recht entscheiden kann, wie ich am sinnvollsten die Default-Einstellungen festlegen soll für die Knoten meines Szenengraphen, beziehungsweise, welche Voreinstellungen ich hinsichtlich der Generierung der zugehörigen Shader-Programme idealerweise treffen sollte.

Also, für diejenigen, die mit der Funktionsweise von WebGL beziehungsweise der Grafikprogrammierung im Allgemeinen nicht so vertraut sind, hier mal eine kurze Zusammenfassung, worum es geht:

Auf die WebGL-Schnittstelle wird mittels JavaScript zugegriffen, aber die Shader-Programme, welche an die GPU übermittelt werden, sind in GLSL zu schreiben.

Nun mal angenommen, man wollte nur eine einzelne Szene rendern, dann würde man den für diesen konkreten Anwendungsfall erforderlichen GLSL-Code einfach innerhalb des HTML-Dokumentes in ein <script>-Element schreiben, selbiges mit irgendeinem Fantasienamen als Typenbezeichnung ausstatten, damit es vom Browser beim parsen ignoriert wird, und das Script dann mittels JavaScript manuell auslesen, um es dann an die WebGL-Schnittstelle weiterzureichen.

Da die Shader-Programme jedoch zu dem Teil der Grafik-Pipeline gehören, den ich durch mein Framework zu abstrahieren versuche, generiere ich die Vertex- und Fragmentshader direkt in JavaScript, wobei es im Prinzip zwei mögliche Herangehensweisen gibt:

Entweder man erstellt ein ellenlanges Shader-Programm, welches alle Eventualitäten abdeckt, das also beispielsweise sowohl Farbe als auch Textur verarbeitet und auch alle möglichen Wünsche hinsichtlich der Beleuchtung der Szene berücksichtigt - was aber natürlich extrem unperformant wäre, oder - wofür ich mich entschieden habe - man erstellt die Shader-Programme je nach tatsächlichem Bedarf, - womit wir bei den Knoten meines Szenengraphen wären!

Bei diesen Knoten handelt es sich um Funktions-Objekte und sie sind gewissermaßen die elementaren Bausteine, aus denen sich die 3D-Szene zusammensetzt, ähnlich den DOM-Elementen, und so wie man über die style-Eigenschaft die entsprechenden Element-Attribute ändern kann, kann man für jeden Knoten festlegen, ob und wenn ja welches 3D-Objekt gezeichnet werden soll, ob Farbe oder Textur verwendet werden soll, Transparenz, Beleuchtung, Animation, usw.

Auf diese Art erhält jeder Knoten ein eigenes Eigenschaftenprofil, welches dann die Grundlage für die Parameter liefert, nach denen das vom Knoten-Objekt verwendete Shader-Programm erstellt wird (wobei Code-intern natürlich erst einmal geprüft wird, ob nicht bereits ein entsprechend passendes Shader-Programm verfügbar ist, dass vom Knoten genutzt werden kann).

Mein Problem ist nun, dass ich mir nicht sicher bin, was aus Usability- und auch aus Performance-Sicht die beste Herangehensweise ist, um dem Umstand zu begegnen, dass sich das Anforderungsprofil an die Shader in einer animierten Szene durchaus verändern kann.

Denn auch hier gibt es ja wieder die zwei Möglichkeiten: Entweder ich verlange, dass bei der Erstellung beziehungsweise Initialisierung des Knotens das Eigenschaftsprofil in Vorhersehung der weiteren Verwendung des Objektes vollständig angegeben und das Shader-Programm dementsprechend zum Beispiel unter Verwendung boolescher Variablen generiert wird, oder aber ich erlaube auch die nachträgliche Veränderung von Objekteigenschaften, - was dann aber natürlich die erneute Erstellung eines Shader-Programms erfordern würde - bei entsprechender Anzahl an nodes und bei 60fps unter Umständen nicht gerade die performanteste Lösung, aber im Vergleich eben deutlich intuitiver in der Handhabung...

Wie löse ich dieses Dilemma also auf?

Ich tendiere dazu, eventuelle Performance-Einbußen in Kauf zu nehmen und die Frage nach der Initialisierung des Knotens beziehungsweise des Zeitpunkts und der Bedingungen der Erstellung der Shader von der Benutzerschnittstelle einfach komplett auszunehmen, - aber sicher bin ich mir dabei nicht!

Andererseits könnte man als Kompromiss vielleicht zwar davon absehen, die Initialisierung der Knoten beziehungsweise der Shader zu formalisieren, jedoch trotzdem die Möglichkeit einräumen, bereits bei der Erstellung der Knoten auch prinzipiell einander ausschließende Einstellungen wie etwa Farbe/Textur oder Licht/kein Licht zuzulassen und über boolesche Variablen entsprechende Schalter einzubauen...

Wozu würdet ihr mir raten?

Gruß,

var