使用变形¶
变形是指通过无缝过渡将一个形状转换为另一个形状。使用包含变形数据的 Mesh 资源在形状之间变形。
Kanzi 使用着色器来启用变形。请参阅 着色器 (Shaders)。
在您可以在 Kanzi 中进行网格变形之前,您需要在第三方工具中创建3D模型并将其导入到 Kanzi Studio。
当在第三方工具中创建网格以便在它们之间进行变形时,首先创建基础网格。从基础网格开始,塑造要变形到的网格。在创建网格时,请记住:
所有网格必须都具有相同数量的顶点和组合仪表。
请勿更改网格的拓扑。
添加变形¶
在您可以将变形添加到 Kanzi Studio 项目之前,需在第三方工具中创建带有变形的3D模型,并将其导出为gltf、glb、fbx或dae格式。
要在您的 Kanzi Studio 项目中添加变形:
在 Assets 中,单击 Import Assets 并导入使用变形网格的 3D 模型,该模型具有您希望在其间进行变形的变形目标。
每个变形目标都是变形基础形状的变形版本。
如果模型包含没有法线的网格,Kanzi Studio 提供生成法线的功能。Kanzi 在光照计算中使用法线。当您不让 Kanzi Studio 生成法线时,网格使用变形基网格的法线。请参阅 使用 morph target normals。
当 Kanzi Studio 导入变形时,它会创建:
在 Library > Meshes 中,包含其基础顶点数据和差分变形数据的网格。
在 Library > Materials and Textures 中,如果您的项目尚不包含此类材质类型,则需要支持变形的材质类型。
Kanzi Studio 创建使用此材质类型的材质,并将您的变形的基础网格设置为使用这些材质。
在材质类型中,Kanzi Studio 设置同时激活的变形目标的最大数量,以匹配导入变形中的网格数量。为了优化性能,您可以限制同时激活的变形目标的数量。请参阅 限制同时激活的变形目标的数量。
在 Prefabs 中,一个 Scene 预设包含使用 Morph 和 Mesh 资源的 Model 节点。
要在 Prefabs 中的 Preview 中显示 Scene 预设的内容,请双击该预设。
Kanzi Studio 在新的 Preview 选项卡中打开预设,并在 Preview 中显示该预设的内容。
在 Prefabs 中,选择显示包含变形数据的 Mesh 资源的 Model 节点。在 Properties 的 Morphing 属性中,您可以调整 Morph 资源中每个网格的权重。
通过这种方式,您可以控制 Morph 的形状。
值越高,Mesh 就越接近给定的形状。Kanzi 变形着色器使用网格的基础通道数据,并将所有形状累加到基础形状上。由于变形形状表示为与基础形状的差值,因此使用大于 1 的权重,或在 Morphing 属性中为多个形状设置较高的权重,可能会导致视觉错误。
例如,可以使用关键帧动画来更改变形的形状。请参阅 创建变形权重动画。
将目标添加到 Morph 中¶
要添加您想在其间变形的形状,请使用 Model 节点中 Morphing 属性的下拉菜单向变形添加形状。您只能从与分配给该 Model 的 Mesh 关联的形状中添加变形目标。
要将目标添加到 Morph:
在要变形的 Model 节点的 Morphing 属性中,点击 + Morph shape 按钮,然后选择要添加到变形的形状。
要重新排列变形列表,请使用 Morphing 属性中与形状关联的向上和向下箭头。
要移除形状,请使用 Morphing 属性中与形状关联的叉号按钮。
要从头开始并使用默认权重添加所有形状,请移除 Morphing 属性,然后使用 + 按钮重新添加该属性。
(可选) 在 Library > Materials and Textures > Material Types 中,选择您的变形基网格使用的每个材质类型。在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_MORPH_TARGET_COUNT 设置为您希望 Kanzi 一次可以激活的变形目标数量。
如果您使用智能材质,Kanzi 会根据为材质设置的属性自动设置 Preprocessor Definitions。
导入带有变形的 Mesh 时,Kanzi 会自动为您创建合适的材质并将其分配给该 Mesh。
如果变形数据中的变形形状数量无需使用 Morph Data Texture 即可容纳在 GPU 特性通道中,则应使用 Mesh 变形数据中确切的变形目标数量,并且无需更改 KANZI_SHADER_MORPH_TARGET_COUNT。请参阅 限制同时激活的变形目标数量。
(可选) 如果您的图形驱动程序不支持 Mesh 中的变形目标数量,请在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_USE_MORPH_DATA_TEXTURE 设置为 1。
通过这种方式,您可以启用材质类型使用变形数据纹理。数据纹理允许同时拥有任意数量的活动变形目标,但会带来性能成本。
Kanzi 会自动检测是否需要 Morph Data Texture,创建该纹理,并将其分配给 Model。在这种情况下,更改所分配变形目标的顺序和数量会就地修改该纹理。您可以通过移除不必要的变形形状来降低性能开销。请参阅 限制同时激活的变形目标的数量。
使用 morph target normals¶
当您将使用变形网格的 3D 模型导入 Kanzi Studio,并且该模型中的某些网格没有法线时,Kanzi Studio 会自动为变形目标生成法线。Kanzi 在光照计算中使用这些法线。
由于 Kanzi Studio 为变形目标生成的法线可能与变形基础形状的法线不同,因此随着您激活更多变形目标,这种差异会累积误差,从而导致视觉效果逐渐下降。为避免这种情况,Kanzi Studio 在为变形目标生成法线时也会重新生成基网格的法线。
要避免 Kanzi Studio 生成或更改法线,请从 3D 编辑软件中导出所有变形形状的法线。
小技巧
要手动生成网格的法线, 在 Library > Meshes 中右键单击该网格并选择 Generate Normals。
控制使用变形目标法线¶
要控制变形目标法线的使用:
在 Library > Materials and Textures > Materials Types 中,选择您的变形基网格使用的材质类型。
在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_USE_MORPH_TARGET_NORMALS 的值设置为:
0 将形变目标设置为使用形变基础网格的法线。
1 将每个变形目标设置为使用其自身的法线。
限制同时激活的变形目标的数量¶
当您将包含变形的3D模型导入到 Kanzi Studio 时,Kanzi Studio 将该变形设置为使用支持同时激活所有变形目标的材质类型。如果您的变形包含大量目标,Kanzi 会将变形设置为在数据纹理中存储其变形目标的顶点属性。数据纹理允许同时拥有任意数量的活动变形目标,但会带来性能成本。一次激活的变形目标越多,处理顶点着色器所需的时间就越长。要优化性能,您可以:
限制一次可以激活的变形目标的数量。
禁用数据纹理的使用。
在没有数据纹理的情况下,同时激活的变形目标的最大数量是
在其中:
\(MaxChannels\) 是您的图形驱动程序支持的最大顶点属性通道数。
例如,16。
\(ConstantChannels\) 是包含所有变形目标相同属性数据的通道数量。
例如,纹理坐标、骨骼权重和骨骼索引对于所有变形目标都是相同的。
\(PerTargetChannels\) 是包含目标特定属性数据的通道数量。
例如,顶点位置、法线和切线可以在每个变形目标中有所不同。
Kanzi Studio 根据实际网格数据选择操作模式:
如果通道数量足够少,无需 Morph Data Texture 即可使用,Kanzi 始终使用所有变形数据通道。移除形状对性能没有影响——未选定的形状权重为 \(0.0\)。
在 Library > Materials and Textures > Material Types 中,选择您的变形基网格使用的每个材质类型。在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_USE_MORPH_DATA_TEXTURE 设置为 0。
如果这样做,请确保将 KANZI_SHADER_MORPH_TARGET_COUNT 设置为与 Mesh 中变形目标数量完全相同的值。否则,Kanzi Studio 会使用红色错误材质渲染您的模型,并在日志中打印警告。
如果变形数据的通道数量足够多,可能需要使用 Morph Data Texture,Kanzi 始终使用数据纹理。移除形状可以提高性能并减小数据纹理,从而降低内存需求。
在 Library > Materials and Textures > Material Types 中,选择您的变形基网格使用的每个材质类型。在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_USE_MORPH_DATA_TEXTURE 设置为 1。
为优化性能,当您不需要网格数据中的某些变形形状时:
从 Morphing 属性的形状列表中移除该形状。
在 Library > Materials and Textures > Material Types 中,选择您的变形基网格使用的每个材质类型。
在 Properties 的 Preprocessor Definitions 中,将 KANZI_SHADER_MORPH_TARGET_COUNT 设置为您需要的变形目标数量。
(可选) 如果网格包含在任何情况下都不会使用的变形目标,最好在 3D 编辑软件中禁用这些目标的导出,从一开始就不导出它们。这样,无论如何 Kanzi 都不会使用这些变形目标。
创建变形权重动画¶
要更改变形的形状,使用关键帧动画。您可以从 gltf、glb、fbx 或 dae 文件中导入变形权重动画,或者在 Kanzi Studio 中创建动画。
要在 Kanzi Studio 中创建变形权重动画:
在 Library > Animation Data 中,按 Alt 并右键单击 Animation Data,然后选择 Animation。
例如,将动画命名为 Middle Animation,并在 Properties 中设置:
将 Target Property 设置为 Model3D.Morphing 属性,并将目标形状索引设置为 1。
Property Field 到 Whole property
您使用 Animation Clip 来保存变形中各网格的关键帧动画。每个动画都以特定的变形形状为目标,并定义网格在不同时间点的权重。Middle Animation 是您要变形的第一个网格的关键帧动画。
对您要动画化的 Mesh 中的每个目标形状重复上一步。对于范围索引 n 中的每个动画,将 n 设置为 Model 中您要通过该动画更改其权重的形状的索引。不要为基础网格添加动画。
例如,要使用三个网格对变形进行动画化,请创建两个动画。将它们命名为 Middle Animation 和 Ready Animation,并设置:
将 Middle Animation 的 Target Property 设置为 Model3D.Morphing 索引 1
将 Ready Animation 的 Target Property 设置为 Model3D.Morphing 索引 2
使用 Middle Animation 设置变形中第二个网格的权重。使用 Ready Animation 在不同时间点设置变形中第三个网格的权重。Kanzi 变形着色器设置第一个网格的权重。
备注
动画数据中的索引指向被动画化的 Model3D 中的形状索引。
如果网格的变形目标数量足够少,不需要 Morph Data Texture,则此项指向变形数据中的确切形状。如果使用了 Morph Data Texture`,则此项取决于为 Morphing 属性选择的形状的顺序和数量。
为您在上一步中创建的动画创建关键帧。请参阅 为目标属性字段创建关键帧动画。
您使用关键帧值在不同时间点设置变形中网格的 Weight 属性。
值越高,Mesh 就越接近给定的形状。Kanzi 变形着色器使用网格的基础通道数据,并将所有形状累加到基础形状上。由于变形形状表示为与基础形状的差值,因此使用大于 1 的权重,或在 Morphing 属性中为多个形状设置较高的权重,可能会导致视觉错误。
例如,要为包含三个网格的变形创建一秒钟的线性动画,请在 Library 中双击 Middle Animation,然后在 Animation Clip Editor 中创建以下关键帧:
Middle Animation:
第一个关键帧:
将 Time 设为 0。
Value 到 0
第二个关键帧:
Time 到 0.5
Value 到 1
第三个关键帧:
Time 到 1
Value 到 0
Ready Animation:
第一个关键帧:
将 Time 设为 0。
Value 到 0
第二个关键帧:
Time 到 0.5
Value 到 0
第三个关键帧:
Time 到 1
Value 到 1
使用您创建的关键帧动画对变形进行动画化:
在 Node Tree 中,选择其 Mesh 属性设置为您要动画化的 Mesh 的 Model 节点。请参阅 添加变形。
在 Node Components 中,按 Alt 并右键单击 Animation 并选择 Animation Player。
在您创建的 Animation Player 中的 Node Components 中,将 Target Animation Timeline 属性设置为您在第一步中创建的 Animation Clip,并设置动画播放。请参阅 播放关键帧动画。
例如,设置:
将 Autoplay Enabled 设置为 enabled。
Playback Mode 到 Ping pong
将 Repeat Count Infinite 设置为 enabled。
在 API 中使用变形¶
要手动创建变形时间线并为时间线时钟创建回放:
// Create float animation and add two keyframes.
FloatKeyframeAnimationSharedPtr morphAnimation =
FloatKeyframeAnimation::create(domain);
morphAnimation->addLinearKeyframe(chrono::milliseconds(0), 0.0f);
morphAnimation->addLinearKeyframe(chrono::milliseconds(100), 1.0f);
// Create a range index animation timeline and apply it to the Morphing property of the current node.
RangeIndexAnimationTimelineSharedPtr rangeIndexTimeline =
RangeIndexAnimationTimeline::create(domain, ".", Model3D::MorphingProperty);
// Animate the first morph target using the keyframe animation (this animation goes from weight zero to one).
rangeIndexTimeline->addEntry(0, PropertyFieldWhole, morphAnimation);
// Create range index animation timeline playback.
RangeIndexAnimationTimelinePlaybackSharedPtr playback =
RangeIndexAnimationTimelinePlayback::create(rangeIndexTimeline, context);