Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 11:49

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 45 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
BeitragVerfasst: Di Sep 28, 2004 22:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Habe die Tage irgendwo (glaube auf gamedev) ne Demo gesehen, in der jemand auf nem Terrain nen sich im Wind wiegenden Graslayer dargestellt hat, der allerdings alles andere als toll ausgesehen hat. Hab mir dann aus reiner Neugier mal selbst Gedanken zu de Thema gemacht und ne eigene Variante erstellt, die auch recht schön aussieht.
Da sich die Spitzen der Gras/Pflanzenbillboards im Wind wiegen sollen nutzt man im Normalfall ne Sinus-Funktion, und ich dachte mir zuerst dass es sinnvoller (=schneller) wäre diese Per-Vertex-Berechnungen auf der GPU ausführen zu lassen, dass war allerdings ein kompletter Fehlschluss.
Wenn ich die Berechnungen auf der CPU laufen lassen, dann erreiche ich knapp 30FpS, lagere ich diese auf die GPU aus, sinkt es direkt auf ~18FpS, was ich eher nicht erwartet habe (zumal der Sinus ja auf der GPU in Hardware berechnet wird, wenn ich nicht irre). Im Normalfall sieht man ~12000 Billboards, der Shader sieht so aus :
Code:
  1. attribute float weight;
  2. attribute float time;
  3.  
  4. void main()
  5.  {
  6.  // use weight and time attributes to let the upper part of the billboard wave in the wind
  7.  vec4 vertex    = gl_Vertex;
  8.  float tSin     = sin(time);
  9.  vertex.x       = vertex.x + (0.2 * tSin) * weight;
  10.  gl_Position    = gl_ModelViewProjectionMatrix * vertex;
  11.  gl_TexCoord[0] = gl_MultiTexCoord0;
  12.  gl_FrontColor  = gl_Color;
  13.  }


Und an sich ist (besonders mit dem beiden letzten Treiberreleases) glSlang in Sachen Geschwindigkeit um einiges besser geworden. Wollte deshalb mal rundfragen obs generell so ist, dass die trigonometrischen Berechnungen besser auf der GPU gemacht werden, oder es an der Hardware/den Treibern liegt.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 28, 2004 22:22 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Bei der GFFX wird SIN,COS in einem Takt wie ADD,MOV usw.. berechnet, aber bei der Radeon muß dazu diese Potenzreihe mit 6 bzw 7 Befehlen aufsummiert werden. Daher wäre mal das Ergebnis auf einer GeForce interessant.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 28, 2004 22:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Oja, ich sehs grad in der Programming-Guide zum R9700 ausm Radeon-SDK. In ARB_Fragment_Program braucht die SIN-Funktion tatsächlich 10 Hardwareinstruktionen (und 2 Tmp-Register, was wohl darauf schliessen lässt dass es über Umwege berechnet wird), und ist in Sachen "teuer" nur von der COS-Funktion (11 Instruktionen) getoppt.

Aber würde mich wirklich mal interessieren wie das auf der GFFX läuft. Werd meine kleine Anwendung dann mal umwurschteln, und auf einen Benchmarkvergleich GPU/CPU erweitern, so dass hier ein GFFX-Besitzer das mal testen kann.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 10:12 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Hab heute mal ein wenig "investigiert" und dabei ist mir folgendes aufgefallen : Bisher habe ich jedes Billboard so gerendert :
    *Matrix auf den Stack
    *An Position verschieben
    *Entgegengesetzt zu Betrachterwinkel auf y- und z-Achse rotieren
    *Als Quad rendern
    *Matrix wieder vom Stack holen
Wenn ich das auf der GPU machen will, muss ich das ja so machen. Pointsprites kommen nicht in Frage, da ich ja den oberen Teil der Billboards im Wind wehen lassen und zudem noch via glColor einen Helligkeitsverlauf von unten (etwas dunkler) nach oben (normale Helligkeit) simulieren. In diesem Szenario ist der Unterschied zwischen Berechnung der Windbewegung der Billboards auf der CPU bzw. der GPU recht hoch (~28 FPS wenn auf CPU berechnet, und ~18 FPS wenn auf GPU per Shader berechnet).

Obige Renderprozedur ist natürlich recht aufwendig, schliesslich muss ich dann (je nach Ansicht) bis zu 11.000 mal die Matrix auf den Stack legen und dort wieder runterholen. Im Gegenzug werden die Rotationen und die Verschiebung allerdings von der GPU abgewickelt, worauf diese ja spezialisiert ist.

Dann habe ich grade eben diese Berechnungen komplett auf die CPU ausgelagert, und es sieht jetzt so aus :
    *(Für alle vier Eckpunkte des Billboard-Quads)
    *Vektor auf der CPU entgegengesetzt zu Betrachterwinkel auf der y-Achse rotieren
    *Vektor auf der CPU entgegengesetzt zu Betrachterwinkel auf der z-Achse rotieren
    *Positionsvektor zu obigem Vektor addieren
    *So berechnete Daten via glVertex3fv an die GL senden

Und siehe da : das Bild sieht plötzlich total anders aus. Mal abgesehen davon dass es so generell schneller läuft (obwohl ich ja jetzt alle Berechnungen auf ner "General-Purpose"-CPU mache, statt auf der dafür ausgelegten GPU) ist der Unterschied zwischen dem Berechnen der Windbewegung auf der CPU und auf der GPU nun recht marginal : ~31 FPS auf der CPU und ~28 FPS auf der GPU.

Schon eigenartig dieses Ergebnis, denn selbst wenn ich ALLE Berechnungen (also Rotation, Verschiebung, sowie Windbewegung) auf der CPU mache ists immernoch schneller als wenn ich nur die grundlegenden Sachen auf der GPU mache. Irgendwie eigenartig, denn eigentlich sollte man erwarten dass ne spezielle PU die Sache beschleunigen sollte.

Alternativ kann das natürlich auch bedeuten dass ATIs GL-Treiber wirklich ne Generalüberholung braucht. Aber evtl. kann jemand diese Beobachtungen nachvollziehen, oder damit was anfangen.

P.S. : Werde später mal die Demo hochladen, da kann dann jemand mit ner GFFX mal gucken ob er ein ähnliches Bild bekommt (da dürfte es eher das Gegenteil sein).

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 11:15 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Verwendest du eigentlich bei der Variante, die alles im VS macht, einen Vertex und IndexBuffer? Das könnte das Ergebnis auch noch mal beeinflussen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 11:29 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Nein, geht ja an sich nicht, da ich die Billboards ja einzeln rotiere und dann müsste ich wenn ich ein VA oder ein VBO verwende diese ja in jedem Frame anpassen, was wohl kaum für Geschwindigkeit sorgen dürfte. Im VS wird übrigens nur die Windbewegung gemacht, also keine Ausrichtung bzgl. der Betrachterposition (dann müsste ich ja noch mehr Sinus/Cosinus-Berechnungen auf der GPU machen).

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 13:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Wers probier will, kann die Demo hier runterladen (790 KByte, RAR-Datei, benötigt Karte die glSlang-fähig ist). Am besten direkt nach dem Start (der etwas dauert) 'b' drücken, dann läuft der Benchmark in allen Kombinationen durch und zeigt ein Ergebnis, dass auch in einer Datei abgelegt wird. Interessieren würde mich hier u.a. auch ein Ergebnis von einer GFFX (muss ja keine große sein, mir gehts eher um die Relation CPU<->GPU).

Screenshot :
Bild

Falls euch etwaige Ungereimtheiten auffallen (Gras in hängt in der Luft, ausserhalb des Terrains, etc.) dann behaltet es für euch. Das hier ist nur ein kleiner Test und ich hab nur knapp ne Stunde Programmierzeit investiert. Mir gehts nur um die Relation GPU <-> CPU.

Meine Ergebnisse, Radeon 9700 (Catalyst 4.9, 0xAA, 8xAF Quali.) :
Code:
  1. Rotations and translations done on CPU :
  2.   Wind calculations on CPU = 29,40 FpS
  3.   Wind calculations on GPU = 27,10 FpS
  4. Rotations and translations done on GPU :
  5.   Wind calculations on CPU = 26,50 FpS
  6.   Wind calculations on GPU = 17,00 FpS
  7.  


Edit : 'W' -> nach vorne bewegen, 'S' -> nach hinten bewegen.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Zuletzt geändert von Sascha Willems am Mi Sep 29, 2004 16:41, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 13:32 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Ich habe bei einer Radeon 9800 pro und einem Athlon 2000+ XP folgendes Ergebnis:
Rotations and translations done on CPU :
Wind calculations on CPU = 23,10 FpS
Wind calculations on GPU = 22,00 FpS
Rotations and translations done on GPU :
Wind calculations on CPU = 22,00 FpS
Wind calculations on GPU = 14,60 FpS

Daher scheint es hauptsächlich durch die CPU (glVertex) begrenzt zu sein.


Zuletzt geändert von LarsMiddendorf am Mi Sep 29, 2004 14:57, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 13:54 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Darf man fragen mt was du Tarrain und Pflanzen erstellt hast?
Der kleine Screenshot sieht ja aller erste Sahne aus!

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 14:47 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Terrain mit meinem eigenen Tool (TerrTexGen, dürfte eigentlich bekannt sein), Pflanzen "mit" der Google-Bildsuche.

P.S. : Bitte On-Topic bleiben.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 15:48 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Bei mir sieht das Ergebniss ähnlich aus...
Zitat:
Rotations and translations done on CPU :
Wind calculations on CPU = 28,30 FpS
Wind calculations on GPU = 26,60 FpS
Rotations and translations done on GPU :
Wind calculations on CPU = 25,90 FpS
Wind calculations on GPU = 17,30 FpS

Radeon 9600 Pro + Athlon 2800+ XP


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 29, 2004 16:46 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
LarsMiddendorf hat geschrieben:
Daher scheint es hauptsächlich durch die CPU (glVertex) begrenzt zu sein.


Klingt irgendwo logisch, lässt sich nur halt leider nicht vermeiden. Oder hat jemand ne andere Idee wie man das realisieren könne. Wäre im Endeffekt natürlich optimal wenn man das über Pointsprites realisieren könnte, aber wie gesagt kann man da nicht so einfach Einfluß auf die Eckpunkte des Pointsprites nehmen.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Sep 30, 2004 02:13 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Will ja nix sagen, aber wenn es langsamer wird wenn man etwas auf die GPU auslagert dann erscheint mir das hier: "Daher scheint es hauptsächlich durch die CPU (glVertex) begrenzt zu sein." nicht allzu logisch. Scheint eher die GPU das Bottleneck zu sein.

Aber zum eigentlichen Thema:
Obwohl ich (noch) nicht allzu viel mit Shadern am Hut hab (mir fehlt noch die Hardware dafür :-) ) hab ich mich auch vor einem Zeiterl mal mit diesem Problem beschäftigt. Und ich fand die beste Lösung die, das man das vorberechnet. Also du legst dir meinetwegen ne Tabelle mit 256 Einträgen zurecht die du immer dann updatest wenn sich Windgeschwindigkeit oder Grashöhe (bei Bedarf) ändert.
Wenn du die Billboards in Software berechnest, kannst du zusätzlich auch gleich nen Array mit 256*4 Vektoren anlegen wo du dir die fertigen Billboard Vektoren berechnest, also nur noch diese 4 Vektoren zum jeweiligen Grasbüschel-Punkt addieren musst. Diesen Array musst du natürlich je Frame berechnen aber da ist ja auch keine Aufwändige Rechenoperation drinnen.
Um noch ne schöne Wellenbewegung des gesamten Grases zu sehen (nicht nur für einen Grashalm) kannst du ganz einfach den Offset innerhalb des Arrays je nach x- oder y- coordinate berechnen.

Naja ich denk ihr könnt es euch schon so ungefähr vor stellen. Wie man das für Vertex Programme brauchbar machen könnt wisst ihr sicher auch besser als ich, ausser die ein oder andere Spec gelesen hab ich damit ja noch nicht viel gemacht. Aber es findet sich sicher irgend eine Möglichkeit um den Sin zu umgehen. Interpolieren kann man ja die vorberechneten Werte immer noch, dann is der Unterschied zu einem wirklichen Sin nur noch minimal. In Software natürlich nicht so brauchbar :-).

Bei mir führte diese Methode sehr schnell zu Füllratenbeschränkungen. Vertexabhängig bin ich nicht, da es mehr oder weniger egal ist (FPS mäßig) ob ich je Grasbüschel ein 4eck oder 3 4ecke (1 mit 2 Unterteilungen halt) verwende.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 01, 2004 10:22 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Mit deiner vorberechneten Tabelle dürtest du schon recht haben, denn damit nimmt man (je nachdem wo mans macht) GPU bzw. CPU ne Menge arbeit ab und muss im schlimmsten Falle ja nur eine Rundung (um den Index für das Wertearray zu bekommen) pro Billboard ausführen. "Nachteil" ist dann zwar dass die Bewegung nicht mehr ganz so flüssig ist, aber dass dürfte den wenigsten Personen auffallen. Werde das mal bei Gelegenheit ausprobieren.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 01, 2004 11:27 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Die Sache mit der CPU Begrenzung kann schon stimmen. Ich habe einen Athlon XP 2000 und eine Radeon 9800 pro, die 30% schneller ist als die Radeon 9700 von SoS ist. SoS hat aber einen schnelleren Prozessor. Anstelle der Tabelle könnte man ja auch statt der 6 Befehle nur 3 nehmen. Dann ist der Wert eben nicht so genau.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 45 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Foren-Übersicht » Programmierung » Shader


Wer ist online?

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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]