This page provides some details on how Phoenix FD works in 3ds Max.
Phoenix FD is a fluid dynamics simulator that is intended to create a wide range of effects including smoke, flames, liquids, and explosions.
Because simulation is a relatively slow process, it has to be precalculated. Otherwise it wouldn't be possible to interactively move the time slider or render. The result is saved to cache files. They are used in the rendering afterwards, as well as to add more detail to an already simulated effect.
The simulation is done in the background, and the user interface of 3ds Max remains active. You can change the parameters (except for a few initial core parameters) during the simulation and see how they affect it. The rendering (both Production and RT) is also enabled and you don't have to wait until the end of the simulation to see a single frame.
What is a Fluid Simulation and How Does It Work?
Everyone has an intuitive idea of what a simulation is, because we do them every day, trying to predict events in the near future and make decisions. For example if we have to cross the street, we try to predict where the cars will be, and we do this automatically without any complicated math. If you try to predict where a moving car will be after one second, a simple extrapolation is quite enough. The car can't change its speed too much in a second. But if you try to predict the car's position after an hour, the simple extrapolation won't work. We can only predict the future position of an object for short time intervals, where the velocity remains relatively the same. The longer the time interval is, the bigger the velocity change is, and the bigger the error of the estimated object position is. However, if we have some rule that allows us to update the velocity (for example we know the road and the speed restrictions), we can extrapolate for a short time interval, then update the velocity, and by repeating the same procedure step by step we can achieve plausible long term predictions.
The fluid simulation works the exact same way. The simulator extrapolates and updates velocity, evaluating new states of the fluid continuously. In most fluid simulation systems, the extrapolation phase is called advection, and the velocity update is called pressure projection. For the extrapolation we will use the term advection, but for the velocity update/pressure projection we will use the term conservation, because it is highly related to the fluids ability to keep its amount. The extrapolation time interval mentioned above is called simulation time step. In Phoenix FD the simulation time step is controlled by the Steps Per Frame (SPF) parameter, which is equal to the frame duration divided by the simulation time step.
Particle and Grid-based Simulation
There are two main approaches used in simulation systems:
The first one is focused on the matter. The mass, the color, the temperature, the coordinates, etc. are just properties of the matter and are associated to abstract pieces of the matter called particles. This is the concept of the particle based simulators, Phoenix FD uses this concept to calculate the liquids and the effects related to them: foam splash, mist, wetting .
The second approach is focused on the space. The mass, the color, the coordinates, etc. are just properties of the space, and are associated to abstract pieces of space called voxels or cells. This is the concept of the grid based simulators. Phoenix FD uses this concept to simulate the gaseous effects: fire, smoke, explosions. This method is better for smoke and fire related simulations, because it can achieve semitransparent and otherwise difficult results relatively easy. The grid can be viewed as a 3D bitmap, but the pixels are called voxels or cells. When Phoenix FD simulates, it repeatedly "repaints" the 3D image following certain rules. The more voxels there are, the slower the simulation runs. It's very important to understand the difference between the grid approach and the particle approach, because it's not just question of technical solution. Even if the simulation is perfect, you have to use very different methods to render the simulation results.
The Content of the Files Exported by Phoenix FD
The result of the simulation is a sequence of files called cache files. Each cache file has two sections: the grid content and particles. PhoenixFD uses its own file format that allows it to keep grid and particles in single cache and also additional values used to restore simulations starting from certain frame.
As we already mentioned, the grid is similar to a multi-channel 3d bitmap, but instead of colors, it contains physical values called channels (temperature, smoke density, velocity, etc.). There is only one grid in given file, but it can contain more than one channel. Unlike the grid, the cache file can contain multiple particle systems, for example foam particles and liquid particles, each of them with its own channel set. The particles are representing in the scene by hidden objects named in a specific manner. For example, the object representing the liquid particles of the simulator PhoenixFDLiquid01 is called "PG [Liquid] of system [PhoenixFDLiquid01]". These objects obey the 3ds Max standards for particle systems, allowing their content to be accessed by 3rd party software.
How to Set up a Simple Simulation
Phoenix FD 3.0 comes with a toolbar that contains ready Quick Setup presets for commonly used fluid simulations.
The minimal setup needed for simplest simulation includes 3 objects: simulator, source helper and some geometry.
- Create a simulator.
- Create a geometry object and place it inside the simulator.
- Create a source helper.
- Select the geometry in the object list of the source helper.
At this stage, the setup is ready. To begin the simulation, go to the "Simulation" rollout of the simulator and press start.
The simulation is performed in a box (called a grid) divided into small cells that contain the fluid's properties at their coordinates (temperature,velocity etc...). The minimal setup of the simulation core includes velocity and temperature as fluid properties of the fire/smoke simulation or velocity and liquid density for the liquid simulator, respectively. Depending on the core settings, one or more additional channels can be added and will be dragged along the fluid. These additional channels are:
- Particle ID
- Particle Age
- Particle Size
The RGB channel does not affect the simulation; it's just a helper channel that can be used in the rendering for texture mapping or directly as RGB value. The Wavelet channel must be exported only when wavelet turbulence must be applied to the simulation on a second pass. Particle ID channel is helpful to identify the same particle between the frames.
The core recalculates the grid content repeating three main actions:
- Interact with external objects.
- Move the fluid with respect to the velocity (Advection).
- Change the velocity due to the internal collisions in the fluid (Conservation). Conservation is the same process which makes the liquid in a syringe's needle to move forward when the plunger is pressed.
Depending on the core settings, one or more additional operations can be included in the process. These operations are:
Simulation Step (SPF)
Each simulation cycle calculates the future fluid state starting from the current fluid state. But how far apart should the new and the old fluid states be with regard to the timeline? This time interval is called a "simulation step" and is one of the most important values for the simulation. Obviously, if we try to calculate too far in the future (a big simulation step), the results will not be plausible. On the other hand, if we calculate some very near moment (a small simulation step), we have to repeat the calculation many more times to cover the entire simulation interval, which decreases performance and also introduces some specific distortions.
Determining the optimal simulation step might look like a complicated task, but in fact it is not. In most cases, the optimal simulation step is related to the time the fluid takes to travel a few grid cells. Since a high number of Steps per Frame (SPF) can slow down the simulation significantly, it is best to start off with a step value of 1 and increase it only if the fire/smoke simulation produces grain artifacts or liquids refuse to keep their volumes. If the fluid has to move fast through the container, it would be better to use a higher SPF. Also, if you are happy with the way a low-res simulation works and want to increase the grid resolution, you need to adjust the SPF accordingly. If you double the linear resolution, you have to double the SPF too. But since the grid is three-dimensional, you need to double the SPF if you increase the voxel count 8 times. Note: The SPF value can not be a fractional value; it has to be a whole integer.
The burning process requires Fuel and Smoke as additional channels (they will be included automatically). Like in the real world, the burning process converts the fuel into smoke and produces some heat which expands the fluid. There is no separate channel for oxygen, however it is taken into consideration using the smoke and the fuel to be calculated. The relation is oxygen=1-fuel-smoke. The energy of the fuel controls how much heat will be produced and the inflation/expansion rate controls how fast the ignition will propagate.
For convenience the second parameter is just called "Propagation", but advanced users should keep in mind that the real meaning of the parameter is inflation/expansion rate.
The vorticity confinement keeps the small turbulences alive. Why do we need this kind of correction? The fluid transport (advection) moves the grid content from cell to cell according to the velocity. In a traditional case, the movement of any given point is not an integer count of cells. This causes the content of the cell to be mixed with the content of the neighboring cells during the advection. As a result, the fine details in the velocity tend to disappear. Amplify them to make the fluid more turbulent.
There are three types of external objects that can interact directly with the simulator:
In every simulation step, all the nodes in the scene are enumerated and processed whether or not they belong to one of the above mentioned groups and have permission to interact with the simulator.
All geometry objects in the scene are considered to be rigid bodies. They can affect the simulation in three different ways:
- When the body is not selected as source but interacts with the simulator, the cells inside the geometry are frozen and the velocity of the surface cells is determined by the movement of the body.
- When the body is selected as source, the cells inside are frozen and the surface cells are set with the parameters of the source. The velocity is calculated according the discharge and the body's movement.
- When the body is selected as source, but doesn't interact with the simulator; the fluid inside the geometry is directly affected according to the Emit Mode of the simulator.
Another Phoenix simulator can also be used as Rigid body. In this case, the Surface Channel is used to determine the surface.
The particles can interact directly with the simulation only as sources, depending on the Emit Mode (Volume Inject or Volume Brush) of the Fire Source | PHXSource. The velocity of the injected fluid is the velocity of the particle, which allows the fluid to be involved in the particles' motion.
The forces change the velocity of the fluid in two different ways:
- If the force is a Gravity force, the acceleration is calculated directly using the buoyancy of the fluid. If the buoyancy is negative, the fluid accelerates toward the gravity force, otherwise it accelerates away from the gravity force.
- If the force is not Gravity, the fluid is accelerated toward the force. The magnitude of the acceleration is determined by the magnitude of the force.
Resimulation is the process of simulating over an existing simulation, which is called a base simulation. The base simulation must be processed first, and its Velocity channel must be exported. Then, to enable the resimulation, the Enable option in the Resimulation rollout must be checked. While this option is enabled, the simulator works in resimulation mode (i.e. all simulator functionality is now related to the resimulation).
The resimulation can affect the grid content and the particles separately. If only the grid is resimulated, the particles will be directly copied from the base simulation. If only the particles are resimulated, the grid content will be directly copied from the base simulation. Both grid content and the particles can be resimulated at the same time.
The resimulation process uses the velocity force of the base simulation to achieve the same flow of the fluid. This force can be resized if the user wants to increase the resolution when resimulating. There are two methods to resize the velocity force: interpolation and wavelet turbulence. The second method tries to add high frequency detail that is lost with simple interpolation, but it requires that the base simulation exports a special "Wavelet" channel and "UVW" channel in addition to the regularly exported channels.
Since the resimulation can do sub-steps, it must do conservation of the velocity force on its own. However since this conservation is valid only inside a single frame, the global flow will not be affected, and lower conservation values can be used, which can greatly increase the overall simulation speed.
When resimulating, almost all simulator parameters can be changed (for example the SPF limits, advection step, time scale). However this can produce a flow of the fluid that is different from the original.
The restore function works with resimulation cache, even if the Velocity channel is not exported. However the base cache must be preserved.
Here are examples of what can be achieved with resimulation.
- Increase the resolution of an existing fire/smoke simulation, preserving its general flow.
- Add new channels/change source parameters of a fire/smoke simulation. Note that you may not get a physically accurate result. For example, with non-uniform conservation, the temperature affects the velocity.
- Increase/decrease the amount of drag particles, without doing a full simulation.
- Add foam and splashes, tweak parameters without fully simulating the liquid again.
Phoenix FD registers itself as a global environment volumetric, except when working in Geometry Mode. The global volumetric takes care to blend properly all Phoenix instances in the scene (simulators and foam/splashes). However for overlapping with other volumetrics, geometry mode is recommended.
Channels, Diagrams and Gradients
After the simulation, cache files containing the exported physical channels are produced. In the real world, the connection between the physical quantities and the visual appearance is well-defined. However, for more flexibility in Phoenix FD, the user is allowed to choose how the render elements depend on the physics. For example, in the real world, the temperature determines the emissive color; however, in Phoenix FD, the velocity can be set to determine the emissive color instead of the temperature. The physical channel used to determine any given render element is called a source, and the dependence between the physical quantity and the render element is determined by tables called palettes. For the rendering of the volumetric content, three render elements are calculated for each point: emissive color, diffuse color, and opacity (alpha). To calculate each of them, the shader performs the following steps:
- Determines which physical channel is used as the source.
- Samples the input data in the shaded point to determine the value of the source channel.
- Passes the value of the source channel through the palette to obtain the value of the render element.
The control over the above mentioned process is arranged in Render Fire, Render Smoke Color, and Render Smoke Opacity rollouts where the user can choose the source and the palette for each channel. For the emissive color, both a diagram and a gradient are used, because–as opposed to the diffuse color–it can be outside the range 0-1. When this happens, the gradient will appear saturated. For each render element, the user is also allowed to select a texture map as the source channel. In this case, the palette is skipped and the sampled color is used directly.
Smoke Opacity vs. Fully Visible Shading
There is a well-defined connection between the transparency and the emissive light in the real world. For smoke (diffuse light), the connection is pretty clear and everyone has intuitive sense of how it works. For the emissive light, however, most of the people will give the wrong answer when asked, "Is a smokeless fire fully transparent?" The common, yet wrong, answer is, "Yes it is. If there is no smoke, the flame is fully transparent and will cast no shadows." However, the correct answer is "No, the fully transparent gases cannot emit any light, even if they are hot enough." This is why acetylene flame is less bright than a candle, despite its higher temperature. It just produces less smoke. However, this way of shading can seem strange and inconvenient, because there is no clearly separated control over the smoke and flame. Be careful when trying to achieve denser smoke, because the result can be an undesired brighter flame. For this reason, Phoenix FD provides different modes of shading: physical and detached. This is controlled by the Fire Opacity Mode parameter in the Fire rollout. In Fully Visible mode, the emissive part is fully independent of the transparency and you are not obligated to keep in mind the aforementioned connection. In Use Smoke Opacity mode, the smoke's alpha controls the Fire's opacity. There is also the Use Own Opacity mode where the fire has a separate opacity curve that can be adjusted independently from that of the smoke.
The Surface Channel
Some rendering techniques (like solid rendering, displacement, etc.) require a separate channel to work with, and for this reason the Surface channel is provided. Most of them use the Surface channel to calculate an implicit surface from its content, using the following rule: all the points with a value above given threshold will lie inside the surface and all the points with a value below the threshold will lie outside the surface. The Mesh Mode gives the best look over the whole concept, because it makes the surface visible.
In this mode, the appearance of the content is exactly like in the Volumetric Mode, except for the ability to blend with other overlapping volumetric objects. However, it is slower to render and takes more memory. Also it requires the Max. transp levels in the Global Switches rollout in the V-Ray Render Settings to be increased.
This mode is used to achieve mirage effects and heat haze. In this mode, the ray traced in the volume changes its direction at each step according to the content of the Surface Channel. It may appear that this mode is similar to pure geometry mode, but it is not. The shading is more similar to a V-Ray refractive material than the shading in volumetric mode or pure geometry mode. As with the shading of refractive materials, the alpha is set to 1 for the rays intersecting the simulator's grid.
This mode produces a solid object with a sharp surface, determined by the Surface channel, and can be shaded using any material.
There are two direct methods that can be used to add fine details in the shading. In order to enhance the realism of the movement of small details in the fluid, V-Ray comes with a Particle Texture called Particle Texture | PhoenixFDParticleTex. When used in combination with a particle system driven by a Phoenix Simulator, the particle texture is capable of properly animating the small details along the fluid surface.
This is the common way used in the fluid systems to add fine details. In the Render Fire, Render Smoke Color and Render Smoke Opacity rollouts is a parameter called Modulate near the texture slots for each render element. When enabled, the corresponding render element will be multiplied by the value of the texture map, except in the case when a texture is selected as the source channel.
This technique is more sophisticated than texture modulation and produces a significantly better result. The idea of displacement is similar to the usual geometry displacement, where the surface is displaced along its own normals at a distance determined by a texture map. The nearest point of the surface as specified by the Surface channel determines the direction for the displacement.
Surface Driven vs. Volumetric Displacement
The displacement in Phoenix FD works by shifting the point of sampling with an offset, the direction of which is determined by the gradient of the effects channel while the distance is determined by the brightness of a given map. There are two different modes used to sample the aforementioned map, switched by a checkbox in the rendering rollout. If the checkbox is NOT checked, the map is sampled at the point of shading, and we call this "volumetric displacement". If the checkbox is checked, the coordinates are first projected over the surface as determined by the effects channel. The point of projection is then used as map coordinates. We call this "surface driven displacement." Surface driven displacement is slower and requires some initial calculations, but it keeps the topology of the iso-surfaces. Volumetric displacement is faster, but tends to produce island-like formations if the displacement value is too big. Beside performance, volumetric displacement has one more important advantage: it does not require the distinct surface of the effects channel. Therefore, it will work fine in scenes where surface-driven displacement produces flickering.
Example: Surface Driven vs Volumetric Displacement
Surface driven displacement
Note the small islands floating above the original surface.
Foam and Splashes
The PhoenixFD solution for creating foam and splashes is particle based and is achieved by two relatively separate features - a foam/splashes particle simulator and a foam/splashes particle shader. The particle simulator is embedded in the PhoenixFD Simulator node and exports its content via PhoenixFDPGroup nodes, supporting position, velocity, size and id channels. The particle shader is designed as a separate component: PhoenixFDFoam. This component can render PhoenixFDPGroup and any standard particle system that exports position, size and velocity channels.
Particles of the PhoenixFD Simulator
There are several particle types that the PhoenixFD Simulator exports:
The birth of particles can be performed automatically (for foam and splashes) by a user source (see Fire Source | PHXSource) or by a script. When automatic birth is used, the simulator calculates a "birth potential" for each cell and compares this potential with the birth threshold set by the user. If the potential is above the threshold, the simulator creates new particles in the quantity specified in the "birth rate" parameter, in thousands per cubic scene unit. Both foam and splashes are born in this way; the only difference is how the "birth potential" is calculated. Additionally, when a splash particle hits the water surface, foam is automatically created.
The simulation of the particles is very different for each type. The simplest one is the "drag". This type of particle simulation generates particles that are just dragged with the fluid. This is much like the PhoenixFDForce operator for the standard particle systems but much more efficient: you can drag a million particles in few minutes. The second type (by complexity) is the splashes type. The splashes are just left in free fall until they hit some object or the water surface. The free fall is not the simplest one, it is affected by the movement of the air (do not forget that Phoenix simulates the air too, not just the liquid!) and the air-splashes interaction is controlled by the air friction parameter. The most complicated type is foam. The foam particles interact not only with the fluid, but with each other as well. This interaction produces a repulsive force when the particles are too close, and an attractive force when they are not, ensuring the foam's consolidation. This process is the most expensive one and is controlled by the B2B interaction parameter. When only surface foam is needed, the aforementioned process can be switched off by setting the parameter to zero.
Rendering of Foam and Splashes
The Particle Shader | PHXFoam node can render the particle systems in several different ways - as separate bubbles/droplets, as points, or as fog. In fog mode, the bounding box of all particles is calculated and a grid based shader is constructed using the bounding box and the fog resolution parameter. This mode is most suitable for surface foams, when the grid height is relatively large and the particle count is huge. The other mode (particle-based shading) is more complicated and interesting; it allows us to achieve a larger variety of effects. One reasonable question about this mode is why we need it, when one can render each particle as geometry with the proper material instead. There are several advantages, but the most important one is the ability to convert the scattering into diffuse color, which gives the natural bright appearance of the foam and the splashes. Another important advantage is cellular mode, which allows shading of close-up foam.
There are three different modes of shading for spherical particles - bubbles, cellular, and splashes. In each mode, a particle is represented as a sphere with a radius equal to its size and with certain optical properties. The "bubble" and "cellular" modes are intended for foam rendering and have the same optical properties of the surface. They differ in the geometry representation only - bubble mode uses simple spheres, whereas cellular mode builds polyhedron-like cells, similar to real foam. The cell walls are not flat, but slightly curved, which provides a more realistic appearance.
Example: Rendering of Foam and Splashes