Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

12.11.2015, 15:36

FFT in Shader

Hallo,
ich bin auf der Suche nach einer Implementierung der Fast Fourier Transformation in einem Shader.
Leider habe ich durch meine Projektumgebung die Einschränkung, dass ein Compute Shader nicht verwendet werden kann, aber nach eigenen Recherchen sollte sich das Problem auch über Texturen im Fragment Shader lösen lassen.
Nun habe ich schon einige Beispiele gefunden, die aber fest in einer OpenGl Umgebung verwurzelt sind, da mein Projekt aber in x3d laufen muss, fällt eine Portierung schwierig.
Cuda und OpenCl implementiert über ein Java Script wäre eine andere Möglichkeit, besser wäre es aber, wenn ich die FFT direkt im Shader bewältigen könnte.
Hat damit schon einer Erfahrungen gesammelt? Gibt es vielleciht ein gutes Beispiel, welches nicht auf OpenGl basiert?

Gruß, Flo

2

12.11.2015, 18:00

Was ist denn dein Ziel, willst du eine parallele (schnelle) FFT durchführen, oder willst du das ganze im Rahmen eines Spieles für Grafikeffekte nutzen?

3

13.11.2015, 09:09

Ich möchte das ganze im Rahmen einer grafischen Simulation nutzen, Shader werden also bereits verwendet.
Es würde daher den Overhead erheblich reduzieren, wenn ich nicht noch extra Cuda oder ähnliches einbinden müsste.

Die Umgebung der des Programms sieht so aus:
Darstellung über die beschreibende Sprache x3d (leider Vorgabe),
Shader werden in der x3d Umgebung aufgerufen, Vertex-, Geometry- und Fragmentshader sind möglich, als Sprache kann glsl, cg und hlsl genutz werden.
Alle weiteren Berechnungen müssen über Script, also Javascript oder Java-Klasse implementiert werden.

Im Moment benutze ich JTransform als Java Klasse, also eine reine CPU basierte Lösung.
Die erstellte FFT wird nicht mehr verändert, sondern direkt als Texture an meinen Vertex Shader übergeben, falls das irgendwie helfen sollte.

Falls das ganze im Shader nicht so einfach möglich ist, bin ich für alle anderen Lösungsansätze natürlich auch sehr dankbar! :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

13.11.2015, 09:27

Was für Daten sind das genau, von denen du da die FFT berechnen willst und was genau machst du mit der FFT danach?

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

5

13.11.2015, 10:20

Klar, das geht im Fragment-Shader. Krishty drüben im ZFX hat das gemacht, um einen sehr geilen Menschliche-Augen-Effekt hinzubekommen. Anstatt einem Speicherzugriff machst Du halt ein tex2Dlod() mit Point-Filter.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

6

13.11.2015, 15:37

@Schrompf:
Vielen Dank, da werde ich mich spätestens nächste Woche mal einlesen. Mal schauen, wie gut ich den Lösungsansatz auf meine Umgebung übertragen kann. :)

@dot:
Es handelt sich dabei um ein Wellenspektrum für eine Ozeandarstellung, die ich im Moment mit Java berechne.
Die Größe beträgt Momentan 256x256, soll aber nach Möglichkeit größer werden.
Durch Berechnen der Inversen FFT bekomme ich ein Höhenfeld, welches ich in einer Textur speicher und im Vertex shader lade, um die Vertizes zu verschieben.
Ich hoffe, du kannst dir nun zumindest grob etwas darunter vorstellen. :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

13.11.2015, 18:26

@dot:
Es handelt sich dabei um ein Wellenspektrum für eine Ozeandarstellung, die ich im Moment mit Java berechne.
Die Größe beträgt Momentan 256x256, soll aber nach Möglichkeit größer werden.
Durch Berechnen der Inversen FFT bekomme ich ein Höhenfeld, welches ich in einer Textur speicher und im Vertex shader lade, um die Vertizes zu verschieben.
Ich hoffe, du kannst dir nun zumindest grob etwas darunter vorstellen.

Naja, diese Berechnung lauft aber also als separater Durchgang und muss nicht während dem Rendern in einem Shader ausgewertet werden. Ich sehe keinen Grund, wieso man das also nicht in einem Compute Shader machen könnte, CUDA ist damit ebenfalls eine Option und dort gibt es hochoptimierte Libraries wie z.B. cuFFT...

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

13.11.2015, 18:30

Er hat ja schon ganz am Anfang gesagt, dass er keinen Compute Shader benutzen kann ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

13.11.2015, 18:32

Naja, OpenCL und CUDA sind aber angeblich ja eine Option und ich würde erwarten, dass die im konkreten Fall der FFT, beispielsweise aufgrund der Möglichkeit local Shared Memory zu benutzen, wesentliche Performancevorteile besitzen... ;)

10

17.11.2015, 10:10

Ich habe erst einmal Cuda in die Anwendung integriert, das Ergebnis hatte ich mir allerdings anders vorgestellt.
Hier mal ein kleiner Benchmark:

Umgebung:
- Zwei Unterprogramme, Berechnung einmal auf CPU Basis (JTransform), einmal auf GPU Basis (JCuda), welche sich bis auf kleine Anpassungen nicht voneinander unterscheiden.
- Beide laufen mit double Präzision und 2D
- Es werden pro Unterprogrammdurchlauf 3 iFFT hintereinander durchgeführt und die Zeit gemessen
- Notebook: i7-4710HQ, 8GB Ram, GTX 860m, Windows 10 64bit

Input 512²:
CPU: 7-16 ms
GPU: 16-32 ms

Input 1024²:
CPU: 31-47 ms
GPU: 47-63 ms

Input 2048²:
CPU: 141-156 ms
GPU: 234-250 ms

Die richtige Grafikkarte wird belastet, aber nur mit etwa 8%.
Erklären kann ich mir die Ergebnisse nur damit, dass der Datentransfer zur Grafikkarte derart langsam ist, dass jeglicher Performance-Vorteil aufgefressen wird.

Kommt das sonst ungefähr hin, oder sind 10-20ms bei 1024² auch sonst viel zu langsam? (Java kann hier natürlich auch nicht so schnell sein, wie c).

Werbeanzeige