Diskussion:GLSL noise
Kann noch jemand den Unterschied zwischen Rauschen und Zufallszahlen beschreiben. --Flash 21:11, 10. Aug. 2008 (UTC)
Shader Model 4.0
Man könnte noch erwähnen, dass man mit ShaderModel 4.0 auch beliebig viele vernünftige Pseudozufallszahlen direkt im Shader erzeugen kann. Also als Alternative bzw. Verbesserung der Zufallstextur.
Man benötigt mindestens die Extensions GL_EXT_gpu_shader4 und GL_EXT_texture_integer. Diese stellen Integer-Arithmetik im Shader bereit und man kann sich ganz leicht einen lineareren Kongruenzgenerator bauen. Die Pseudozufallszahlen in C/C++/Delphi werden übrigens auf die gleiche Weise erzeugt. Im wesentlichen braucht man nur eine Multiplikation, eine Addition und einmal Modulo um von einer Zufallszahl zur nächsten zu kommen:
s := (a * s + c) mod m
Wählt man gute Werte für a, c und m erhält man mit diesen Operationen halbwegs gleich verteilte Pseudozufallszahlen. Die so erzeugten Zahlen sind natürlich deterministisch. Verwendet man also den gleichen Ausgangswert s, erhält man immer die gleiche Zahlenfolge. Folglich benötigt man auch hier eine Textur mit zufälligen Ausgangswerten für jeden Vertex (bzw. Pixel) den man rendert. Allerdings kann man sich aus diesem einen Wert beliebig viele weitere Zahlen erzeugen, also beispielsweise je eine für die XYZ-Achse.
Ich verwende hier einen Texturbuffer (GL_EXT_texture_buffer_object). In jedem Frame werden die vom Shader aktualisierten Seed-Werte via Transform-Feedback wieder in diese Textur geschrieben. Die CPU muss die Textur also nicht in jedem Frame neu initialisieren. Funktioniert so aber natürlich nur im Vertexshader bzw. Geometryshader. Bei dieser Methode wird die Extension GL_NV_transform_feedback oder GL_EXT_transform_feedback benötigt. Mit klassischen Framebufferobjects kann man sich aber sicher auch was basteln.
Hier ein Beispiel für den Vertexshader:
uniform usamplerBuffer tboSeed; varying unsigned int seed; // wird vom Transform-Feedback abgegriffen float random() { seed = (seed * 1103515245u + 12345u); return float(seed) / 4294967296.0; } void main() { seed = texelFetchBuffer(tboSeed, gl_VertexID).x; // ... float randomNumber = random(); // ... }
--Coolcat 16:36, 31. Jan. 2009 (UTC)
Danke coolcat für den Hinweis. Könntest du deinen Text unter der Überschrift "Workaround" in den Artikel einfügen? Falls du noch ein paar Infos zu deinem Ansatz hast z.B. gute Zahlen für den Seed etc. dann kannst du das gerne noch einbauen. (Den Konjunktiv (Man könnte noch schreiben...) kannst du dann auch wegmachen. ;) ) --Flash 21:48, 31. Jan. 2009 (UTC)
- Done. --Coolcat 11:26, 1. Feb. 2009 (UTC)