Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Rosenblatt Partikel Rezzer Lastoptimiert
#1
Für Freunde romantischer Stunden hier mal ein Rosenblatt Partikel Rezzer.


Auch dieser Rezzer macht nur Partikel wenn ein Avatar in Sichtweite ist. So sparen wir zusammen Serverlast, und halten unsere Sims performant. Ihr könnt ihn also bedenkenlos einsetzten.


Lege dazu in ein Prim eine Rosenblatt Textur mit dem Namen "Rosenblatt" sowie dieses Script hinein. Auflösung 128x128 ist super.

Rezze dieses Prim auf ca 3 Meter Höhe über dem Boden für den besten Effekt.
Je nach Simulator Version und Physik Engine fällt das Ergebnis stark unterschiedlich aus.
Am meisten sichtbar sind die Partikel in Opensimulator mit Bulletsim Physik.

in der Zeile "integer count = 3;     // Anzahl Partikel pro Ausstoß" könnt ihr die Anzahl Partikel nachstellen.

Tip: es macht sich besser 3 Partikel Rezzer im Dreieck mit ca 7 m Distanz aufzustellen als einen Rezzer mehr Partikel erzeugen zu lassen.

Als Avatar Atachment getragen erzeugt er eine Rosenblatt Spur auf eurem Weg durch die Sim.

Ich habe mal ein Rosenblatt als Attachment hinzugefügt.





   



Inworld ist der Rezzer an mehreren Stellen bereits im Einsatz, so auf Loru Castle und der Hochzeits Kapelle der World Sim.
Wer mag kann inworld von mir verschiedene Varianten erhalten.


Viel Spaß damit


Tron




Code:
/* P405 Rosenblatt Partikel Rezzer mit Bewegungsmelder  TJ/ Tron V1
*
* auf Arriba 0.8x getestet: TJ/Tron 25.03.2016
*
* Grundzustand: Keine Partikel
*                Alle "scantimer" sekunden wird überprüft ob ein Avatar sich in "scandistance" Reichweite befindet.
*
* Befindet sich ein Ava in der Scanzone wird Rosenbalttfall für "effektdauer" sekunden eingeschalten.
* Diese Periode wiederholt sich bis kein Ava gefunden wird.
* Etwa 10 Meter über Grund anbringen
*/

                                   
float efektdauer = 60.0;            // Dauer des Effekts bis auto Abschaltung
float scantimer  = 20.0;            // Interval der Avatar Suche in Reichweite
float scandistance = 50.0;          // Reichweite der Avatar Erkennung. Auch Höhe beachten!
integer debug = FALSE;              // Debugmodus  [FALSE,TRUE]                                  
                                                           
string texture = "Rosenblatt";      // Partikel Textur im Prim                                    

integer count = 3;     // Anzahl Partikel pro Ausstoß
float    rate = 0.25;  // Wartezeit zwischen Partikel Ausstossen
float     age = 10.0;  // Partikel Lebensdauer
integer wind = TRUE;

integer   pattern = PSYS_SRC_PATTERN_ANGLE;
integer flags;
list sys;


updateParticles()
{
   flags = 0;
   flags = flags | PSYS_PART_EMISSIVE_MASK;
   if (wind) flags = flags | PSYS_PART_WIND_MASK;
   flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;

   sys = [  PSYS_PART_MAX_AGE,age,
                       PSYS_PART_FLAGS,flags,
                       PSYS_PART_START_COLOR, <1,1,1>,
                       PSYS_PART_END_COLOR, <1,1,1>,
                       PSYS_PART_START_SCALE,<0.1,0.1,0.1>,
                       PSYS_PART_END_SCALE,<0.1,0.1,0.1>,
                       PSYS_SRC_PATTERN, pattern,
                       PSYS_SRC_BURST_RATE,rate,
                       PSYS_SRC_ACCEL, <0,0,-0.03>,
                       PSYS_SRC_BURST_PART_COUNT,count,
                       PSYS_SRC_BURST_RADIUS,0.5,
                       PSYS_SRC_BURST_SPEED_MIN,0.2,
                       PSYS_SRC_BURST_SPEED_MAX,0.5,
                       PSYS_SRC_TARGET_KEY,"",
                       PSYS_SRC_INNERANGLE,0,
                       PSYS_SRC_OUTERANGLE,0,
                       PSYS_SRC_ANGLE_BEGIN, 0.2,
                       PSYS_SRC_ANGLE_END, 1,
                       PSYS_SRC_OMEGA, <0,0,-1>,
                       PSYS_SRC_MAX_AGE, 0.0,
                       PSYS_SRC_TEXTURE, texture,
                       PSYS_PART_START_ALPHA, 1,
                       PSYS_PART_END_ALPHA, 0.1
                           ];
   float newrate = rate;
   if (newrate == 0.0) newrate=.01;
   if ( (age/rate)*count < 4096) llParticleSystem(sys);
   else {
       llInstantMessage(llGetOwner(),"Your particle system creates too many concurrent particles.");
       llInstantMessage(llGetOwner(),"Reduce count or age, or increate rate.");
       llParticleSystem( [ ] );
   }
}


feedback(integer status)
{
   if(status)      
       {
           updateParticles();
           if(debug) llSay(PUBLIC_CHANNEL, "Rosenblatt Fall an");
       }  
   else
       {
           llParticleSystem( [ ] );                //Partikel Stoppen
           if(debug) llSay(PUBLIC_CHANNEL, "Rosenblatt Fall aus");
       }    
}    



integer avacheck()
{
   list avatars = llGetAgentList(AGENT_LIST_PARCEL, []);         // Avatarliste holen
   integer anzahl;
       
   for (anzahl = 0; anzahl < llGetListLength(avatars); anzahl++) // Avatareabstande durchtesten
       {
           if (llVecDist(llList2Vector(llGetObjectDetails(llList2Key(avatars, anzahl), [OBJECT_POS]),0), llGetPos()) <= scandistance)  
               { return (TRUE);}                    // Schleife beenden, Avatar in Reichweite gefunden      
       }  
   return (FALSE);    
}



state aktiv                                            // Status: Partikelerzeugung
{
   state_entry()
   {
       llSetTimerEvent(efektdauer);
       feedback(TRUE);        
   }

   timer()                                            // Schleife für Überprüfung ob Avatar noch in Reichweite
   {
       if ( !avacheck()) { state default;}            // Niemand mehr da, abschalten
   }
   
   changed(integer changebits)                        // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}



default                                                // Scannen in standby Modus
{
   state_entry()
   {
       llSetTimerEvent(scantimer);                    // Partikelerzeugung abschalten  
       feedback(FALSE);
   }
   
   timer()                                            // periodicher Check ob Ava in Nähe
   {                
       if ( avacheck()) { state aktiv;}
   }
   
   changed(integer changebits)                        // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}
Antworten }
Thanks given by: Achim , Dina , Tommy
#2
Partikel sind teil der Primeigenschaften und werden rein Clientseitig erzeugt.
Am lastsparendsten wäre es also per Script das Partikelsystem zu setzen und danach das Script zu entfernen.

Für ein Partikelsystem einen Timer laufen zu lassen der ständig die Primeigenschaften ändert ist NICHT Lastoptimiert Wink
Antworten }
Thanks given by: Achim , Manni , Dina
#3
(27.06.2016, 06:42)Kubwa schrieb: Partikel sind teil der Primeigenschaften und werden rein Clientseitig erzeugt.
Am lastsparendsten wäre es also per Script das Partikelsystem zu setzen und danach das Script zu entfernen.

Für ein Partikelsystem einen Timer laufen zu lassen der ständig die Primeigenschaften ändert ist NICHT Lastoptimiert Wink

Der Sinn des Timers ist die gleichzeitige Anzahl der dargestellten Partikel pro Sim zu reduzieren. Ich habe den nach ausgiebigen Test eingeführt weil es insbesondere bei von mehreren Usern bewohnten VAR Region Sims schnell zu einer Überschreitung der verträglichen Partikelzahl kommt. Es ist nachvollziehbar, das die Sim Serverseitig crasht wenn die Anzahl gleichzeitg darzustellender Partikel ca. die 4000er Grenze überschreitet. Da sich diese (vereinfacht) als Summierung der emmitierten Partikel mit deren Lebensdauer darstellt, und alle Partikelscripte einer Sim umfasst, ist die Gesamtzahl nicht sehr hoch. Diese Grenze habe ich schmerzlich mit meinen Feuerwerk Partikel Scripten erkennen müssen.

Meinen Client Rechner (8Core, 16GB, R9-280X, W7_64) hingegen juckt die Partikel Zahl noch gar nicht, der dümpelt so bei ca 20% CPU Last / 50% Grafiklast vor sich hin. Es muss also bei steigender Partikelzahl eine Belastung des Servers durch die Sim erfolgen, die zu dem Sim Absturz führt. Um das zu Prüfen habe ich auf einem "schwachen" Rechner einen Gegentest gemacht. (2 Core x 3.2GHz, 4GB Ram, AMD R7-260X) Ich habe darauf einen lokalen Simulator (Opensim 0.8.2 mit Bullet) und einen den Viewer (Firestorm 32Bit) untergebracht um die Gesamtbelastung Client und Serverseitig als Summe zu erfassen. Fazit: 3 simple (ungeregelte) Rauch Partikel Scripte ohne AVA Abfrage brachten das 2-Core system auf 100% Last, wobei die Last der Servertask stark anstieg. Die Rauchpartikel waren auf verschiedenen Ecken der 512er Sim verteilt. Nach Einfügen der AVA Detektion mit 64 Meter Scanrange ging die Last erträglich runter, da einzelne Rauch Emitter abgeschaltet wurden. Ohne Rauch lag die Belastung des Gesamtsystems  bei ca. 20%.

Diese Ergebnisse veranlassen mich zu der Annahme das Serverseitig der Ort der Partikel berechnet wird, und den Clients mitgeteilt wird. Das Verhalten wäre ja auch konform zu allen anderen darzustellenden Objekten (Prims, Sculpts, Mesh) die von der Sim verwaltet werden, und bei denen die Sim dem Client die aktuelle Position mitteilt. Der Client wäre demzufolge "nur" für die Darstellung der Objekte inclusive Partikel verantwortlich. Das würde zur Folgerung führen das der Server durch ständig darzustellende Partikel Last hätte, selbst wenn gar kein User in der Sim ist, was noch detailliert zu prüfen wäre, aber meinem Eindruck entsprach. Wie sonst sollte der Server sonst bei einem hereinkommenden AVA auch wissen wo sich Partikel und bewegte Objekte gerade befinden.

Wenn jemand ne andere Erklärung hat, der den Code kennt, bitte gerne posten!

Bleibt die Frage wie hoch die Last der Sim durch das Polling nach Avataren tatsächlich ist.

Wichtig ist hier sicher das Überprüfungs Intervall zu minimieren.
Ich habe für mich festgelegt das die Erkennung eines zu Fuß herankommenden Avatars möglichst vor erreichen der Sichtbarkeits Grenze der Partikel erfolgen muss, wo der Viewer die Darstellung der Partikel beginnen würde.

Es hängt also im Einzelfall von dem Scanradius und der Partikelgröße ab welches Intervall notwenig ist, um diese Funktion zu erfüllen.

Bei meinen Tests mit kleinen Partikeln hat sich ein Radius um 50 Metern bewährt bei einem Scannintervall von ca 10 Sekunden.
Entsprechen für große Effekte wie Wasserspray an Felsen (100m) oder animierte Wellen (>250m).
Dieses scannen (ohne Schaltvorgang!) alle 10 Sekunden findet nur statt solange die Sim in Reichweite keinen Avatar hat - also hoffentlich eh in lastarmer Phase ist. Sobald ein Avatar erkannt wird, wird einmalig umgeschalten. Danach wird nur mehr alle 60 Sekunden überprüft ob noch ein Avatar da ist.
Hier könnte man sicher auch das Intervall vergrößern. Auch hier findet nur ein einmaliger Schaltvorgang statt wenn sich eine Änderung des Zustandes ergeben hat.

Der Blick in die Region Console (Region/Grundbesitz - Debug - Top-Scripts) offenbart die tatsächliche Scripting Last. Die liegt bei fast allen meiner AVA Scan Scripte die obigen Muster folgen bei ca 0,2ms.

Das vorhin angesprochen Wasserspray Partikel Script das ohne Ava Erkennung ständig durchlief, lag bei >2ms. Da ich davon ca. 15 auf der Sim verbaut hatte war das damals mein Grund diesen Weg einzuschlagen.


Natürlich ist die Entfernung des Scriptes aus dem Prim eine Möglichkeit um Speicher am Server zu sparen. (Wobei ich das nicht nachgemesen habe) Für Profis sicher ein Weg zur Endoptimierung einer fertigen Sim, auch was die unbefugte Kopiererei angeht. Jedoch verliert man dann die Möglichkeit das Script noch zu verändern, oder die Parameter nachzusehen. Für unerfahrenen Nutzer errichtet man auch eine zusätzliche Hürde. Und wenn man so wie ich alles auf der Sim zum Kopieren, Mitnehmen und Verändern für Hypergrid Besucher frei gibt, weiss ich nicht ob das Nebenwirkungen hat, das wäre zu testen.

Das Script ist eigentlich für eine nicht scripting Affine Zielgruppe gedacht, die es ohne Bedenken oder tieferes Verständnis der Materie einsetzten kann.

Es ist halt immer die Frage welche Resource man optimieren will, denn umsonst gibt es nichts!
Antworten }
Thanks given by: Dina , Achim
#4
Partikel werden nicht serverseitig berechnet.
Das würde keinen Sinn machen, das ist gar nicht im SL Viewerprotokoll vorgesehen.

Die Wellen auf dem Wasser und lokale Texturanimation sind auch rein lokal.

Die Region kann, wenn überhaupt, nur wegen zu vielen Scripten oder Objekteigenschaften crashen.

Ich kann dir gerne heute Abend demonstrieren wie ich 3000 Partikelscripte zusammen auf einer Region laufen lassen kann ohne den Server auch nur im geringsten keuchen zu lassen.
Antworten }
Thanks given by: Dina , Achim
#5
So etwas ähnliches hatte ich auch mal gemacht aber ein/ausschalten mit Klick.
Hier sind die Texturen davon:

   

   

   

   

   

   

   

Größe, Farbe, etc.  nach Wunsch ändern.


Ach dein Rosenblatt sah so traurig aus.

   
[Bild: attachment.php?aid=2009]
Antworten }
Thanks given by: Sylvia Koeln , Dina , Achim , Tommy
#6
Danke Manfred,

ich denke ein Wespenschwarm anstelle der Rosenblätter würde bei unserer Trauungs Kapelle sicher den Einen oder Anderen vor großer Dummheit bewahren -
die Libellen gefallen mir gut!
Antworten }
Thanks given by: Achim , Dina
#7
Update zur Scriptreduktion in der Sim



Da es sich gezeigt hat das die Kombination von 3 Rezzern in Abstand weniger Meter den schönsten Effekt macht, hab ich das Script nun umgeschrieben. Nun ist nur mehr ein Script im Root Prom nötig. Jedes leere Prim das dazu gelinkt wird, emittiert nun auch Partikel. Achtet aber drauf das das Prim mit dem Script, Root Prim bleibt, indem ihr bei der Selektion für das Linkset dieses Prim mit dem Script zuletzt anwählt-



Vorgehen: Leg das Script und die "Rosenblatt" Textur in ein Prim. Dann linkt dieses Prim zu leeren Prims dazu.

Viel Spaß Tron



Code:
/* P405 Rosenblatt Partikel Rezzer mit Bewegungsmelder für Linkset TJ/ Tron V2
*
* auf Arriba 0.8x getestet: TJ/Tron 05.02.2017
*
* Grundzustand: Keine Partikel
*                Alle "scantimer" sekunden wird überprüft ob ein Avatar sich in "scandistance" Reichweite befindet.
*
* Befindet sich ein Ava in der Scanzone wird Rosenbalttfall für "effektdauer" sekunden eingeschalten.
* Diese Periode wiederholt sich bis kein Ava gefunden wird.
* Etwa 5 - 10 Meter über Grund anbringen
*/

integer channel = 10000;            // Fernbedienungs Kanal ( gleich mit allen Prims der Funktionseinheit) festlegen.
                                   // Remote communication channel (shared for remote function group)
                                   
float efektdauer = 60.0;            // Dauer des Effekts bis auto Abschaltung
float scantimer  = 20.0;            // Interval der Avatar Suche in Reichweite
float scandistance = 50.0;          // Reichweite der Avatar Erkennung. Auch Höhe beachten!
integer debug = FALSE;              // Debugmodus  [FALSE,TRUE]                                  
                                                           
string texture = "Rosenblatt";      // Partikel Textur im Prim                                    

integer count = 1;     // Anzahl Partikel pro Ausstoß
float    rate = 0.25;  // Wartezeit zwischen Partikel Ausstossen
float     age = 10.0;  // Partikel Lebensdauer
integer wind = TRUE;

integer   pattern = PSYS_SRC_PATTERN_ANGLE;
integer flags;
list sys;


updateParticles()
{
   flags = 0;
   flags = flags | PSYS_PART_EMISSIVE_MASK;
   if (wind) flags = flags | PSYS_PART_WIND_MASK;
   flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;

   sys = [  PSYS_PART_MAX_AGE,age,
                       PSYS_PART_FLAGS,flags,
                       PSYS_PART_START_COLOR, <1,1,1>,
                       PSYS_PART_END_COLOR, <1,1,1>,
                       PSYS_PART_START_SCALE,<0.1,0.1,0.1>,
                       PSYS_PART_END_SCALE,<0.1,0.1,0.1>,
                       PSYS_SRC_PATTERN, pattern,
                       PSYS_SRC_BURST_RATE,rate,
                       PSYS_SRC_ACCEL, <0,0,-0.03>,
                       PSYS_SRC_BURST_PART_COUNT,count,
                       PSYS_SRC_BURST_RADIUS,0.5,
                       PSYS_SRC_BURST_SPEED_MIN,0.2,
                       PSYS_SRC_BURST_SPEED_MAX,0.5,
                       PSYS_SRC_TARGET_KEY,"",
                       PSYS_SRC_INNERANGLE,0,
                       PSYS_SRC_OUTERANGLE,0,
                       PSYS_SRC_ANGLE_BEGIN, 0.2,
                       PSYS_SRC_ANGLE_END, 1,
                       PSYS_SRC_OMEGA, <0,0,-1>,
                       PSYS_SRC_MAX_AGE, 0.0,
                       PSYS_SRC_TEXTURE, texture,
                       PSYS_PART_START_ALPHA, 1,
                       PSYS_PART_END_ALPHA, 0.1
                           ];
   float newrate = rate;
   if (newrate == 0.0) newrate=.01;
   if ( (age/rate)*count < 4096) llLinkParticleSystem(LINK_SET,sys);
   else {
       llInstantMessage(llGetOwner(),"Your particle system creates too many concurrent particles.");
       llInstantMessage(llGetOwner(),"Reduce count or age, or increate rate.");
       llLinkParticleSystem(LINK_SET, [ ] );
   }
}


feedback(integer status)
{
   if(status)      
       {
           updateParticles();
           if(debug) llSay(PUBLIC_CHANNEL, "Rosenblatt Fall an");
       }  
   else
       {
           llLinkParticleSystem(LINK_SET, [ ] );              //Partikel Stoppen
           if(debug) llSay(PUBLIC_CHANNEL, "Rosenblatt Fall aus");
       }    
}    



integer avacheck()
{
   list avatars = llGetAgentList(AGENT_LIST_PARCEL, []);         // Avatarliste holen
   integer anzahl;
       
   for (anzahl = 0; anzahl < llGetListLength(avatars); anzahl++) // Avatareabstande durchtesten
       {
           if (llVecDist(llList2Vector(llGetObjectDetails(llList2Key(avatars, anzahl), [OBJECT_POS]),0), llGetPos()) <= scandistance)  
               { return (TRUE);}                    // Schleife beenden, Avatar in Reichweite gefunden      
       }  
   return (FALSE);    
}



state aktiv                                            // Status: Partikelerzeugung
{
   state_entry()
   {
       llSetTimerEvent(efektdauer);
       feedback(TRUE);        
   }

   timer()                                            // Schleife für Überprüfung ob Avatar noch in Reichweite
   {
       if ( !avacheck()) { state default;}            // Niemand mehr da, abschalten
   }
   
   changed(integer changebits)                        // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}



default                                                // Scannen in standby Modus
{
   state_entry()
   {
       llSetTimerEvent(scantimer);                    // Partikelerzeugung abschalten  
       feedback(FALSE);
   }
   
   timer()                                            // periodicher Check ob Ava in Nähe
   {                
       if ( avacheck()) { state aktiv;}
   }
   
   changed(integer changebits)                        // Reset nach Region restart
   {
       if(CHANGED_REGION_START & changebits) { llResetScript(); }  
   }
}
Antworten }
Thanks given by: Manni , Wollex Baily2 , Sylvia Koeln , Tommy


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste