Using Morph resources¶
Morphing transforms a shape into another in a seamless transition. Use the Morph resource to morph between meshes.
Kanzi uses shaders to enable morphing. See Shaders.
Before you can morph between meshes in Kanzi, you need to create the 3D models in a third-party tool and import them to Kanzi Studio.
When you create in your third-party tool meshes between which you want to morph, first create the base mesh. From the base mesh, shape the meshes to which you want to morph. When creating the meshes, keep in mind:
All meshes must have the same amount of vertices and clusters.
Do not change the topology of meshes.
Adding a morph¶
Before you can add a morph to a Kanzi Studio project, in a third-party tool create a 3D model with the morph and export it to gltf, glb, fbx, or dae format.
To add a morph to your Kanzi Studio project:
In the Assets, click Import Assets and import the 3D model that uses a morph mesh with morph targets between which you want to morph.
Each morph target is a deformed version of the morph base shape.
If the model contains meshes that do not have normals, Kanzi Studio offers to generate the normals. Kanzi uses the normals in lighting calculations. When you do not let Kanzi Studio generate the normals, the meshes use the normals of the morph base mesh. See Using morph target normals.
When Kanzi Studio imports a morph, it creates:
In the Library > Meshes, the meshes from the 3D model and a Morph resource that uses the imported meshes.
In the Library > Materials and Textures, a material type that supports morphing, if your project does not already contain such material type.
Kanzi Studio creates materials that use this material type, and sets the base mesh of your morph to use these materials.
In the material type, Kanzi Studio sets the maximum number of simultaneously active morph targets to match the number of meshes in the imported morph. To optimize performance, you can limit the number of simultaneously active morph targets. See Limiting the number of simultaneously active morph targets.
In the Prefabs, a Scene prefab that contains the Model nodes that use the Morph and Mesh resources.
To show the content of the Scene prefab in the Preview, in the Prefabs, double-click that prefab.
Kanzi Studio opens the prefab in a new Preview tab and shows the content of that prefab in the Preview.
In the Prefabs, select a Model node that shows the Morph resource. In the Properties in the Morph Target Weights property, you can adjust the weight of each mesh in the Morph resource.
This way, you control the shape of the Morph.
The higher the value, the closer the Morph takes the shape of that mesh. The Kanzi morph shader sets the weight of the base morph shape so that the sum of the Morph Target Weights is 1. This makes the scale of the resulting shape stay true to the target shapes.
For example, to change the shape of a morph, use a keyframe animation. See Creating a morph weight animation.
Adding targets to a Morph¶
To add shapes between which you want to morph, add meshes to a Morph.
For the morphing to work correctly, add only meshes that:
Are shaped from the same base mesh.
Have the same topology and amount of vertices and clusters.
To add targets to a Morph:
In the Library > Meshes, create or select a Morph resource.
In the Properties in the Morph Target Weights property:
Click Add. In the dropdown menu, select the mesh that you want to add as a target to the Morph and adjust the weight of the mesh. The higher the value, the closer the Morph takes the shape of that mesh.
Repeat the previous step to add all the morph targets between which you want to morph.
In the Library > Materials and Textures > Material Types, select each material type that the base mesh of your morph uses. In the Properties in the Preprocessor Defines property, set the KANZI_SHADER_MORPH_TARGET_COUNT to the number of morph targets that you want to let Kanzi activate at once.
When a morph has more targets than the value of KANZI_SHADER_MORPH_TARGET_COUNT, Kanzi automatically selects for activation those morph targets that have the largest weight.
(Optional) If your graphics driver does not support the number of morph targets that you set:
In the Properties in the Preprocessor Defines property, set the KANZI_SHADER_USE_MORPH_DATA_TEXTURE to 1.
This way, you enable the material type to use a morph data texture. The data texture enables having an arbitrary number of active morph targets at once, but comes with a performance cost.
In the Library > Meshes, select your Morph resource. In the Properties, add and enable the Morph > Export as Data Texture property.
Using morph target normals¶
When you import to Kanzi Studio a 3D model that uses a morph mesh and some of the meshes in that model do not have normals, Kanzi Studio offers to generate the normals. Kanzi uses the normals in lighting calculations. When you do not let Kanzi Studio generate the missing normals during import, the morph targets automatically use the normals of the morph base mesh.
Tip
To generate normals for a mesh manually, in the Library > Meshes right-click that mesh and select Generate Normals.
Controlling the use of morph target normals¶
To control the use of morph target normals:
In the Library > Materials and Textures > Materials Types, select the material type that the base mesh of your morph uses.
In the Properties in the Preprocessor Defines property, set the value of the KANZI_SHADER_USE_MORPH_TARGET_NORMALS to:
0 to set the morph targets to use the normals of the morph base mesh.
1 to set each morph target to use its own normals.
Improving the generated morph target normals¶
When the normals that Kanzi Studio generates for morph targets differ from those of the morph base shape, the difference accumulates as you activate more morph targets. This can cause incremental visual degradation in the normals.
To improve the generated morph target normals:
In the Library > Materials and Textures > Materials Types, select the material type that the base mesh of your morph uses.
In the Properties in the Preprocessor Defines property, set the value of the KANZI_SHADER_USE_MORPH_NORMAL_LIMIT to 1.
This limits the difference in the normals to that caused by a single target shape.
Limiting the number of simultaneously active morph targets¶
When you import to Kanzi Studio a 3D model that contains a morph, Kanzi Studio sets that morph to use a material type that supports activating all morph targets at once. If your morph contains a large number of targets, Kanzi sets the morph to store the vertex attributes of its morph targets in a data texture. The data texture enables having an arbitrary number of active morph targets at once, but comes with a performance cost. The more morph targets are active at once, the more time it takes to process the vertex shader. To optimize performance, you can:
Limit the number of morph targets that can be active at once.
Disable the use of the data texture.
Without a data texture, the maximum number of simultaneously active morph targets is
where:
\(MaxChannels\) is the maximum number of vertex attribute channels supported by your graphics driver.
For example, 16.
\(ConstantChannels\) is the number of channels that contain the same attribute data for all morph targets.
For example, texture coordinates, bone weights, and bone indices are the same for all morph targets.
\(PerTargetChannels\) is the number of channels that contain target-specific attribute data.
For example, vertex positions, normals, and tangents can be different for each morph target.
To optimize performance, when you do not need to activate in your morph more than \(N\) targets at once, disable the use of the data texture.
When your morph does not use a data texture, only the \(N\) targets that have the largest weight can be active at once.
To limit the number of simultaneously active morph targets:
In the Library > Materials and Textures > Material Types, select each material type that the base mesh of your morph uses. In the Properties in the Preprocessor Defines property, set the KANZI_SHADER_MORPH_TARGET_COUNT to the number of morph targets that you want to let Kanzi activate at once.
When a morph has more targets than the value of KANZI_SHADER_MORPH_TARGET_COUNT, Kanzi automatically selects for activation those morph targets that have the largest weight.
(Optional) If you set the KANZI_SHADER_MORPH_TARGET_COUNT to a value that your graphics driver supports without the use of a data texture, disable the data texture:
In the Library > Materials and Textures > Material Types, select each material type that the base mesh of your morph uses. In the Properties in the Preprocessor Defines property, set the KANZI_SHADER_USE_MORPH_DATA_TEXTURE to 0.
If you do this, make sure that the KANZI_SHADER_MORPH_TARGET_COUNT is set to a value that your graphics driver supports without the use of a data texture. Otherwise, Kanzi Studio renders your model with a red error material and prints a warning in the log.
In the Library > Meshes, select the Morph resource. In the Properties, disable or remove the Export as Data Texture property.
Creating a morph weight animation¶
To change the shape of a morph, use a keyframe animation. You can import the morph weight animation from gltf, glb, fbx, or dae files, or create the animation in Kanzi Studio.
To create a morph weight animation in Kanzi Studio:
In the Library, press Alt and right-click Animations, select Animation Clip, and name it.
You use the Animation Clip to host keyframe animations for the meshes in your morph. Each animation targets a specific mesh in the morph and defines the weight of the mesh at different points in time.
In the Library > Animations, select the animation clip that you created in the previous step. Create a keyframe animation for the first mesh that you want to morph.
For example, name the animation Middle Animation and in the Properties, set:
Target Property to <Expression>, click to add the Morph Weight property, and set it to <MorphWeight>[1]
Property Field to Whole property
Repeat the previous step as many times as there are target shapes in the Morph that you want to animate. For each animation in the <MorphWeight>[n], set the n to the mesh in the Morph whose weight you want to change with the animation. Do not add an animation for the base mesh.
For example, to animate a morph with three meshes, create two animations. Name them Middle Animation and Ready Animation, and set:
Middle Animation Target Property to <Expression> <MorphWeight>[1]
Ready Animation Target Property to <Expression> <MorphWeight>[2]
You use the Middle Animation to set the weight of the second mesh in your morph. You use the Ready Animation to set the weight of the third mesh in your morph at different points in time. The Kanzi morph shader sets the weight of the first mesh.
Create keyframes for the animations that you created in the previous step. See Creating keyframe animations for target property fields.
You use the keyframe values to set the Weight properties of the meshes in the morph at different points in time.
The higher the value, the closer the Morph takes the shape of that mesh. The Kanzi morph shader sets the weight of the base morph shape so that the sum of the Morph Target Weights is 1. This makes the scale of the resulting shape stay true to the target shapes.
For example, to create a one-second linear animation of a morph with three meshes, use these keyframes:
Middle Animation:
First keyframe:
Time to 0
Value to 0
Second keyframe:
Time to 0.5
Value to 1
Third keyframe:
Time to 1
Value to 0
Ready Animation:
First keyframe:
Time to 0.5
Value to 0
Second keyframe:
Time to 1
Value to 1
Animate the morph with the keyframe animations that you created:
In the Node Tree, select the Model node whose Mesh property is set to the Morph that you want to animate. See Adding a morph.
In the Node Components, press Alt and right-click Animation and select Animation Player.
In the Node Components in the Animation Player that you created, set the Target Animation Timeline property to the Animation Clip that you created in the first step, and set the animation playback. See Playing keyframe animations.
For example, set:
Autoplay Enabled to enabled
Playback Mode to Ping pong
Repeat Count Infinite to enabled
Using morphs in the API¶
To manually create a morph timeline and create a playback for timeline clock:
// Create morph and add meshes (created beforehand) into it.
MorphSharedPtr morph = Morph::create(domain, "testMorph");
morph->add(mesh1, 0.0f);
morph->add(mesh2, 1.0f);
// Add node that will hold the morph, then add it to the scene graph (scene).
Model3DSharedPtr model = Model3D::create(domain, "testSphere");
model->setMesh(morph);
scene->addChild(model);
// Create float animation and add two keyframes.
FloatKeyframeAnimationSharedPtr animation = FloatKeyframeAnimation::create(domain);
animation->addLinearKeyframe(chrono::milliseconds(0), 0.0f);
animation->addLinearKeyframe(chrono::milliseconds(100), 1.0f);
// Create timeline and playback.
MorphWeightTimelineSharedPtr morphTimeline = MorphWeightTimeline::create(domain, "testSphere", 1, animation);
SceneGraphTimelinePlaybackContext context(*scene);
TimelinePlaybackSharedPtr playback = morphTimeline->createPlayback(context);
// Add playback to root clock
domain->getRootTimelineClock()->addTimelinePlayback(playback);
For details, see the Morph
class.
See also¶
Preparing 3D assets in third-party tools