Call for Submission
NAB 2012 Best of the Best Show Reel
Submit your work today!
Theme color:
  • 1/3
You are here: Homepage /  Blogs /  Duncan's Blog / Volume displacement method for clouds using fluids
Volume displacement method for clouds using fluids
Posted: Aug 03, 2007
Category: Tutorials
Social Media:
Bookmark and Share
 
I was recently asked how to convert a cloud displacement map to bring it into Maya fluids. Displacement is rather incomplete for clouds.. even if one assumes the cloud bottom is flat, however it can look good in some cases. Also infrared images of clouds from space tend to nicely code for cloud height, because it gets cooler with altitude. Here is one of many sites that have nice infrared cloud images:

National Geophysical Data Center

2D Fluid Displacement method (shown above)

There are a few methods where one can import the data into a fully 3D fluid grid, although it is also possible to directly apply the 2d displacement image to a 2d fluid and volumetrically render it. The "useAsHeightField" toggle on a 2d fluid will interpret its opacity as displacement. It renders as a flat bottomed volume with continuous density between the bottom and the top or surface of displacement. The "pond" feature uses this toggle, but uses a surface render method. For clouds it is better to use a volume render method with self shadowing.

In the examples I've attached I've mapped a texture to the opacity and edited the opacity graph to get good shape on the clouds. If one instead wishes to use a map then instead make the opacityInput = density, and make the density grid static. Make the opacity graph the default linear 0-1 ramp to start with. Set the fluid resolution to your displacement map resolution, then use the fluid paint tool import function to load the image into the fluid density grid. One can then adjust the the opacityInputBias and transparency to get the best effect. Also the edgeDropoff can be used to soften the bottoms of the clouds( although it also softens all 6 boundaries of the fluids container ). The fluid's size "z" value will determine the maximum displacment while the opacity determines the displacement relative to the range. The transparency attribute determines how opaque the clouds are.

Here is a 2D fluid heightfield that uses noise on the opacity to create the clouds:
displacementClouds.ma (find this at the bottom)

Image Description: displacementClouds.ma (find this at the bottom)

Here is the same scene but with the addition of a second fluid for the atmosphere. (Create a 3D fluid and then select the SkyFog preset in the attribute editor)
displacementCloudsWithSkyFog.ma (find this at the bottom)

Image Description: displacementCloudsWithSkyFog.ma (find this at the bottom)

This next file uses a hurricane infra-red image loaded into a 2D fluid initial state for a more realistic cloud shape:
displacementHurricane.mb, fluid initial state (you'll find these at the bottom)

Image Description: displacementHurricane.mb, fluid initial state (you'll find these at the bottom)

Here is the same file but with some added procedural noise to give it more detail than there is in the fluid grid:
hurricaneDetailNoise.mb (you'll find this at the bottom)

Image Description: hurricaneDetailNoise.mb (you'll find this at the bottom)

To animate the fluid One can simple set the initial state to a rotating velocity and simulate. (make sure to set density buoyancy to zero) You could paint velocity with the paint fluids tool or use a vortex field. Another method that can be very controllable is to keyframe the rotation of a drag field that has a magnitude around 10 and inherit motion set to 1.0.
hurricaneDynamic.mb (you'll find this at the bottom)

Image Description: hurricaneDynamic.mb (you'll find this at the bottom)

3D Fluid Method

If you want to instead map a displacement to a 3d fluid grid there are a variety of possible methods, although they are generally harder to implement than the 2D method above and will require more memory.

First off you should create a fluid that has the resolution set to cloud image resolution in x and z and the y resolution set based on the relative height of the cloud layer. Adjust the fluid size to the desired cloud bank size, but make sure the size value is always proportional to the resolution. Thus for a resolution of 1000, 500, 10 one might have a size of 20.0, 10.0, 0.2. The total memory used will be proportional to xres*yres*zres.

Here are a couple of methods for initializing the fluid density values from the displacement image:

1. In the paint fluids tool Import the cloud image as density starting from the bottom fluid slice or layer(click on the light blue dial next to the fluid to set the layer.. the view initially rotates the layer unless on hit the lock icon). As one moves upward
import the same (displacement style) texture, but threshold it so that only the peak intensities remain. The import remaps the image based on the min/max values in the paint attributes block, so I think one could use this to do the desired thresholding by making the min negative.

2. Write a script that loops over the image pixels, getting the color using either bonus tools iffPixelCmd or perhaps using colorAtPoint on a file texture with the image. For each pixel do setFluidAttr on the voxels where intensity from the image would be considered height, so for a given pixel if the intensity was one, one would set the density of all the fluid voxels in that column. If the intensity was 0.5 one would only set the bottom half of the voxels in that column, etc..

3. Apply the texture as a displacement to a surface. Convert this displacement to polys. Then emit from this mesh into the fluid over a few frames moving the mesh downward during the emission until it is totally below the fluid.

4. Write a standalone program that converts the image to a fluids cache using the technique in #2 above.

A Dynamic Cloud texture

In some cases you may wish to texture a cloud layer on a planet yet dynamically animate it as a fluid. In this case one can simply apply a 2D fluid texture as a transparency and color map on a cloud layer shader, and initializes it with the paint fluids tool. This is useful when you need to have clouds wrap around curvature of the earth.
In order to post any comments, you must be logged in!
Newest users comments View All 15 Comments
Posted by jbturof on Jun 16, 2011 at 08:18 AM
Thanks much Duncan. I'll try that---and keep in mind what you said about the incompressible motion.
Sounds like this might be exactly what I needed!

Jeff
Posted by Duncan Brinsmead on Jun 15, 2011 at 04:49 PM
Also you might look into having a dynamic temperature grid, then emitting temperature and density into the simulation to drive the motion. It will get quite involved for the kind of simulation you describe. Check out cgtalk threads on fluids in the Maya dynamics section for some help.
Posted by Duncan Brinsmead on Jun 15, 2011 at 04:44 PM
The paint fluids tool is the one you use to load the image. This tool by default auto sets the initial state of the fluid after edits. If you look in the paint fluids tool options attributeMaps:import is used to bring in image data. when you paint a 3d fluid the brush is always working on a slice of the fluid, but there is stamp depth, which if large then the imported image will project down the entire fluid. ( or you could use different images for different slices ) In the options "min/max value" determines the min/max range the image is mapped to. You also can use the different operations and opacity when importing depending on how you want to apply the image. The initial state is saved as an old style fluids cache file and appears in a node that is created called initialState_fluidShape1 ( or your fluid name).

To push the fluid around with a field, assign the field to the fluid. Make sure the fluid has a dynamic density and velocity grid or it won't move. Also remember that the fluid solves for incompressible motion, so the motion may not be as you would think. (it is not like particles) Some motion like converging to a point is not allowed. Also note that some fields are applied to all fluid voxels uniformly while others like gravity are applied more in voxels with higher density.

Another way of giving a push would be to paint the initial state of the fluid velocity(paint fluids tool:velocity).
Posted by jbturof on Jun 15, 2011 at 04:23 PM
Hi Duncan.
I have two questions.
Can your method above of loading an IR image into the fluid's initial state be applied to a 3d fluid? Also...where would I find the initial state?--apologies...I'm still very new to fluids.
Second, If I wanted to connect an air field to a cloud and have that field distort the cloud, what might be a process for that? I attempted simply connecting them, set attenuation to 0 and pumped up the speed and magnitude but I still get no movement. Suggestions? Is adjusting the velocity and rotation the only way to achieve fluid movement?
I'm trying to simulate a mezzocyclone within a thunderstorm (anvil, rotation, etc).

Thanks!
Posted by Isaac Peral on Feb 21, 2011 at 08:44 PM
Sorry Duncan:
I was so obsessed in my clouds.
I noticed in your previous comment.
The sun is still pending.
Apreciated.