[B3D] - Particle/Mesh in CameraView?
Übersicht

![]() |
PSYBetreff: [B3D] - Particle/Mesh in CameraView? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hiho,
momentan bin ich dabei, ein Particle System zu coden. Infos dazu gibts im Worklog-Bereich. Ein Problem bei solchen Systemen ist ja bekanntlich die Performance. Deshalb ist es ungemein wichtig, auch nur die Particle zu rendern, die innerhalb des Sichtbereichs der Kamera liegen. Dabei wird oftmals die Funktion CameraProject(...) verwendet, die 3D Koordinaten in 2D Koordinaten umrechnet. Man braucht also nur die x,y,z Position seines Particles mit Hilfe von CameraProject() in 2D Koordinaten umzuwandeln, und dann überprüfen ob die Koordinaten innerhalb der eingestellten Auflösung liegen. Beispiel: Code: [AUSKLAPPEN] If ProjectedX() >0 and ProjectedX()<800 then RENDERPARTICLE....
Diese Methode hat jedoch einen entscheidenden Nachteil: Je grösser der Particle skaliert wird, und je dichter sich die Kamera am Particle befindet, desto ungenauer wird die Berechnung. D.h. entweder wird der Particle gerendert, obwohl er sich schon ausserhalb des sichtbaren Bereiches befindet, oder (was meistens der Fall ist) Teile des Particles ragen noch in den sichtbaren Bereich, aber er wird dank der ungenauen Berechnung schon nicht mehr gerendert. Deshalb hab ich mal ein wenig rumgespielt, und rausgekommen ist folgender Code: (bei grossen Particlemengen sogar schneller als die CameraProject()-Methode): (edit) es geht hier eigentlich nur um die function visible_new(), der Rest des Codes dient nur der Veranschaulichung! Code: [AUSKLAPPEN] Graphics3D 800,600,0,2
SetBuffer BackBuffer() Local v%,algo%=0,x#,y#,z# Global Cam = CreateCamera() Global Mesh = CreateMesh() Global Surface = CreateSurface(Mesh) Global screenw = GraphicsWidth() Global screenh = GraphicsHeight() Global screen_ratio# = Float(screenw)/screenh Global xx#,yy#,zz#,size% =1 PositionEntity Cam,0,0,-20 ;CREATE "PARTICLE" v=AddVertex (Surface, -1, 1, 0) AddVertex Surface, 1, 1, 0 AddVertex Surface, -1,-1, 0 AddVertex Surface, 1,-1, 0 AddTriangle Surface, v, v+1, v+2 AddTriangle Surface, v+1,v+3, v+2 Repeat size=size+KeyHit(31)-KeyHit(45) : If size<1 Then size=1 ScaleEntity Mesh,size,size,size,1 xx=xx+KeyHit(205)*.5-KeyHit(203)*.5 yy=yy+KeyHit(200)*.5-KeyHit(208)*.5 zz=zz+KeyHit(44)-KeyHit(30) If KeyHit(28) Then algo=1-algo PositionEntity Mesh,xx,yy,zz RenderWorld() ;GET VERTEX COORDINATES OF PARTICLE TFormPoint VertexX(Surface,0),VertexY(Surface,0),VertexZ(Surface,0),Mesh,0 x = TFormedX() y = TFormedY() z = TFormedZ() Text 10,10,"VERTICE 0: " + x + " " + y + " " + z TFormPoint VertexX(Surface,1),VertexY(Surface,1),VertexZ(Surface,1),Mesh,0 x = TFormedX() y = TFormedY() z = TFormedZ() Text 500,10,"VERTICE 1: " + x + " " + y + " " +z TFormPoint VertexX(Surface,2),VertexY(Surface,2),VertexZ(Surface,2),Mesh,0 x = TFormedX() y = TFormedY() z = TFormedZ() Text 10,100,"VERTICE 2: " + x + " " + y + " " + z TFormPoint VertexX(Surface,3),VertexY(Surface,3),VertexZ(Surface,3),Mesh,0 x = TFormedX() y = TFormedY() z = TFormedZ() Text 500,100,"VERTICE 3: " + x + " " + y + " " + z If algo=1 visible_new() Else visible_old() EndIf Color 255,255,255 Text 0,300, "CURSOR KEYS : HORIZONTAL / VERTICAL MOVEMENT" Text 0,320, "A AND Y : CAMERA ZOOM" Text 0,340, "S AND X : SCALE PARTICLE" Text 0,360, "RETURN : TOGGLE ALGORITHM" If algo=1 Then Text 0,400,"USING NEW ALGORITHM: " Else Text 0,400,"USING CAMERAPROJECT: " Flip 1 Until KeyHit(1) Function visible_new() Local zdist# zdist = zz-EntityZ(Cam) If zdist > 0 If zdist > Abs(xx) - size If zdist > (Abs(yy)-size) * screen_ratio Color 0,255,0 Text 200,400,"PARTICLE VISIBLE" : Return End If End If End If Color 255,0,0 Text 200,400,"PARTICLE NOT VISIBLE" End Function Function visible_old() CameraProject Cam,xx,yy,zz If ProjectedZ()>0 If ProjectedX() > -size And ProjectedX() < screenw + size If ProjectedY() > -size And ProjectedY() < screenh + size Color 0,255,0 Text 200,400,"PARTICLE VISIBLE" : Return End If End If End If Color 255,0,0 Text 200,400,"PARTICLE NOT VISIBLE" End Function Steuerung: Mit den Cursortasten Particle in x und y Richtung bewegen Mit A und Y die Cam bewegen Mit S und X den Particle skalieren Mit RETURN zwischen der alten Methode (CameraProject) und der neuen Methode umschalten. Einfach mal den Partikel grösser skalieren und/oder mit der Cam ranfahren, dann sieht man das Problem. Wie man sehen kann, hat die neue Methode gegenüber der oftmals benutzen Cameraproject()-Methode einen entscheidenden Vorteil. L8er, PSY |
||
- Zuletzt bearbeitet von PSY am Fr, Feb 27, 2009 0:04, insgesamt einmal bearbeitet
![]() |
FireballFlame |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich versteh das noch nicht ganz. Rendert Blitz nicht automatisch nur das, was im Sichtfeld ist? Und kann man im Zweifelsfall nicht EntityInView benutzen? | ||
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit |
![]() |
the FR3AK |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zu EntityInView:
Blitz geht aber immer nur vom MittelPunkt des Objektes aus und dann treten eben mal solche Fehler auf wie oben beschrieben. Zu Blitz rendert nur alles was im Sichbereich ist: Ich glaube Blitz rendert alles was im CameraRange Bereich ist oder? |
||
![]() |
aMulSieger des Minimalist Compo 01/13 |
![]() Antworten mit Zitat ![]() |
---|---|---|
BB rendert ein Mesh komplett, sobald auch nur ein Polygon im Sichtbereich ist.
Da bei Partikelengines aber die Polygone oft jeden Frame neu erstellt werden lohnt es sich die die außerhalb des Bildschirms gerendert würden auszulassen. EntityInView ![]() EDIT: Auf den Code bezogen: Vier mal TFormPoint ![]() Wenn man das Partikel-Mesh an die Kamera hängt(EntityParent ![]() Wenn dann das Mesh eh an der Kamera hängt kann man übrigens auch ganz leicht und ohne großartige Rechnungen überprüfen ob die Partikel gesehen werden oder nicht, indem man einfach auf Überschneidung mit der pyramidenartige Form des Sichtfeldes prüft(oder noch simpler, aber dafür nicht so genau alle Partikel mit z<0 ausblendet) |
||
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans! Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver |
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
aMul hat Folgendes geschrieben: EDIT: Auf den Code bezogen: Vier mal TFormPoint ![]() Wenn man das Partikel-Mesh an die Kamera hängt(EntityParent ![]() Wenn dann das Mesh eh an der Kamera hängt kann man übrigens auch ganz leicht und ohne großartige Rechnungen überprüfen ob die Partikel gesehen werden oder nicht, indem man einfach auf Überschneidung mit der pyramidenartige Form des Sichtfeldes prüft(oder noch simpler, aber dafür nicht so genau alle Partikel mit z<0 ausblendet) Da muss ich widersprechen! Viel zu kompliziert. Ich will ja die Particel nicht nur drehen. Erstmal müssen sie rotieren können. Dann gibts die Option, alle Partikel auf die Kamera auszurichten. Dann brauch ich Partikel, die nach "oben" schaun, z.b. Wasserringe, Blätter, Zeitungen auf dem Boden usw. Partikel, die sich in Kreiselbewegungen fortbewegen (Helix) Partikel, die wachsen, schrumpfen, sich um alle Achsen drehn uswusw... Das soll ich alles von Hand berechnen? Wozu? Viel zu umständlich... So erstell ich ein Ghostmesh, skalier es auf die Grösse des Partikels, und platzier den Partikel ins Ghostmesh an x,y,z. Dann richt ich das Ghostmesh aus (je nachdem mit pointcamera, aligntovector, nen pivot rotieren lassen für helix uswusw.) Dann schnapp ich mir einfach die 4 Vertexcoordinaten von dem Particle aus dem Ghostmesh und übertrag sie auf mein Hauptmesh...das ist zig-mal einfacher und nur ein Bruchteil des Aufwandes gegenüber anderen Berechnungen. Und von der Geschwindigkeit ändert das überhaupt nix, eher im Gegenteil... ich brauch nicht einen sin oder cos befehl im ganzen system... Zitat: Wenn dann das Mesh eh an der Kamera hängt kann man übrigens auch ganz leicht und ohne großartige Rechnungen überprüfen ob die Partikel gesehen werden oder nicht, indem man einfach auf Überschneidung mit der pyramidenartige Form des Sichtfeldes prüft
genau das mach ich ja .... L8er, PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group