一个动画的 GLB 或 GLTF 模型存储几何体和动画数据,而不是一组预制图像的文件夹。要创建缩略图或帧序列,需要在特定时间戳评估模型的动画,并将每个生成的场景渲染为图像。本教程说明如何使用 Aspose.3D for Python via .NET 在 Python 中渲染 GLB 动画帧。您将加载动画模型,选择一个剪辑,采样其时间轴,并将每帧保存为编号的 PNG 图像。您可以将生成的图像用作模型预览或作为单独的图像序列工作流的输入。
安装 Aspose.3D for Python via .NET
使用 pip 安装 package:
pip install aspose-3d
您还需要:
- 一个带有伴随缓冲区和纹理的动画
.glb文件或.gltf文件。 - 一个符合 Aspose.3D 硬件要求的渲染环境。请参阅系统要求。
- 一个相机位置,使动画对象在整个采样时间轴上保持可见。
将动画剪辑渲染为 PNG 帧
将以下代码保存为 render_glb_animation_frames.py,并在包含 animated_model.glb 的文件夹中运行它。
import hashlib
import math
from pathlib import Path
import aspose.threed as a3d
from aspose.pydrawing import Color, Size
from aspose.pydrawing.imaging import ImageFormat
from aspose.threed.entities import Camera
from aspose.threed.utilities import Vector3
INPUT_FILE = Path("animated_model.glb")
OUTPUT_DIR = Path("frames")
FRAMES_PER_SECOND = 5
IMAGE_WIDTH = 800
IMAGE_HEIGHT = 600
def main():
if not INPUT_FILE.is_file():
raise FileNotFoundError(f"Input model not found: {INPUT_FILE}")
scene = a3d.Scene.from_file(str(INPUT_FILE))
clips = list(scene.animation_clips)
if not clips:
raise RuntimeError("The input model has no animation clips.")
clip = clips[0]
duration = float(clip.stop - clip.start)
if duration <= 0:
raise ValueError("The selected animation has no positive time range.")
# Use the same camera position for every frame.
camera = Camera()
camera_node = scene.root_node.create_child_node("PreviewCamera", camera)
camera_node.transform.translation = Vector3(3, 2, 6)
camera.look_at = Vector3.ORIGIN
options = a3d.ImageRenderOptions()
options.background_color = Color.white
options.asset_directories.append(str(INPUT_FILE.resolve().parent))
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
frame_count = max(1, math.ceil(duration * FRAMES_PER_SECOND))
hashes = set()
for frame_index in range(frame_count):
timestamp = float(clip.start) + frame_index / FRAMES_PER_SECOND
clip.apply_to(timestamp)
frame_path = OUTPUT_DIR / f"frame_{frame_index:04d}.png"
scene.render(
camera,
str(frame_path),
Size(IMAGE_WIDTH, IMAGE_HEIGHT),
ImageFormat.png,
options,
)
if not frame_path.is_file() or frame_path.stat().st_size == 0:
raise RuntimeError(f"Rendering did not create a usable PNG: {frame_path}")
hashes.add(hashlib.sha256(frame_path.read_bytes()).digest())
print(f"Frame {frame_index + 1}/{frame_count}: {frame_path} at {timestamp:.3f}s")
if frame_count > 1 and len(hashes) == 1:
print("WARNING: All PNG files are byte-identical. Check animation state and camera view.")
print(f"Created {frame_count} PNG file(s) in {OUTPUT_DIR}/")
if __name__ == "__main__":
main()
运行它:
python render_glb_animation_frames.py
预期输出: 一个 frames 目录,包含诸如 frame_0000.png、frame_0001.png 和 frame_0002.png 的图像。当渲染器正确捕获已应用的动画状态时,这些图像显示模型在动画中的连续帧。
帧渲染代码的工作原理
加载场景并选择动画剪辑
Scene.from_file() 方法打开模型,而 scene.animation_clips 提供对其包含的动画剪辑的访问。示例使用第一个剪辑并读取其 start 和 stop 属性以确定时间范围。没有动画剪辑的模型无法通过此方法生成动画序列。
如需了解有关剪辑选择和节点变换的更多详细信息,请参阅 在 Python 中加载和评估 GLB/GLTF 动画.
在固定间隔对时间线进行抽样
脚本每秒使用五个采样。如果剪辑持续两秒,则在剪辑从零开始时,它会在 0.0 到 1.8 秒的时间戳上请求十帧。排除精确的终点可避免为循环回到起始姿势的动画生成冗余的最后一帧。
clip.apply_to(timestamp) 方法在每个时间戳上应用选定的动画剪辑。与评估单个关键帧序列不同,此步骤旨在在渲染图像之前更新动画场景。
从单个相机渲染更新的场景
示例在固定位置添加了摄像机,并在每帧调用 scene.render()。它还将图像大小设置为 800 × 600 像素,并使用 PNG 输出格式。保持摄像机固定可以更容易检查帧与帧之间的差异。
The Aspose.3D 场景渲染指南 显示了如何将 3D 视图保存为图像。对于动画序列,请验证每个图像是否反映了预期的时间戳。如果连续帧显示相同的姿势,请检查渲染路径是否使用了当前的动画状态。
为每个 PNG 帧统一命名
frame_0000.png 模式在按文件名排序时保持图像顺序。它适用于生成预览缩略图或将输出传递给单独的图像序列或视频工作流。该脚本不会创建视频或动画 GIF。
脚本还会比较文件哈希,以在所有输出文件字节完全相同的情况下发出警告。不同的哈希本身并不能证明动画渲染正确;请并排检查代表性帧。
获取免费临时许可证
您可以请求免费 30 天的临时许可证来使用 Aspose.3D for Python via .NET 渲染 GLB 和 GLTF 动画帧,且没有评估限制。要在您的 Python 应用程序中应用许可证,请遵循Aspose.3D 许可指南。
免费学习资源
探索以下资源,深入了解如何加载动画 3D 模型、使用动画剪辑以及使用 Aspose.3D for Python via .NET 渲染 3D 场景:
- Aspose.3D for Python Developer Guide – 了解如何在 Python 中加载、修改、动画化和渲染 3D 模型。
- Render 3D Scenes to Images – 了解如何配置相机并将 3D 场景渲染为图像文件。
- Aspose.3D Python API Reference – 探索用于动画剪辑、场景渲染、相机和 3D 文件处理的类和方法。
- Free Online 3D Applications – 在浏览器中直接查看、转换和处理受支持的 3D 模型。
- Aspose.3D Tutorials and Articles – 查找涵盖 GLB/GLTF 动画、关键帧评估以及其他 3D 处理任务的实用 Python 教程。
结论
您可以通过对动画时间轴进行采样并在每个选定的时间戳渲染场景来生成帧图像。使用编号的 PNG 来创建缩略图、比较姿势,或为其他工具准备图像序列。如果您需要数值动画数据而不是图像,请参阅关键帧评估教程。如遇渲染问题,请访问Aspose.3D 支持论坛。
