Ich hab' mir jetzt nicht alles genau durchgelesen, aber zu den ganzen "projMap"-Texturen und den if-Abfragen: Wäre es möglich die Texturen in eine 3D-Textur zu packen, bzw. in ein TextureArray? Dann könnte man die Layer wie ein Array ansprechen. Allerdings wird bei ersterem zwischen den Texeln der unterschiedlichen Layer interpoliert oder man muss es manuell machen. Bei letzterem wird die "EXT_texture_array" benötigt, die deine Grafikkarte aber beherrschen sollte.
Ich hab' mir jetzt nicht alles genau durchgelesen, aber zu den ganzen "projMap"-Texturen und den if-Abfragen: Wäre es möglich die Texturen in eine 3D-Textur zu packen, bzw. in ein TextureArray? Dann könnte man die Layer wie ein Array ansprechen. Allerdings wird bei ersterem zwischen den Texeln der unterschiedlichen Layer interpoliert oder man muss es manuell machen. Bei letzterem wird die "EXT_texture_array" benötigt, die deine Grafikkarte aber beherrschen sollte.
Nun meine Grafikkarte vielleicht, aber die der Kunden vielleicht nicht..
nun ich kann die If-Abfragen aber nicht rausnehmen da ich keine Texturarrays nutzen kann.
Hast du wie hier im Thread irgendwo vorgeschlagen wurde mal versucht erst sämtliche Texturen auszulesen und die Ergebnisse in einem lokalen Array zu speichern? Auf alten Grafikkarten ist es möglich das eine if-Anweisung nur emuliert wird indem dem then und der else Zweig ausgewertet wird und am Ende das Ergebnis interpoliert wird. In dem Fall würdest du in jedem Schleifendurchlauf jede der Texturen abfragen...
Ich habe mal stark vereinfacht geschaut wie viele FPS ich bei 1024x800 bekomme (GeForce 8600M GT, recht ähnlich). Dabei habe ich die Faktoren für die Lichtberechnung fast komplett durch Konstanten ersetzt, nur ein einfaches Quad gezeichnet und auch die 9 sampler2d durch einen ersetzt, die ifs aber erhalten. Ich hatte dann so um die 8,8 ms/frame. Ohne die 8 ifs in der Schleife waren es 3,4 ms/frame. Noch weiter reduziert, so dass im Grunde nur die Ergebnisse 7 verschiedener Texturzugriffe aufsummiert werden geht es dann runter auf 2,2 ms/frame. Welche Tipps hast du bereits ausprobiert? Was war das Ergebnis? Zeichnest du viele Pixel über oder renderst du evtl. schon erst in den Depth-Buffer, dann in den Color-Buffer? Ist der Vertex-Shader stark mit Objekten beschäftigt die außerhalb des Blickfeldes liegen und verbaucht wertvolle Zeit für den Pixel-Shader? Wie verhält sich eine einfache Szenarie (z.B. nur ein Quad)? Warum kannst du keine Textur-Arrays verwenden und die if-Anweisungen auf die CPU verlagern?
Nun meine Grafikkarte vielleicht, aber die der Kunden vielleicht nicht..
Achso. Dann was ganz einfaches: Wie wäre es die Texturen in einem Texturatlas zusammenzufassen? Die verändern sich doch nicht (häufig) oder? Allerdings muss man dann darauf achten einen Rand um jede Textur zu lassen, wegen Mipmapping. Für den schlimmsten Fall müsste der Rand halb so breit sein wie die Textur selbst. Der Speicherverbrauch würde sich also vervierfachen.
du meinst das ich quasi mehrere Projektionstexturen auf eine zusammenfassen soll.. Ich weiss das wär genial, aber 1. weiss ich nicht wie ich die zusammenfügen könnte (jedenfalls nich mit OpenGL) 2. und ich weiß nich wie ich die im Shader wieder auseinander pflücke..
Nun die Texturen haben aktuell eine größe von nur 32x32 pixel, später maximal 128x128
Ich weiß nicht wie du deine Texturen lädst, aber für mich gesprochen verwende ich zum Beispiel libpng oder eine andere Grafikformatbibliothek und die geben mir die Zeilen des Bildes als Pointer. Auch eine Delphi-Bitmap verfügt über die Eigenschaft Scanline[]. Sofern die Grafikbibliothek Bildzeilen in RGB-Pixeln zurück kannst du diese ja direkt so in einen neuen Speicherblock kopieren, dass du eine Fotostrecke bekommst und den Speicherblock dann OpenGL als Textur übergeben. Dabei kannst du noch entscheiden, ob du das MipMapping abstellst und nur mit einem Rand von einem einzelnen schwarzen Pixel auskommst oder es an lässt und so vorgehst wie Schläfer es beschreibt. oder Im Shader verwendest du dann deinen GoboIndex, um das korrekte Bild auszuwählen. Das ist einfach x = x + GoboIndex[i] / Anzahl Bilder. So wird die x-Koordinate jeweils um 1/8 nach rechts verschoben. Vorher sind natürlich Korrekturen an deinen Texturkoordinaten nötig. Da auch in der Atlastextur die entgegengesetzten Ecken bei (0,0) bzw. (1,1) liegen würdest du momentan bloß eine gestauchte Version der ganzen Textur projezieren. Das Clamp-To-Border bringt hier für die x-Koordinate keinen Nutzen mehr, die Begrenzung musst du im Shader durchführen. Mit anderen Worten, du musst die x-Koordinate vor dem Texturzugriff auf den Bereich [0,0..1,0] begrenzen. Du verwendest texture2DProj(), dabei werden einfach x und y durch die letzte Komponente des Vektors geteilt. Auch das müssen wir manuell machen, um wirklich an die effektiven x- und y-Koordinaten zu kommen. Da deine Projektionskoordinaten in einem vec4 stecken ist die letze Komponente w: vec2 tc = projCoord[i].xy / projCoord[i].w; Damit die Texturkoordinaten nicht kleiner 0 oder größer 1 werden noch ein clamp(): vec2 tc = clamp(projCoord[i].xy / projCoord[i].w, 0.0f, 1.0f); Nun haben wir damit Clamp-To-Border und texture2DProj ersetzt. Was noch fehlt ist die Skalierung und Positionierung im Texturatlas. Jetzt nehme ich mal der Einfachheit halber an du verwendest die Variante mit 25% Rand an jeder Textur. Wie man sieht ist jede Textur halb so hoch wie der Atlas und ein sechzehntel so breit. Außerdem haben wir einen allgemeinen Versatz, der noch mal halb so groß ist wie eine einzelne Textur im Atlas und einen Versatz entsprechend des GoboIndex von einem Achtel. Ich verwende jetzt max_lights = 8 aus deinem Shader: tc = vec2((0.5 * tc.x + 0.25 + GoboIndex[i]) / max_lights, 0.5 * tc.y + 0.25); Jetzt hast du in tc die fertigen Koordinaten für die Atlastextur: ProjMapColor = texture2D(atlas, tc);
EDIT: Da fällt mir gerade noch was ein aus dem Prgramming Guide, den ich oben verlinkt habe. Wenn du komplexe Berechnungen durchführst, bei denen du eine Funktion func(x, y) herausarbeiten kannst und x und y begrenzt sind (z.B. zwischen 0 und 1) kannst du eine Textur verwenden und mittels texture2D(funcTex, x, y) die Werte besten Falls in einem Takt auslesen. Vielleicht würde so etwas deine Lichtberechnung noch beschleunigen. Gleichermaßen kann eine func(x, y, z) in einer 3D-Textur untergebracht werden, wenn du noch genug Speicherbandbreite für solche Klopper über hast.
Korrektur: Wenn du keine MipMaps brauchst macht es mehr Sinn direkt eine 3D-Textur zu verwenden, als einen zusätzlichen Pixelrand stehen zu lassen. Die perfekte Infoquelle ist natürlich wieder der Hardwarehersteller mit nützlichen Tools zur Erstellung und Visualisierung von Texturatlassen (atli?): Batching Via Texture Atlases Im PDF wird das Thema in Bezug auf die Vermeidung von State-Changes, genauer Texturwechsel, zur Beschleunigung des Renderns angesprochen.
Mitglieder in diesem Forum: 0 Mitglieder und 8 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.