Hallo miteinander, ich bastle an einem Shader, der im Vertexteil intensiven gebrauch von texture2D macht (Displacement mapping). Aber es ist soo langsam! Warum? Im Fragmentshader fetche ich über riesige Schleifen für Millionen Pixel und es kratzt die Grafikkarte nicht, warum ist der Textutefetch im VertexShader so viel langsamer? Gibt es eine Alternative? Oder Optimierungsmöglichkeiten?
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Kommt auf den Texturtyp an. Manche, besonders ältere Grafikkarten, unterstützen manche Texturtypen im Vertexshader so gut wie nicht. Z.B. ist auf meiner alten nVidia nur GL_RGBA32F performant gewesen – alles andere hat die Frameraten einbrechen lassen.
Der Grund … keine Ahnung. Wird wohl irgendeinen Pipeline-Abhängigen Grund geben.
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 network • my 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
Hab interessehalber mal ganz grob verglichen, und es kam raus, dass der Vertexshader über 10 mal langsamer bei texture2D ist als der Fragmentshader. Der Fragmentshader ist wohl auch dafür ausgelegt. Kennt jemand Alternativen oder Optimierungsmöglichkeiten?
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Vielleicht hilfts wenn du mal Typ + Treiberversion deiner Grafikkarte angibst (beides gut herauszubekommen mit diesem Tool, wo du auch gleich nen Report hochladen könntest). Gegebenenfalls mal explizit nach der Grafikkarte suchen und schauen, ob du irgendein Caveat übersehen hast.
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 network • my 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
Danke, werd ich ausprobieren. Meinst Du also, dass es nicht normal ist, dass der Fragmentshader schneller auf Texturen zugreifen kann als der Vertexshader?
grüße Vinz
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Hast du mal Mipmaps und lineare Filterung ausgemacht? Also GL_NEAREST für alle Achsen?
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 network • my 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
Hab es grad probiert, bringt immerhin ca. 20%, aber die Bildqualität leidet darunter. Hab jetzt aber gelesen, dass Vertexshader einfach nicht so für den Texturzugriff optimiert sind. Unter: ftp://download.nvidia.com/developer/Pap ... xtures.pdf heißt es: "Since vertex texture reads are much slower than constant reads (see previous section), we strongly advise against using vertex textures as constant memory. The pixel processing architecture in the GPU is highly optimized to hide texture fetch latency, but the vertex shader is not nearly as efficient. Therefore, you should limit your vertex texture fetches to a small number of coherent accesses per vertex."
Es wäre also wesentlich schneller, wenn man die displacemnt-maps als uniform array überegeben würde, aber so viel Platz steht dafür wohl nicht zu Verfügung, oder?
grüße Vinz
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Registriert: Mi Nov 30, 2011 21:41 Beiträge: 136 Wohnort: Bad Vilbel
Programmiersprache: Delphi 7
Guck dir vielleicht mal Uniform Buffer Objects an, die könnten dir in der Hinsicht helfen, wenn du das mit Uniforms lösen willst.
Idee: Du speicherst in diesem Uniform Buffer Object die Werte für das Displacement in ein Array (praktisch nur die Texture) und übergibts dann in jedem Frame zum Beispiel Offset und Scale für die Displacement Map noch dazu und berechnest dann die Texturkoordinaten selber.
Oder: Vorher auf dem Prozessor berechnen und nur relevante Daten übertragen, oder zwischenspeichern. Da ich nicht weis was du genau machst, weis ich nicht ob das für dich in Frage kommt, weil wenn das Displacement sich nicht verändert, könntest dus ja auch ganz vorberechnen.
Wegen dem Speicherplatz... hm... also GL_MAX_UNIFORM_BLOCK_SIZE ist bei den ältesten GraKa (die diese überhaupt unterstützen) 16384 (Bit oder Byte, weis selber nicht^^). Das würde gerademal für einen 32x32 Textur mit 8 Bit Farbtiefe reichen, wahrscheinlich also nicht für deine Zwecke. Vielleicht müsstest du dann die Textur auf mehrere Uniforms aufspalten (normalerweise werden mindestens 1024 uniforms supported also könntest du schon irgendwie eine 512x512 vielleicht sogar 1024x1024 speichern), also der Platz dürfte kein Problem sein, aber ob dir das nachher einen Performanceboost bringt, wage ich zu bezweifeln!
Danke für die Antworten, ich werde mir Uniform Buffer Objects mal genauer anschauen, klingt praktisch. Auf die Frage, was genau ich machen will: Eine Wasseroberfläche, die mit verschiedenen, H-maps mit dynamischen Texturkoordinaten erzeugt wird. Ich muss also für viele Vertices auf mehrere Werte zugreifen.
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Habe jetzt noch etwas mit uniforms rumprobiert, und bin zu dem Ergebnis gekommen, dass sie wenn überhaupt, nur unwesentlich schneller sind. Ich bleibe bei Texturfetch.
Grüße Vinz
_________________ "Pixel, ich bin dein Vater." -Darf Shader
Registriert: Mi Nov 30, 2011 21:41 Beiträge: 136 Wohnort: Bad Vilbel
Programmiersprache: Delphi 7
Kannst du mal deinen Vertexshadercode zeigen, vielleicht können wir dann nochmal gucken ob wir die helfen können.
(Du könntest vielleicht auch versuchen mit Hilfe von Octtree, etc. deine Wasserfläche zu unterteilen und somit weniger Vertices durch den Shader zu jagen)
P.S. Hab mir nochmal deinen Link durchgelesen und bin auf folgendes gestoßen: "Performance dramatically improved by using dynamic branching both in pixel and vertex shaders." Vielleicht hilft dir das ja nochmal weiter.
Mitglieder in diesem Forum: 0 Mitglieder und 3 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.