At the moment, when this article was written, latest build was 2.17.
API is one of the main feature of Magic Particles (Dev). API allows to reproduce special effects, made by Magic Particles, in your application. Special effects are processed by CPU. If your special effect has a large number of particles, your game is likely to slow down. You can see here the analogy with 3d models, which are used in games. A person creating 3d models for game, should understand, that if his model has too many polygons, it is not good. A video card cannot render 3d models fast enough. And in this way, game models need optimization, which minimizes a number of polygons. Such models are named low poly. Video card may easyly process them in real-time. By analogy, for special effects optimization is needed too. In this article, I will try to explain key moments of optimization for effects, created in program Magic Particles.
a) Size of textures
Actually, API doesn’t deal with particles rendering, because it was designed to be used with a lot of different renderers, it’s basically task for users. But however, I decided to begin exactly with the most important moment: don’t use large textures, if you can do without them.
When you make a high resolution texture like 512x512 pixels size and put it on particles of size 8x8, you are risking to lose a chance using special effect in your game. Don’t hope that some very good graphic engine will draw everything. There are no miracles. Same video card will draw everything and this video card has itself exact technical characteristic. In other words, throw away such a quality, which you cannot see on your screen. I found, that on my video card GeForce 6600 GT, FPS increases by three times, when I reduce textures from 512x512 to 256x256.
Currently Texture efficiency field was added in Magic particles, so user could estimate size of the texture for specific special effect. This field defines how close the size of textures matches the size of particles. It is calculated by dividing area of all particles to the area of all textures. Ideal value is 1. If number is less 1, then area of textures exceeds area of particles. In this case you can reduce textures in program visually, using Storage. Practically, if the number equals 0.1, it means, you can reduce the textures by about 10 times. If the number is more than 1, it means, that textures are smaller, than particles and, probably, you should increase them. Texture efficiency is determined with 4 numbers. The first number shows texture efficiency for current frame. The second number shows average texture efficiency, for all frames in the range from zero to current frame. The next 2 numbers show min and max, from the range where this average was measured.
Keep in mind, that special effect usually slows down because of rendering, but not because of calculation. In other words, API calculates everything for you, but when you begin to draw, it might happen, that video card draws too slowly.
b) It is not necessary to use textures with power of two sizes
It’s not a secret, that video card is adapted to work only with sizes of textures, which should be power of two, that is width and height of texture must have 4, 8, 16, 32, 64, 128, 256, 512 pixels ideally. However, API allows to create a texture atlas quickly, which may rather contain textures of nonstandard sizes. So it is not necessary to use textures of standard sizes. If you need a texture 50x34, then don’t increase it to 64x64. A new version of program makes a texture atlas directly from editor.
c) The automatic optimization of textures
In the first versions of program, texture could be kept and used in such a form, in which the user loaded it. Currently Magic Particles, during loading time of the texture, defines it’s “useful” area and automatically throws away everything that is out of this area. The "useful" area of texture is shown by a yellow rectangle.
“Useful” area is defined with alpha channel of texture, so "unuseful" area is where alpha channel equals to zero. There is no image and this lets to throw away a part of texture, as something unnecessary. But texture is shown without any modifications. It is as if nothing was deleted. Keep in mind, that this optimization doesn’t work, if texture has no alpha channel.
d) Storage of textures
You need to use Storage, in order to avoid texture duplicates. Remember, when you use texture out of Storage, it’s not efficient, especially for game developers, because such textures are duplicated in ptc-file. Notice, API will create the texture atlases, avoiding of unnecessary duplication of textures, but there is no sense to keep the textures “out of storage”. Use command: Edit->Move all textures to Storage, and all textures will be in Storage. There also might be a situation when textures are in the Storage, but are not used, so you can delete them with command: Edit->Delete Unused Textures.
2. Factors, accelerating/slowing calculations of special effect
a) Particles count. A number of particles is the most important factor, which affects the speed of calculation of special effect. Try to reduce the number of particles to minimum. It is not necessary to make special effect consisting of thousands of particles. The limit in games is about several hundreds of particles that are visible simultaneously.
b) “Refresh rate” and “Interpolation”.
These factors are tightly connected to each other, so I will consider them together. Refresh rate - a time step, with which special effect is processed, if it is equal to 30, then special effect is processed 30 times per second, and if it is 10, then it is only 10 times per second. This is very important, because the rarer processing of special effect happens, the better for the processor. But, if special effect is rarely processed, you may notice distortions and jerks of animations. Practically, “Refresh rate” is smoothness of the particles movement. Try to understand the following: all calculations of special effect happen with that rate, which is shown in field “Refresh rate”, that is special effect doesn’t change between updates. It means the less “Refresh rate”, the better for rate of calculation. For example, if you have 100 of particles and they are processed 30 times per second, this is almost the same, when you have 200 of particles, which are processed 15 times per second.
Let’s take a look at Interpolation mode. When you use this mode, you get position of particles in the moment time different from “Refresh rate”. For example, animation in modern 3d modeling graphic programs, is made usually through designation of key positions, that is when you move model from one place to another, you need to indicate only initial and final stage, intermediate stage is calculated automatically. The logic for "Interpolation" mode in MP is the same. I’ll explain it giving example: all calculations of positions of particles are always performed only with a step "Refresh rate" and these states are "key frames". But when you have two "key frames", it’s easy to calculate position of the particles between frames. It’s basically how it was implemented. Keep in mind, in this mode, memory usage will be increased by 20 bytes per particle, because it’s necessary to keep previous and subsequent state, but usually it’s not critical. Besides, the "Interpolation" mode allows to lower "Refresh rate" without a loss of quality. For instance, open the file demo.ptc and choose the special effect Salute. Turn off “Interpolation” (if it was turned on), and set “Refresh rate” = 10. The special effect starts moving with the jerks. Now, turn on “Interpolation” and the jerks disappear. So you have saved the speed of calculation of special effect by minimum 2 times, because now special effect is calculated 10 times per second, and not 30, as it was at starting point.
It’s very important, whether Interpolation mode will be used in the game or not. You need to find out this question in advance. If "Interpolation" is not used, it is desirable that "Refresh rate" was the same as for all special effects in the game. Otherwise, you cannot update them at the same time, and it is very uncomfortable for programmers. Also you should remember, that “Animate folder” works in the Interpolation mode in the editor.
Interpolation mode can be controlled by API.
c) The property “Create in portions”
By default it is set to "On" state. When this property is enabled particles are processed faster. If you would like to Disable it ( set to "Off" state ), keep in mind, you should do it only when “Creation rate for new particles” is less than 10 (or better around 1).
3. Memory saving
The complexity of processing of diagrams is in the fact that it is not trivial to define Y coordinate by X coordinate. Why does this happen? It is necessary to find the previous and subsequent points at first, and then, after receiving the formula of a straight or a curve between these points, to find out the appropriate point Y. It is not good, when a similar operation is constantly performed for every particle of the “red” diagram. So I have implemented following: before start of the emitter, all diagrams are pre-calculated with the certain step and all calculations stored in the array. Then diagrams are not used anymore, and all values are taken directly from this array. This approach gains a high speed for API working with diagrams. But… we have an important question: how should we select the length of array? There is additional property “Smoothness of particles properties changes (discrete of life)” on diagram “Life of particle, sec”. This number defines the length of arrays, in which the “red” diagrams are converted. In order to get smooth behavior of the particles, this number should be increased. For example, if particle is changing size significantly during lifetime, you should find out the value, at which this animation will be without jerks. If you write “Smoothness of particles properties changes (discrete of life)” = 5, that all “red” diagrams will be divided into 5 parts and the particle will have only 5 sizes. You will notice artificial animation, because of the abruptly change of particle size. In general, the greater the number you set, the smoother change will be. But… the arrays in memory will increase too. The numbers in the arrays is kept as floats (4 bytes). So, don’t write 5000 there, where it will be better to set 100.
4. A very important moment
Recently, I have watched such thing: I sent a special effect, which was made from a lot of small particles, with only 2 velocity vectors for all particles (not random). In other words, if one particle moves to the right, other should go to the left. And it seems, everything visually works correctly, but if you look inside, you find out, that direction of movement and speed of all particles is chosen randomly! In this way, if you need the specific direction of movement, it is necessary to set the specific corner (diagram “Emission direction”). A programmer may turn on the full randomness of the emitter in API, and in this case all directions of movement will be changed. Besides, nobody guarantees, that the order of random numbers will not be changed in the new version of program Magic Particles. In such case particles will not move in necessary direction and you may do nothing. Summary: if you need specific values for parameters - use them. If you have red and blue lines on the diagram, you will get the values from this range randomly. Turn off one of lines, and then everything will be accurate. If you want to be sure, that your special effect does not depend on random values, change field “¹ randomness”.
5. The color of particles
There are two ways of changing colors for particles.
à) Change color during life of the particles:
á) Blend base particle color with another color at the particle spawn time:
Always use only way 1; if there is no strong necessity to use way 2. Remember, if the diagram “Tint strength” is not constantly equal to 0, it means that the base particle color will be blended with color from "Tint strength" diagram, in the specified proportion. The additional calculations are needed for this operation and it is often unreasonable for using in games. Besides, the diagram “Tint strength” influences all types of particles inside the emitter and it is mainly useful for users, which don’t create games.
6. The feature of “Image” emitter
It will be very good, if the unused "black" area on the image will be as small as possible. The unused rectangular part of the image will be cropped in the new version of program. But you should know, why I am doing that way.
In order to create particles on useful area quite fast, I am creating array of texture coordinates. In other words, during runtime of the game only this list is needed, not the image. List initialization is dependent on the size of the texture. Bigger size - longer initialization. The property «probability» will increase the initialization time too, because of the algorithm complexity. Also, one of the most time consuming processes is property ’tint’. This property allows you to add color, taken from the image, to the base color of the particle. The percent of blending of these colors is again determined by the "Tint strength" diagram. Applying this method is often reasonable and looks interesting, because the particle may be painted in that color of image, in which it was created. However, firstly it demands additional calculations, secondly it is necessary to keep in RAM all image entirely in order to get the mixed colors quickly. And for example, if your image is black-white, this is unnecessary usage of computer resources. Applying the "Tint" property makes sense only for the colored image.
7. Visibility range
The field «Left position of visibility range» allows to animate the special effect from arbitrary point. Sometimes this is very useful. But special effect can not jump to 5-th second of animation instantly. The same calculations are done for these 5 seconds, but without rendering.
When this emitter will be launched in game, the same calculations will be needed to performed there. The wrapper, which is in Magic Particles, processes this moment as follows:
a) At first launch of the emitter, I do calculation of all animations in memory to the point where particles will start being rendered.
b) The result of calculation is saved to the file.
c) Next time, when this emitter is launched, all data is loaded from the file.
So, dispose “Left position of visibility range” closer to 0.
Calculation was done using Magic_EmitterToInterval1 property from API. Notice, that this property takes parameter speed_factor, which allows you to speed up calculation, but you will lose accuracy.
8. The blending of different types of the particles
In previous implementations, rendering was done in ordered way, sorted by particle type.
Currently, rendering is unsorted, blended. This happens for two reasons: firstly, 3D mode has particle sorting based on distance to the camera; secondly, you may intentionally force particles to be blended in 2D mode for receiving special visual effect:
Notice, that particles of smoke are blended with particles of fire on this image, and you may see visual uniformity. However, you may also notice, that particles of fire use the property “Intense” for glow, and particles of smoke don’t use this property. Video card can use only one of modes at the same time. And you have to stop the process of drawing when the special effect is drawn, to change mode. The field “Current DIP” on scene shows, how many times the mode of video card was switched during drawing of special effect.
It’s natural that the maximum drawing speed is achieved, when special effect is drawn in 1 pass.
9. Using the Viewer
There is possibility to create Viewer or Screensaver directly from editor without the help of programmer. Press CTRL+Q and you’ll see the window, which will offer to create Viewer. All emitters, which were loaded to the editor, will be in exe-file, and you can see the work of these emitters in conditions close to natural. Run exe-file and you can estimate performance of this special effect on your computer. The main parameter is FPS or frames per second. The more FPS is the better.