Genome
RSS< Twitter< etc

<< Back To Advanced Workflows

Baking Data In Particles

The following advanced workflow is meant for Technical Directors and technically inclined users.

Problem

Bake animated Scene Lighting as Vertex Color in an object and play it back with the lights removed.

Baking the lighting into a Vertex Paint modifier is supported by 3ds Max but cannot be animated directly since the modifier only stores static information.

Using MAXScript, it is possible to bake the lighting into the Vertex Color channel of a single modifier on each frame, but there is no convenient "container" to store this data over time.

One possible solution is to create a copy of the object, collapse it to Editable Mesh, animate the vertices of the object to positions representing the color values, and then read these positions using a Genome modifier and assign them back to the vertices. While this works, the baking process is prohibitively slow.

Similar approach is the animating of the map vertices in an UVW_Unwrap modifier. The principle is the same, and the performance problem remains. 

A better solution would be to use the Thinkbox XMesh plugin to save the mesh on each frame using a custom script that bakes the lighting into vertex colors and then bakes out the mesh to disk. While this is an awesome approach, it does not involve Genome and will be discussed in a separate, XMesh-related example elsewhere.

Solution

The proposed solution using Genome is to employ the free Evaluation Version of Krakatoa and its MAXScript exposure which allows you to save arbitrary data in a custom PRT file sequence. In this case, all we need to do is save the color of each vertex in a Color channel of a PRT file and then use Genome to read it back onto our mesh.

Example Scene

  • Create a Teapot with 16 segments (or any number of segments for that matter). You can also use any other mesh you want.
  • Set the wireframe color to white or assing a Standard Material.
  • Add a VertexPaint modifier - it will be used to store the Vertex Colors with the lighting.
  • Create an Omni light in the scene. 
  • Enable Auto Key and animate the position of the light in world space to produce some dynamic lighting. Animate the color of the light too, or any other relevant parameters.

   

The Baking Script

The script we will use to bake the lighting to particles is relatively simple.

  • We will get the object and its Vertex Color modifier into user variables first.
  • Then we will loop through the current animation range and set the slider time to the current frame
  • We will create a particle stream for each frame with a Position and Color channel. We have to rename the output filename to match the current frame - the FranticParticles interface exposed by Krakatoa provides a useful function that will deal with the zeros, too...
  • The Vertex Colors will be calculated and stored in the current modifier.
  • Then it will capture the TriMesh of the object using snapshotAsMesh()
  • A for loop through all faces will iterate in parallel through both mesh and map faces, since they have a one-to-one correspondence
  • A second loop will count from 1 to 3 to visit every mesh vertex and corresponding map vertex via the mesh and map faces.
  • A particle will be written with the position of the current vertex and the corresponding color.
  • After both loops have finished, we close the particle file and delete the TriMesh

Here is the script:

theObject = $Teapot001
theMod = theObject.vertexpaint
for t = 0 to 100 do
(
slidertime = t
local theFile = KrakatoaParticleOStream (FranticParticles.ReplaceSequenceNumber "C:\\temp\\bakecolor_0000.prt" t) #("Position float32[3]", "Color float16[3]")
AssignVertexColors.ApplyNodes theObject vertexPaint:theMod
theMesh = snapshotasmesh theObject
for f = 1 to theMesh.numfaces do
(
theFace = getFace theMesh f
theMapFace = meshop.getMapFace theMesh 0 f
for v = 1 to 3 do
theFile.writeParticle #(getVert theMesh theFace[v], meshop.getMapVert theMesh 0 theMapFace[v])
)
theFile.close()
delete theMesh
)--end t loop

Loading The Data

After running the script, a sequence of PRT files will be found on disk. Now we have to load them onto the mesh via a PRT Loader and a Genome modifier.

  • Hold SHIFT and select "Create PRT Loader" from the Krakatoa menu, or click the PRT icon if you have a Krakatoa toolbar.
  • Select the saved sequence
  • Set the PRT Loader to 100% in the viewport
  • Select the Omni light and turn it off.

RESULT: The Teapot turnd black because there is no scene lighting, and the PRT Loader shows the vertex colors with its particles. Playing back the time range will show that the particles are changing color according to the baked dynamic lighting.

   

Creating The Genome Flow

  • Select the Teapot and add a Genome modifier in "Face Corners" iteration mode.
  • Press Ctrl+[O] to add an Output node and set it to Color
  • Press [O] and [P] to create a NearestParticle node.
  • Drag a wire from the Particles input socket and release over empty area to create an InputParticles node. Pick the PRT Loader as the source.
  • Drag a wire from the Lookup Point (WS) input socket and release to automatically create a Position InputChannel with Convert > ToWorld operator.
  • Press Ctrl+[D] to deselect all nodes and press [O] and [A] to create a ParticleQuery operator.
  • Connect the InputParticles to the Particles input socket of the ParticleQuery.
  • Select the Position channel entry from the list of exposed channels and press Remove.
  • Select the Color channel entry from the bottom list and press Add.
  • Connect the Color output of the ParticleQuery to the Output node.
  • Place the ParticleQuery to the right of the NearestParticle node, hold down Ctrl and select InputParticles and NearestParticle together with ParticleQuery, then hit [SPACEBAR] to connect all relevant sockets - the result should be that InputParticles will connect to the Particles input socket of ParticleQuery, and the ParticleIndex of the NearestParticle will connect into the Index socket of ParticleQuery. You can also connect them manually if you prefer.

RESULT: This flow looks for the particle closest to each mesh vertex and grabs its color into the Color channel of the mesh.

  • You can now hide the PRT Loader.
  • Select the Teapot, right-click and open Object Properties.
  • Check "Vertex Color Display" and press OK to close the dialog.

You should now see the Teapot showing dynamic Vertex Colors if you move the time slider:

   

Further Ideas

The same approach can be used for storing any mesh data like vertex positions, selection, mapping coordinates and so on.

With a little bit of additional work and using two passes of saving, we could even implement History Dependent workflows in Genome... Stay tuned.