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

Aktuelle Zeit: Do Jun 19, 2025 22:28

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



Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 06:34 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
Hallöchen,

so, jetzt wirds kompliziert. Ich habe hunderste Partikelemitter die ich am Anfang beim emittieren zu einem Buffer zusammenfasse. Diese werden dann via Transformfeedback weiter berechnet. Damit ich später beim Rendern der Partikel noch weiß, aus welchem Emitter das Partikel kam, (das brauch ich aus mehreren Gründen..) schleife ich einen weiteren EmitterID-Buffer durch die Pipeline.

So nun brauch ich pro Emitter, die BoundingBox der Partikel die von ihm erzeugt wurden. Wie könnte man dies nun am einfachsten realisieren?

Grüße,
Thomas

ADD: Es geht hier meist um bis zu 1000 Emitter und insg. 2-3mio Partikel...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 12:35 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Am besten keine Bounding-Box sondern Bounding-Sphere verwenden.
Eine Bounding-Box benötigt zu viel dynamic branching, während ne Bounding-Sphere mit einem Check verarbeitet ist und auch einem Partikel viel besser repräsentieren kann.
Im Fall einer Bounding-Sphere ist die Position die gleiche wie das transformierte Partikel selber und der Radius entspricht der Größe des Partikels, welches ja auch irgendwo definiert wurde(z.B. t=time, GL_PointSize oder ähnliches).
Der Test selber wäre dann sehr trivial.
float dist=abs(particleA-particleB)-(radiusA+radiusB);

*dist==0 -> 1 Kontaktpunkt
*dist<0 -> überschneiden sich
*dist>0 -> keine kollision

In einem shader könnte man dann z.B. folgendes machen.
color_out=float3(step(dist,0),0.0,0.0);// zeichne alle kollidierenden Partikel rot, sonnst weiß

In einigen Fällen kommt man natürlich nicht um ein dynamic branching, da sollte man dann davon aus gehen, dass der true case der übliche Fall ist.
Also im fall einer Flüssigkeits Simulation wäre es alle Partikel kollidieren.
if (dist<=0.0)
do foo
else
do bla

Im Fall von eines Feuers, Asteroiden, Special FX wäre es keine kollision.
if (dist>0.0)
do foo
else
do bla

Da die CPU und GPU bei branching eine schätzung machen, welcher Fall ein tritt, geht die verarbeitung weiter und wenn dann einige cycles später die Antwort rein kommt, wird geguckt ob alles verworfen werden muss und der else tree durch geht oder einfach weiter machen kann, ohne Zeit verloren zu haben.

Dynamic Branching ist nur sehr teuer, wenn man den seltenden Fall im if und den häufigen im else packt.
Aber auf GPU würde ich das vollständig meiden und mathematische wege suchen, die ein dynamic branching verhindern.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 13:34 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
nein du hast mich leider falsch verstanden.. Ich brauch keine BoundingSphere für das Partikel selbst, sondern für ALLE Partikel EINES Emitters... ich muss um diese Partikel eine Box zeichnen worauf etwas projeziert wird..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 15:50 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
lässt sich die Position deiner Partikel durch eine Funktion f(t) abbilden?

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 17:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also on-thy-fly eine BoundingBox zu berechnen ist nicht leicht, zumindest wenn es effizient sein soll. Wenn möglich solltest du versuchen die Box auf Basis der Parameter des Emitters zu berechnen. Wenn die Parameter konstant sind sollte das ziemlich gut funktionieren, insbesondere da du das nur einmal machen musst.

Es wäre wahrscheinlich hilfreich zu wissen was du da auf die Box projizieren willst. Kannst du das vielleicht direkt auf die Partikel projizieren statt auf die Box?

Wenn du tatsächlich eine BoundingBox brauchst...hm....ich würde irgendwie versuchen mit einem Vertexshader jeweils immer eine BoundingBox für N Partikel zu berechnen (z.B. mit N = 100). Die BoundingBox schreibt der Shader via TransformFeedback Min und Max in einen VBO. Auf den neuen VBO (mit jetzt nur noch 2/N sovielen Partikeln) wendest du den gleichen Shader (leicht angepasst, weil der keine Partikel bekommt) dann wieder an...solange bis nur noch eine einzelne BoundingBox übrig bleibt.

So würde das jedenfalls funktionieren wenn man alle Partikel in EINER Box haben will. Da du nun aber pro Emitter eine Box hast wird es kompliziert. Möglicherweise lässt du den Geometryshader jeweils BoundingBoxen für ca. 10-20 Emitter berechnen. Also du speicherst Min, Max und EmitterID als ein "Vertex" im Buffer. Diese BoundingBoxen fasst du dann in einem weiteren Pass weiter zusammen, solange bis du für jeden Emitter eine Box hast.

Pseudocode:
Code:
  1. uniform int u_particle_offset;
  2. uniform int u_particle_count = 100;
  3. uniform int u_emitter_offset;
  4. uniform int u_emitter_count;   // Anzahl Emitter die bearbeitet werden sollen
  5.  
  6. varying out vec3 vo_min;
  7. varying out vec3 vo_max;
  8. varying out int vo_emitterId;
  9.  
  10. void main() {
  11.     vec3 bbMin[u_emitter_count];
  12.     vec3 bbMax[u_emitter_count];
  13.    
  14.     for (int e=0; e<u_emitter_count; ++e) {
  15.         bbMin[e] = vec3(0,0,0);
  16.         bbMax[e] = vec3(0,0,0);
  17.     }
  18.     for (int i=u_particle_offset; i<u_particle_count; ++i) {
  19.         Particle p = GetParticle(i);
  20.         int e = p.emitterId - u_emitter_offset;
  21.         if (e >= 0 && e < u_emitter_count) {
  22.             bbMin[e] = min(bbMin[e], p.position - p.radius);
  23.             bbMax[e] = max(bbMax[e], p.position + p.radius);
  24.         }
  25.     }
  26.     for (int e=0; e<u_emitter_count; ++e) {
  27.         vo_min = bbMin[e];
  28.         vo_max = bMax[e];
  29.         vo_emitterId = u_emitter_offset + e;
  30.         Emit_Vertex();
  31.     }
  32. }

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 18:14 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Willst du raytracing betreiben, oder wozu brauchst du eine box ?
Soll die boundingbox perfekt sein, also dynamisch anpassen ?
Wenn ja kommst du wohl kaum um eine funktion f(t) drum rum, wenn du nicht gerade lust auf bruteforce hast.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 21:00 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
der Ansatz von Coolcat sieht schon gut aus. Noch paar infos. Die BoundingBox muss keineswegs perfekt sein, wichtig ist alle Partikel eines emitters einschließt und den Partikeln rel. nahe ist. Es geht um die Realisierung von Waterscreens. D.h. kleine Fontänendüsen wo mit Laser oder Videoprojektoren drauf projeziert wird. Es würde also auch genügen die boundingBox von ca. 3-10 Emittern zu berechnen, denn mehr Waterscreens kommen in einer Szene selten vor. Es würde theoretisch auch genügen, wenn sich die BoundingBox nur an Anfang aufbaut. Da die projezierte BoundingBox am Ende mit den Partikeln multipliziert wird, sieht man nur da was wo auch Wasser ist.

An direkter Projektion auf Partikel hab ich schon lange rumprobiert. Aber da es immer sehr viele Lichtquellen sind und die Partikel ohne Tiefentest gerendert werden wirds hier schwierig..

Bei der alten CPU Berechnung war es einfach, da hab ich einfach beim Partikel Update mit dem jeweiligen Min/Max-Wert verglichen..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Mi Jul 25, 2012 23:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Thmfrnk hat geschrieben:
der Ansatz von Coolcat sieht schon gut aus. Noch paar infos. Die BoundingBox muss keineswegs perfekt sein, wichtig ist alle Partikel eines emitters einschließt und den Partikeln rel. nahe ist. Es geht um die Realisierung von Waterscreens. D.h. kleine Fontänendüsen wo mit Laser oder Videoprojektoren drauf projeziert wird. Es würde also auch genügen die boundingBox von ca. 3-10 Emittern zu berechnen, denn mehr Waterscreens kommen in einer Szene selten vor. Es würde theoretisch auch genügen, wenn sich die BoundingBox nur an Anfang aufbaut. Da die projezierte BoundingBox am Ende mit den Partikeln multipliziert wird, sieht man nur da was wo auch Wasser ist.

An direkter Projektion auf Partikel hab ich schon lange rumprobiert. Aber da es immer sehr viele Lichtquellen sind und die Partikel ohne Tiefentest gerendert werden wirds hier schwierig..

Bei der alten CPU Berechnung war es einfach, da hab ich einfach beim Partikel Update mit dem jeweiligen Min/Max-Wert verglichen..


Achso du willst zwei Volumen schneiden.... Dafür brauchst du keine Boundingbox sondern musst Raytracing fälschen. Das geht relativ einfach wenn du
einfach subtrahieren kannst (z.b. Shadowmapping) ansonsten musst du evtl. n bissl tricksen. In deinen Falle dürfte Tiefenpuffer (Partikel) - Tiefenpuffer (Laser) reichen,
wenn du es nicht projezieren willst.... Evtl musst du halt ein Start- und Endbyte definieren und für alles dazwischen den ganzen kram machen....

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Do Jul 26, 2012 14:09 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
Anderer Ansatz:

Ich weiß ja pro Nozzle, mit welcher Power, Richtung + Sprühwinkel die Partikel emittiert werden. Wenn ich nun rausbekommen könnte welche Maximalhöhe ein Partikel des Nozzles erreichen kann, dann kann ich damit + den Sprühwinkel eine statische Box bauen.

So ein Partikel Update sieht so aus:

Code:
  1.  
  2.  Position += dir;
  3.  dir.y  -= gravitation;
  4.  


dir.y enthält am Anfang die Power mit welcher das Partikel emittiert wird. In jedem Frame wird hier dann die gravitation abgezogen. Eine möglichkeit wäre nun folgende. Ich schieße ein "virutelles" partikel ab und gucke wie hoch es kommt:

Code:
  1.  
  2.  maxHeight := 0;
  3.  while dir.y > 0 do //Wenn dir.y = 0 dann Partikel oben angekommen
  4.   begin
  5.    maxHeight := maxHeight + dir.y;
  6.    dir.y := dir.y - gravitation;
  7.   end;
  8.  


Allerdings finde ich das bisschen unprofessionell. Gibts da nicht irgendeine Formel womit man dies in einem Rutsch ausrechnen kann?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Do Jul 26, 2012 14:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
posY(t) = posYStart + (dirYStart - gravitation * t) * t;
posY'(t) = 0
t = dirYStart/(2 * gravitation)

posY(dirYStart/(2 * gravitation)) = posYStart + dirYStart^2 / (4*gravitation)

ist extempunkt von posY

über den ansatz lässt sich das eig lösen

mfg Frenk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Do Jul 26, 2012 15:18 
Offline
DGL Member

Registriert: Do Apr 22, 2010 17:17
Beiträge: 543
mhhh so ganz verstehen tu ich deine formel nicht..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Do Jul 26, 2012 16:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
posY(t) = posYStart + (dirYStart - gravitation * t) * t;

posY gibt schlicht die position die ein Partikel von position posYStart mit dirYStart(richtung*stärke) emittiert nach t an.

posY ist an der stelle maximal/ minimal an der die ableitung = 0 ist sprich :
posY'(t) = 0

löst man diese gleichung bekommt man heraus, dass es ein extremata an der stelle t = dirYStart/(2 * gravitation) gibt.

nun setzt man t wieder in posY ein
posY(dirYStart/(2 * gravitation)) = posYStart + dirYStart^2 / (4*gravitation)

somit ist die maximale Y wert im standart fall
posYStart + dirYStart^2 / (4*gravitation)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: GPU Partikelsystem BoundingBox
BeitragVerfasst: Do Jul 26, 2012 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
mhhh so ganz verstehen tu ich deine formel nicht..

Er hat aus deinem iterativen Ansatz eine geschlossene Formel gemacht
Code:
  1. posY(t) = posYStart + (dirYStart - gravitation * t) * t;

Für t = 1 ist das eben genau 1 Iterationsschritt, für t = 2 sind es 2 usw.
Das Ding hat er abgeleitet und die Nullstelle berechnet. Da die Ableitung linear ist gibt es nur die eine Nullstelle und die liegt eben bei
Zitat:
t = dirYStart/(2 * gravitation)

Dieses t setzt du dann wieder in die Formel ein und erhältst den Extremwert für Y. Normalerweise sollte dies das Maximum sein (nur wenn deine Gravitation nach unten geht ;)). Beachte das du auch ein negatives t erhalten kannst, etwa wenn die Düse unten gerichtet ist. Also du musst das Ergebnis auf den zulässigen Bereich 0...MaxLifetime beschränken.

Aus diesem berechneten Punkt und den Punkten t=0 und t=MaxLifetime baust du dann deine BoundingBox.


Edit: FrenK war schneller.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 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.022s | 17 Queries | GZIP : On ]