
 |
 | |
Rune's Particle System v1.01
for POV-Ray 3.5
|
|
Water, smoke, fire and sparks are just some of the uses of Rune's Particle System. With a generic and non-specialized engine, the system makes it easy to customize the simulation to a wide range of uses.
I sincerely hope you have fun with this package! If you have any problems with it, I would like to hear about it. Also, if you have any comments, questions or enhancements, please contact me!
|
Contents
|
|
|
Using the system
|
|
The system is used by first including the particle.inc include file, then specifying all the options and the particle_element macro and lastly call the particle system. Here the order is described:
-
// 1) include particle system include file
#include "particle.inc"
// 2) define settings
#declare particle_start = 0.0;
#declare particle_end = 1.0;
#declare particle_cyclic = off;
#declare particle_steps = 100;
...
// 3) define the particle_element macro
#macro particle_element () ... #end
// 4) call particle system
particle_system ("my_particle_system")
// If you want one more particle system in your scene, go to step 2.
-
Also see the quickref.pov scene file which has all options specified.
Note that the particle system uses file I/O to write the particle data to files in between the frames of an animation. These files have a .data extension and can safely be deleted once an image or animation has finished rendering. The more particles you use, the larger these files will be. However, in most cases, the sizes of the data files will be insignificant. The .data files will always be written to the same folder as the scene file itself.
|
Clock settings
|
|
The clock settings control how the particle system works with regard to the clock variable in POV-Ray. Remember that all #declared particle system settings must remain constant during an animation. All settings are optional. When a setting is not specified, the default setting will be used, if there is one.
- particle_start, particle_end
- The clock values defining the time interval in which the particle system is active.
Default: #declare particle_start = 0.0; #declare particle_end = 1.0;
- particle_cyclic
- Setting this option to on makes the particle simulation cycle in the time interval defined by the particle_start and particle_end values. Note that this will make the first frame of the animation parse very slowly, because the system has to calculate particle activity far back in time.
Default: #declare particle_cyclic = off;
- particle_steps
- This value specifies how many calculation steps per clock value are performed. Lower values parse faster, while higher values lead to more precise results. To find out if you use enough steps, try to render the animation with only half as many steps as before. If the result differs noteworthy, too few steps are used. If on the other hand you render the animation with twice as many steps and the result is practically the same, then you are using enough steps, or maybe even more than what is necessary.
Default: #declare particle_steps = 100;
|
General particle settings
|
|
The general particle settings control how many particles there are and how long they last. Remember that all #declared particle system settings must remain constant during an animation. All settings are optional. When a setting is not specified, the default setting will be used, if there is one.
- particle_frequency
- This value specifies how many particles are emitted per clock value.
Default: #declare particle_frequency = 100;
- particle_life
- This value controls how long time in clock units a particle lasts before it disappears.
Default: #declare particle_life = 1.0;
- particle_lifeturb
- This value controls the amount of randomness used for the life length of each particle. 0.0 is no randomness and 1.0 is 100% randomness.
Default: #declare particle_lifeturb = 0.0;
- particle_seed
- This value is the seed of all randomness in the particle simulation.
Default: #declare particle_seed = 123;
- particle_maxnumber
- If specified, this value defines the maximum number of particles allowed at a time. When not specified, the system will calculate the number automatically, and most of the time it does it effeciently. But if the particle_emitting option is only set to on a little bit of the time, then the automatic calculation will predict a too large number, which will make the parsing slower, and in that case you can specify it manually if you want.
Default: #declare particle_maxnumber =
ceil(particle_life*(1+particle_lifeturb)*particle_frequency+1)
|
Environment settings
|
|
The environment settings control the air, wind and gravity in the particle simulation. Remember that all #declared particle system settings must remain constant during an animation. All settings are optional. When a setting is not specified, the default setting will be used, if there is one.
- particle_drag
- This value specifies the air resistance. The higher value specified, the more the particles will be slowed down by the air, or follow the wind if there is any wind. The default is no air resistance.
Default: #declare particle_drag = 0.0;
Finding the right drag value can seem difficult, but if you know what the terminal velocity of the particles should be, then you can calculate the drag force using this formula (where gravity is the length of the particle_gravity vector):
terminal_velocity = sqrt(gravity/drag)
Which can be rewritten to:
drag = gravity/(terminal_velocity^2)
- particle_transfer
- This value controls how much kinetic energy is transferred to the particles. It controls how much movement the particles gain from the particle emitter if the particle emitter is moving. 0.0 is no movement and 1.0 is 100% movement. The default is 0.0. However, if a realistic simulation is desired, the value should be set to 1.0, and the particle_drag option should be used to slow down the particles instead. The particle_transfer feature only detects movements of the particle_emitter setting, not movements of the optional particle_emitobj setting. Read more under the emitter settings.
Default: #declare particle_transfer = 0.0;
- particle_gravity
- This user-defined macro controls the gravity force that the particles are influenced by. It has two parameters: Clock and Point. With these two parameters you can make gravity which changes over time or which is different for different points in space. The macro must return a vector. A typical vector is -y or some multiple of that like >-5*y, but any vector can be used. It is important that the vector is only dependent on the Clock and Point parameters and not on any external values such as the clock variable.
Default: #macro particle_gravity (Clock,Point) <0,0,0> #end
- particle_wind
- This user-defined macro controls the wind that the particles are influenced by. It has two parameters: Clock and Point. With these two parameters you can make wind that changes over time or is different for different points in space. The macro must return a vector. The wind has no effect if the particle_drag option is set to 0.0. It is important that the vector is only dependent on the Clock and Point parameters and not on any external values such as the clock variable.
Default: #macro particle_wind (Clock,Point) <0,0,0> #end
|
Emitter settings
|
|
The emitter settings control the particle emitter, from which the particles are emitted. There are several settings that control the directions in which the particles are emitted. When more than one of these options are set, the direction vectors are simply added together. All settings are optional. When a setting is not specified, the default setting will be used, if there is one.
- particle_emitter
- This user-defined macro controls the location point of the particle emitter. It has one parameter: Clock. With this parameter you can make the emitter location move over time. The macro must return a vector. It is important that the vector is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: #macro particle_emitter (Clock) <0,0,0> #end
- particle_emitting
- This user-defined macro can be used to turn on and off the particle emitter over time. It has one parameter: Clock. The macro must return a boolean value which is either true or false. For example the expression (Clock<0.5) will turn off the emitter when the clock value reaches 0.5. It is important that the expression is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: #macro particle_emitting (Clock) on #end
- particle_emitvect
- This user-defined macro controls the direction in which the particles are emitted and also the thrust with which they are emitted. It has one parameter: Clock. With this parameter you can make the emitter direction move over time. The macro must return a vector. It is important that the vector is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: #macro particle_emitvect (Clock) <0,0,0> #end
- particle_emitturb
- This user-defined macro controls the turbulence added to the directions in which the particles are emitted. It has one parameter: Clock. With this parameter you can make the turbulence vary over time. The macro must return a float. It is important that the float is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: #macro particle_emitturb (Clock) 0.0 #end
- particle_emitobj
- This optional user-defined macro can be used to make the particles be emitted from an object instead of a point. The particles are emitted from the surface of the object. It has one parameter: Clock. With this parameter you can move the emitter object over time. The macro must return a solid object. It is important that the object is only dependent on the Clock parameter and not on any external values such as the clock variable. The particle_emitobj object will automatically be translated by the point specified in the particle_emitter setting. So either the particle_emitobj should be centered on the origin all the time, or else the particle_emitter should be set to <0,0,0> all the time. Also read about particle_transfer in the environment settings.
Default: none. If macro is not specified, a regular point emitter is used.
- particle_emitobjn
- When the particle_emitobj macro is defined to create an emitter object, the particle_emitobjn macro can be used to make the particles be emitted in the direction away from the emitter object. They are then emitted according to the normal of the surface of the emitter object. The macro has one parameter: Clock. With this parameter you can make the emitter direction move over time. The macro must return a float. This float controls the thrust with which the particles are emitted away from the emitter object. It is important that the float is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: #macro particle_emitobjn (Clock) 0.0 #end
|
Collision settings
|
|
The collision settings control what happens when particles collide with objects. Remember that all #declared particle system settings must remain constant during an animation. All settings are optional. When a setting is not specified, the default setting will be used, if there is one.
- particle_blockobj
- This is the object that the particle simulation performs collision detection against. If this option is not specified, collision detection is turned off.
Default: none. If object is not specified, collision detection is turned off.
- particle_bounce
- This value controls how much particles bounce when hitting a surface. 1.0 is 100% preservation of kinetic energy and 0.0 is no bouncing.
Default: #declare particle_bounce = 0.5;
- particle_bounceturb
- This value controls how much turbulence is added to the direction in which the particle bounces. When set to 0.0 the particles bounce perfectly like billiard balls and when set to 1.0 the particles bounce in random directions.
Default: #declare particle_bounceturb = 0.5;
- particle_friction
- When particle_friction is set to 0.0, then the movement tangental to the surface at a collision is not reduced. When particle_friction is set to 1.0, then the movement tangental to the surface is reduced equally much as the movement perpendicular to the surface, which is controlled by the particle_bounce variable. Generally, a low particle_friction value makes the particles flow better on surfaces, while a high particle_friction value makes the particles stop faster.
Default: #declare particle_friction = 0.0;
- particle_bounceoffset
- This value is used to avoid errors in the particle collision detection calculations. It controls how much a particle should be offset away from the surface when a collision has happened. By offsetting the particle a little bit away from the surface, it is avoided that the particle falls through the surface. The value should be small enough that it cannot be noticed in the animation, but if you notice particles falling through surfaces, you may consider increasing it.
Default: #declare particle_bounceoffset = 0.01;
- particle_killobj
- This optional user-defined macro can be used to make the particles disappear if they get inside the space occupied by a specific kill object. It has one parameter: Clock. With this parameter you can move the object over time. The macro must return a solid object. It is important that the object is only dependent on the Clock parameter and not on any external values such as the clock variable.
Default: none. If macro is not specified, there is no kill object.
|
The particle_element macro
|
|
The particle_element macro is used to control what the particles actually look like. Whether you want water, smoke, sparks or something different is a matter of defining the right particle_element macro. You are basically just given some variables which you can the use as you wish to create the particles. Unlike in the other user-defined macros, you may also refer to the clock variable in the particle_element macro. The particle_element macros has no parameters and it is you who decide what it returns, but usually it is an object. The available variables are described here:
- p_id
- A unique integer id number for the particle.
- p_random
- A random number between 0 and 1 assigned to the current particle. If you need a random number, use this one, as in an animation you cannot rely on a regular random stream. If you need more than one random number, base them from this one, or from the p_id value.
- p_location
- The current location vector of the particle.
- p_direction
- The current direction vector of the particle. Speed can be derived from this using vlength(p_direction).
- p_life
- The predicted age of the particle in clock units. In other words, the time from it was born till it will die.
- p_age
- The current age of the particle in clock units.
- p_birth
- The clock value where the particle was born. If particle_cyclic is turned on, the p_birth value can be higher than the current clock value.
- p_state
- The age of the particle expressed in a value that goes from 0.0 to 1.0 from the particle is born till it dies. Same as (p_age/particle_life).
- p_rotate
- A rotation vector which will make the z direction of the particle point in the direction that the particle is moving.
-
The particle_element macro can be put in an include file and called from different scene files. This particle system package contains several such include files with custom particle_element macros. Look at the files expl.inc, fire.inc, glitter.inc, glow.inc, smoke.inc, and water.inc to learn how they are used.
|
Calling the particle system
|
|
After all settings have been specified, the particle system can be loaded by calling the particle_system macro:
particle_system ("system1")
The string passed to the macro can be anything and is only used to identify the system and to name the data files where the particle data is stored in between frames. This is particularly useful if you have more than one particle system in your scene, in which case they must have different names so that they don't get mixed up. It also means that in the message windows where the debug messages are shown, you can see which statistics belong to which systems.
The particle_system macro will do all the calculations and call your user-defined particle_element macro for each active particle. This means that if you want all your particle objects to be placed inside a union, the particle_system macro should be called from within that union:
-
union {
particle_system ("my_particle_system")
}
-
Similarly, if your particle_element macro creates a blob element, you should place the particle_system macro inside a blob object:
-
blob {
threshold 1.0
particle_system ("my_particle_system")
texture {My_Water_Texture}
}
-
If no particle_element macro is defined, the particles won't show up unless you use the Load System feature to create the particles.
|
Loading a system
|
|
Normally the particle_element macro is used to create the particles, but if you are an advanced user, in some cases you may need more control over how the particles are created. For this reason it is possible to load a system that has been defined. The load_system macro and load_particle macro is used for this. The macros should be used as shown here:
-
#declare Number_Of_Particles = load_system ("system1");
#declare Counter = 0;
#while (Counter<Number_Of_Particles)
load_particle(Counter)
// Do things with the particle data here. Available data:
// p_id, p_random, p_location, p_direction, p_life,
// p_age, p_birth, p_state, p_rotate
#declare Counter = Counter+1;
#end
-
The load_system macro takes the name of the system as input. The macro loads the system into memory and it also returns the number of currently active particles that are in the system. The load_particle macro calculates the data for a particle.
After having loaded a particle, you have access to the same data as you have in the particle_element macro. Please refer to the section about the particle_element macro for details about that data.
Note that since particles are created and destroyed all the time, the same counter value will not always load the same particle. If you need a unique integer value which identifies each particle, use the p_id variable which was made for this purpose.
|
Questions and answers
|
|
Please read this section before sending me questions. If you have a question not listed here, feel free to contact me.
- How can I make a conical emitter / a spray emitter?
- There is no special emitter type designed for this, but you can just use the particle_emitvect setting together with the particle_emitturb setting to have the particles emitted in a conical, spray-like fashion.
- Can I move the particle_blockobj around in an animation?
- No. It is not supported in this version, but may be supported in future versions.
- How can I have one wind vector of for example <20,0,0> for particles lower than y=5 but no wind for the other particles?
- You can do something like this:
#macro particle_wind (Clock,Point)
#if (Point.y<5) <20,0,0> #else <0,0,0> #end
#end
- How can I simulate atmospheric turbulence?
- You can use the vturbulence() function in POV-Ray in the particle_wind() macro. For example:
#macro particle_wind (Clock,Point)
Amount*vturbulence( Lambda, Omega, Octaves, Point*Frequency + Speed*y*Clock );
#end
Where Amount, Lambda, Omega, Octaves, Frequency and Speed are constants. It's not a perfect method, but try to tweak it and see if you can get it working to your liking.
- The media feature in POV-Ray is used to render particulate matter. Is your particle system related to this?
- Not directly. In this particle system, each particle is only a point in space. Over time, the points are affected by forces such as gravity and wind, which make the points move, and they can also be set to bounce or glide upon collision with certain surfaces. You can place an object filled with media at the location of each particle, but you can also place any other object there, so the particle system is not directly related to the media feature in POV-Ray.
- The particles are emitted in small groups. How can I avoid that?
- Try to increase the particle_steps. If it doesn't help no matter how much you increase the particle_steps, then one of your emitter settings are probably dependent on external variables, which is not allowed. They must only be dependent on the Clock parameter.
- Why can't I fill an object with particles, for example a glass of water?
- See the next question.
- Can I get the particles to interact with each other?
- No. This particle system does not support particle interaction. It would be very difficult to implement in a satisfying way in a system aimed at so different uses as this system is. Particle interaction is better suited for more specialized systems that are aimed at specific goals, like for example simulating liquids. Besides, particle interaction would not be compatible with all features of this particle system, such as cyclic animation.
|
Contacting the author
|
|
- If you have questions, comments, bug reports etc. or if you just want to tell about something you've made using this utility, please contact me through my website at
- http://runevision.com
|
Terms of use
|
|
Rune's Particle System v1.01 for POV-Ray 3.5
Copyright (C) 2002 Rune S. Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The above are the only terms you have to follow. However, I would be very thankful if you would consider helping me and supporting my work as described below.
- Give credit
If you make any images or animations using my particle system, I would appreciate it if you would give me credit where due, including both my name (Rune S. Johansen) and a link to my web site.
If you use my particle system in the creation process of images or animations for the Internet Ray-Tracing Competition located at http://www.irtc.org, I would also appreciate such credit written in the text file accompanying the entry.
- Donate
I have made my particle system available for free, for everyone to use. However, if you find it to be a valuable tool in your work, I hope you will consider making a small donation. This way you can help support the further development of free utilities, in which I invest so much of my time. You can read more about the donation options on this page:
http://runevision.com/welcome/donate/
- Contact me
I also always appreciate to hear from people who use the utilities I have made available, so if you have any comments, questions, or problems, please contact me, because I'd like to hear about it! (See contact information above.)
Regards,
Rune S. Johansen
|
|  |