RSS< Twitter< etc

Creating Snow Cover Using Frost and Krakatoa

Introduction

The following tutorial was inspired by this CGTuts+ Tutorial by Cristian Pop, which on itself was inpired by the SnowFlow commercial script by Zwischendrin/48design.

It was presented as part of the Frost and Krakatoa Master Class at the End User Event 2011 in Utrecht, The Netherlands on June 30th, 2011.

The main goal of this demo is to underscore the difference between History-Dependent Particle Simulation in Particle Flow and Histroy-Independent Particle Channel Editing using Krakatoa MagmaFlow. Both approaches can use FROST as the meshing solution instead of the 3dsMax' BlobMesh or 3DAliens' PWrapper.

Note that while this demo requires a commercial license of FROST, it does NOT require a Krakatoa license - you can use the free Evanuation version of Krakatoa for the Magma channel editing at no additional cost!

 

Overview

In this demonstration, we will create some geometry, produce some particles using the Krakatoa PRT Volume object, use MagmaFlow to move the particles to the surface of the geometry objects, then delete particles dynamically based on the angle between the surface normal and the world up vector to make the snow stick differently. The particles will be meshed using FROST.

 

Creating The Base Scene

Fist, let's create some geometry to drop the particles onto. We will use approximately the same setup as in Cristain Pop's tutorial mentioned above - a Torus Knot on a Cylinder: 

  • Create a Cylinder standard primitive with Radius 50.0 and Height 20.0 anywhere in the scene. (the location of the object does not affect the final result in either the PFlow or Krakatoa+Frost setup)
  • Increase the number of Cylinder Sides to 36 to inprove its appearance.
  • Create a Torus Knot extended primitive with Base Curve Radius 25.0 and Cross Section Radius 6.0.
  • Use the Align tool to align the bottom Z of the Torus Knot to the top of the Cylinder, then Center the Pivot of the Torus Knot to the Pivot of the Cylinder:

 

Creating the Particle Emitter

We will use a Circle shape and a Krakatoa PRT Volume object to emit the particles.  

  • Create a Circle shape with a Radius of approx. 55.0 units.
  • Align the Circle shape to the Cylinder, then move the Circle up to about Z:100.0 (the exact location does not matter as long as it is completely above the Torus Knot)

Now let's create some particles within the Circle shape:

  • With the Circle shape selected, go to the Krakatoa menu in the 3ds Max Main Menu bar and select the  "Create PRT Volume object(s) from selected Object(s)..." item.

Note that we could have used ANY geometry shape to distribute the particles, but using a Circle shape demonstrates nicely that the PRT Volume does NOT require CLOSED volumes to generate particles!

 

Moving The Particles To The Surface

Next, we want our particles to be moved to the geometry surfaces below them. 

  • With the PRT Volume object selected, click on the "Add Krakatoa Channels Modifier (KCM) to selected object(s)..." item in the Krakatoa menu of the 3ds Max Main Menu bar.
  • With the Krakatoa Channels modifier selected in the Modify Panel, click the "Open MagmaFlow Editor..." button.
  • In the View menu of the Editor, switch the options to Reorder Patterns>Tree Pattern.
  • In the View menu, check the Auto-Reorder - Toggle option to be enabled if it is not. This will ensure the flow will be reordered automatically each time a node is added.

  • Select the "1 OUT:Color" output node and change its Channel from Color to Position.
  • Select the "2 IN:Channel:Color" input node and press the button "Same Channel As Output" to set it to Position, too. Alternatively, just select the Position channel from the list.
  • With the Position input node selected, hit the S key to display the "Surface" nodes menu, then hit the R key to insert a RayIntersect node between the Position input and the Position output.
  • Since the Position input is expected as second input in the RayIntersect, press Ctrl+W to swap the first and second sockets of the RayIntersect node.
  • We now need a Geometry input node, so we hit U key to display the "Input" nodes menu (note that the "u" is underlined in the Input category in the Editor), then hit the G key for Geometry input.
  • Select the Geometry input node and use the "Add Names..." button to add the Cylinder and Torus Knot objects to the list of Geometry nodes to intersect with.
  • Select the RayIntersect node again - it still needs a 3rd input for the ray direction. Hold down the SHIFT key and press the 3 key in the top row to create a [0,0,1] Vector input node.
  • Change the Z component of the Vector input to -1.0 to shoot rays down along the -Z world axis.
  • Since the RayIntersect expects its controls in World Space, we now have to convert the Position channel to World Space. Select the Position Channel input node again and click the "ToWorld" button - this will insert a ToWorld node which will convert the Particle Positions from their default Object Space to World Space. Note that the ToWorld will automatically switch to "Point" mode which is used to convert 3D Positions to world space (as opposed to Vectors and Normals which are handled differently)
  • Now we want to read the result of the RayIntersect operation - select the RayIntersect and hit the S key for "Surface", then D for "SurfDataValue" (note how SD spells "SurfData"!). The default output of this node is "Position", so we are set. 
  • We just need the Position to be back to Object Space because the PRT Volume operates in its own local space, but the RayIntersect returns values in World Space. Just click the FromWorld button in the SurfDataValue node!

Here is the result in the viewport - all particles are moved to the closest point on one of the two surfaces:

 

Creating the FROST Object

Now that we have a basic particle distribution where we want it, let's mesh the PRT Volume using FROST:

  • Select the PRT Volume object
  • If you have custromized a Frost toolbar, click the Frost icon. If not, go to Create tab of the Command panel, select the Thinkbox category, click the Frost button, click and drag anywhere in the viewport to create the Frost object, then switch to Modify panel and use the Pick button in the Frost UI to add the PRT Volume to the list of objects to mesh.

Hopefully the above paragraph will convince you to set up a Frost toolbar with all shipping icons to speed up your workflow! 

  • With the FROST object selected, check the Frost rollout > Viewport Update > "When Particles Change" option. This will ensure our FROST object will remesh dynamically anytime we tweak the PRT Volume.
  • Switch the Meshing mode from the default Union Of Spheres to Metaballs.
  • Change the Particle Size > Radius from 5.0 to 2.0.
  • Assign a Standard material with white diffuse color and higher specularity to the FROST object. Of course, you can assign any material you want to render in your renderer of choice...
  • Select the PRT Volume object again, go to the PRT Volume base object, enter 1.5 for Spacing and uncheck the Viewp. Spacing checkbox to use the same distribution for both the Viewport and Rendering - the FROST object will update dynamically: 

 

Controlling the Particle Stickiness By Angle

Currently, our particles are placed on the surface as long as the ray intersection produces a valid position. In fact, some particles will appear at the origin because their intersections returns no valid hit and the Position was returned as [0,0,0]. There are ways to deal with these stray particles explicitly by checking whether the intersection result was valid, but our next step will take care of them as a side effect of figuring out whether the particles should stick to the surface based on the normal vector's angle to the world's up axis.

We will add another Krakatoa Channels Modifier to the PRT Volume's stack and select particles that should not stick to the surface, then delete them using a Krakatoa Delete modifier.

  • Select the PRT Volume object.
  • Add a new Krakatoa Channels modifier either by using the Krakatoa menu or from the Modifier list.
  • Press the "Open MagmaFlow Editor..." button.
  • Select the Output node and switch the channel from Color to Selection.
  • Select the Input node and switch from Color to Position channel.
  • With the Input node selected, hit the S key then the N key to create a NearestPoint surface operator.
  • With the NearestPoint node selected, press Ctrl+W to swap the first and second inputs, then hit U and G for a Geometry Input node. Use the "Add Names..." button to add the Cylinder and Torus Knot objects to the list again.
  • Select the Position input node again and click the ToWorld button to convert the data to World Space.
  • Select the NearestPoint node, then hit S and D keys for SurfDataValue node. Change the output data type from Position to FaceNormal.
  • With the SurfDataValue node selected, hit the . (period) key at the bottom row of the keyboard to insert a Vector DotProduct node (alternatively, hit the V and D keys for Vector>DotProduct).
  • With the DotProduct node selected, hold down SHIFT and press the 3 key for a [0,0,1] Vector input. This represents the World Up Z axis.
  • Select the DotProduct node again and hit L and E keys for Logic > Less. This will insert a Less logical operator which expects a second input to compare the dot product value to, so we press Ctrl and hit the 1 key to create a Float input node with a value of 1.0. This is our threshold value.
  • Since the output value of the Logic operators is an Integer which is either 1 for TRUE or 0 for FALSE, but the Selection channel is a Floating point value, we have to convert the Integer to Float. Simply select the Less node and click the "Convert To Float" button to insert the necessary operator.
  • All we need now is to add a Krakatoa Delete modifier to the PRT Volume's stack, above the second KCM. Any particles that are on a surface where the Dot Product between the World Up and the Face Normal is Less than the threshold value will be set to Selected 1.0 and will be deleted. 

Only particles on top of the Cylinder will remain because the Face Normal is parallel to the World Up vector, all other particles on the Torus Knot will be deleted:

 

Exposing And Tweaking The Threshold

Let's tweak the Threshold value and see how it affects the particle distribution and the FROST object.

  • Select the KCM_Selection modifier and open the MagmaFlow Editor if it was closed previously.
  • Select the Float Input going into the second socket of the Less operator, right-click it and select "Expose Control" - the control will be exposed in an "Exposed Parametets" rollout in the 3ds Max Command Panel.
  • Now you can close the MagmaFlow Editor and tweak the threshold value from the Command Panel.
  • Enter 0.7 instead of 1.0 in the Command Panel and the particles will reappear on the Torus Knot:

You can now spin the threshold spinner up and down between 0.0 (all particles there) and 1.0 (only particles on top). Values above 1.0 will delete all particles.

 

Conclusion

This demonstration provided an alternative approach to using Particle Flow history-dependent simulation  to determine whether a particle hits a mesh surface or not. Using Krakatoa MagmaFlow channel editing and its very fast kd-tree accelerated Ray Intersection methods, we were able to place the particles on the surfaces instantaneously without optimizing the geometry or processing the particle positions over multiple frames to interact with a Deflector.

Using this setup, you could add more objects with literally millions of polygons and cover with millions of particles in reasonable channel processing and meshing times.