Verwenden Sie einheitliche Puffer (dh konstante Puffer im D3D-Jargon).
Solange sich alle Ihre Shader auf das Layout und den Bindungspunkt jedes solchen Puffers einigen, wird das Aktualisieren zum Kinderspiel. Modelle müssen überhaupt nichts über Shader wissen. Sie müssen nur die Modellansichtsmatrix in ihrem konstanten Puffer aktualisieren, und die Rendering-Pipeline verwendet sie automatisch.
Zumindest würde ich argumentieren, dass Sie zwei solche Puffer haben sollten. Die erste sollte Ihre Projektionsmatrix, Kameramatrix, die verkettete Kamera-Projektionsmatrix, Ansichtsfensterinformationen, Frustrumdetails und Matrixumkehrungen speichern. Sie müssen diesen Puffer nur einmal pro Szene aktualisieren.
Geben Sie dann jedem Modell einen weiteren Puffer, um seine Modellansichtsmatrix, Normalmatrix, Inversen und Materialeigenschaften zu speichern. Dies wird für jedes Modell einmal aktualisiert und kann in einem anderen Aktualisierungsdurchlauf durchgeführt werden (falls zutreffend). Die Materialinformationen können / sollten in einen dritten materialspezifischen Puffer verschoben werden, wenn Sie die Möglichkeit haben, Materialien für mehrere Objekte freizugeben.
In einem Vorwärtsschattierungsaufbau ist es sinnvoll, alle Lichter in einen anderen Puffer zu legen, und in der verzögerten Schattierung ist es ebenfalls sinnvoll, einen Lichtpuffer für den Lichtdurchgang zu verwenden (anstelle eines Modell- / Materialpuffers, der in der Geometriepass).
Beachten Sie, dass Sie eine mäßig aktuelle Version von GL benötigen, um überhaupt einheitliche Puffer zu verwenden (3.1 oder eine Erweiterung; heute üblich genug, außer bei einigen älteren, aber noch in Betrieb befindlichen Laptops), und dass Sie eine relativ aktuelle Version benötigen Sie können einheitliche Puffer innerhalb des Shader-Codes an bestimmte Bindungsstellen binden (4.2; immer noch ungewöhnlich, aber immer besser). Andernfalls müssen Sie mehr Arbeit in Ihrem CPU-seitigen Code leisten, um die Einstellungen vorzunehmen (Ihr CPU-Code muss die richtige Bindung kennen Punkte sowieso, so ist es eher ein API-Geruch als ein ernstes Problem). OpenGL | ES hat bis 3.0 keine einheitlichen Puffer hinzugefügt, was auf den meisten gängigen mobilen Plattformen leider immer noch nicht unterstützt wird.
Wenn Puffer keine Option sind, benötigen Sie einen globalen Speicherort für Indexpositionen für den aktiven Shader. Sie können glGetUniformLocation
nach dem Laden Ihres Shaders die Indizes für bekannte Namen (wie ModelViewMatrix
oder ähnliche) suchen und diese Indizes speichern. Ihr Rendering kann Enum-Werte wie MODEL_VIEW
an eine SetUniform
Wrapper-Funktion übergeben zuordnen, um in den gebundenen Shader zu schauen, den Index zu finden und glUniform
ordnungsgemäß aufzurufen . Es ist keine besonders große Änderung in der Verwendung von Client-Code aufgrund von Puffern, außer dass jede Uniform einzeln festgelegt werden muss, wenn alles gut verpackt ist.
Siehe GLSL-Schnittstellenblöcke und einheitliche Pufferobjekte .