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:

  1. 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.

    ../../_images/assets-import-assets8.png

    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.

      Kanzi Studio sets the base mesh of the morph to use materials whose material type supports morphing. If your project does not contain a material type that supports morphing, Kanzi Studio automatically creates the material type. In that 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.

      ../../_images/library-morph-cube.png
    • 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.

      ../../_images/morph-composition.png
  2. 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.

    ../../_images/prefabs-main-model.png ../../_images/properties-main-model-adjust-weights.png

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:

  1. In the Library > Meshes, create or select a Morph resource.

    ../../_images/library-morph-cube.png
  2. In the Properties in the Morph Target Weights property:

    1. 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.

      ../../_images/morph-targets-add.png ../../_images/set-morph-targets.png
    2. Repeat the previous step to add all the morph targets between which you want to morph.

  3. 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.

    ../../_images/library-vertex-phong-morph.png ../../_images/properties-morph-target-count-9.png
  4. (Optional) If your graphics driver does not support the number of morph targets that you set:

    1. 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.

      ../../_images/properties-use-morph-data-texture-1.png
    2. In the Library > Meshes, select your Morph resource. In the Properties, add and enable the Morph > Export as Data Texture property.

      ../../_images/library-morph-cube.png ../../_images/properties-export-as-data-texture.png

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

\[N = floor((MaxChannels - ConstantChannels) / PerTargetChannels)\]

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:

  1. 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.

    ../../_images/library-vertex-phong-morph.png ../../_images/properties-morph-target-count-6.png
  2. (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:

    1. 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.

      ../../_images/library-vertex-phong-morph.png ../../_images/properties-use-morph-data-texture-0.png
    2. In the Library > Meshes, select the Morph resource. In the Properties, disable or remove the Export as Data Texture property.

      ../../_images/library-morph-cube.png ../../_images/properties-disable-morph-data-texture.png

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:

  1. 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.

    ../../_images/create-animation-clip.png
  2. 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 image0 to add the Morph Weight property, and set it to <MorphWeight>[1]

    • Property Field to Whole property

    ../../_images/create-morph-animation.png ../../_images/middle-animation-target-property-add-morph-weight-adding.png ../../_images/middle-animation-properties.png
  3. 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.

    ../../_images/morph-animations-in-the-library.png ../../_images/middle-animation-properties.png ../../_images/ready-animation-properties.png
  4. 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

      ../../_images/middle-animation-in-animation-clip-editor.png
    • Ready Animation:

      • First keyframe:

        • Time to 0.5

        • Value to 0

      • Second keyframe:

        • Time to 1

        • Value to 1

      ../../_images/ready-animation-in-animation-clip-editor.png
    ../../_images/morph-animation-clip-in-animation-clip-editor.png
  5. Animate the morph with the keyframe animations that you created:

    1. 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.

      ../../_images/model-in-the-project.png ../../_images/set-model-mesh-property.png
    2. In the Node Components, press Alt and right-click Animation and select Animation Player.

      ../../_images/triggers-add-animation-player3.png
    3. 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

      ../../_images/animation-player-target-animation-timeline-morph-animation-clip.png ../../_images/morph-animation.gif

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

3D assets

Importing 3D assets

Preparing 3D assets in third-party tools

Using meshes

Meshes best practices

Material types and materials

Using material types

Animations

Creating keyframe animations for target property fields

Using keyframe animations

Editing shaders

Property precedence