
OpenMontage 中的 ManimCE 3D 图形实战ThreeDScene、曲面与三维相机完全指南【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage导读本文基于 OpenMontage 仓库内manimce-best-practices技能包中的 3D 规则文档rules/3d.md系统讲解如何在 Manim Community EditionManimCE中使用ThreeDScene构建三维可视化从相机姿态控制、三维几何体与坐标系到曲面绘图、参数曲线与着色技巧。文章同时结合仓库内的可运行示例examples/3d_visualization.py、场景模板templates/threed_scene.py以及项目中封装 ManimCE 的math_animate工具tools/graphics/math_animate.py让读者既能直接复制代码渲染出自己的 3D 数学动画也能理解其在 OpenMontage 视频生产管线中的落地方式。为什么在 OpenMontage 中要掌握 ThreeDSceneOpenMontage 是一个开源的 Agentic 视频生产系统其math_animate工具tools/graphics/math_animate.py通过 ManimCE 在本地免费生成数学/科学/讲解类动画视频。仓库的 ManimCE 使用指南skills/creative/manim-usage.md给出了一条明确的取舍原则默认使用 2D只有当空间关系本身就是概念时才使用 3D——例如可视化曲面z f(x,y)、体积、三维向量场、叉积与法向量或需要通过相机环绕揭示隐藏结构时。也就是说ThreeDScene不是更酷的 2D而是专门服务于那些必须在三维空间中才能讲清楚的知识点。掌握本文的内容意味着你可以在 OpenMontage 中产出一类独特的、二维动画难以表达的内容旋转的黎曼曲面、三维向量场、Lorenz 吸引子等。仓库自带的 Lorenz 吸引子示例examples/lorenz_attractor.py就是 3D 场景的典型应用。另外需要注意OpenMontage 的这套 3D 规则面向ManimCEfrom manim import *、manimCLI而非 3Blue1Brown 的 ManimGL 版本from manimlib import *、manimglCLI。两者的 API 与 CLI 均不相同使用前请先确认版本。ThreeDScene 基础第一个三维场景ThreeDScene是 ManimCE 中承载三维内容的场景类。与普通Scene不同它拥有一个可以在三维空间中自由摆位的相机因此每个场景的第一步几乎都是设置相机姿态否则默认视角往往无法良好呈现三维内容。from manim import * class Basic3D(ThreeDScene): def construct(self): # 设置相机角度phi 为相对 z 轴的俯仰角theta 为绕 z 轴的水平旋转角 self.set_camera_orientation(phi75 * DEGREES, theta-45 * DEGREES) # 添加三维坐标轴 axes ThreeDAxes() self.add(axes)渲染命令来自仓库 rules/cli.md 的通用约定# 低质量预览开发阶段迭代最快 manim -pql 3d_visualization.py Basic3D # 高质量最终输出1080p60 manim -pqh 3d_visualization.py Basic3D相机姿态phi、theta 与 gamma三维场景的视觉成败取决于相机姿态。ManimCE 使用球坐标来描述相机方向class CameraOrientation(ThreeDScene): def construct(self): axes ThreeDAxes() # phi: 从 z 轴算起的俯仰角0 俯视图90 侧视图 # theta: 绕 z 轴的水平旋转角 # gamma: 滚动角画面自身的旋转 self.set_camera_orientation( phi75 * DEGREES, theta-45 * DEGREES, gamma0 ) self.add(axes)参数语义速查参数含义典型取值phi相对 z 轴的俯仰角0为俯视90为侧视60~75度是最常用的略带俯视视角theta绕 z 轴的旋转角-45度能同时看到三个轴面是文档示例中最常见的默认值gamma画面滚动角默认0一般保持不动仓库的 3D 场景模板templates/threed_scene.py把相机设置作为场景的固定步骤并建议在此基础上再叠加轴与物体。动画式相机移动move_camera可以在播放过程中平滑地把相机从当前姿态动画到目标姿态class AnimatedCamera(ThreeDScene): def construct(self): axes ThreeDAxes() self.add(axes) self.set_camera_orientation(phi75*DEGREES, theta0) # 动画移动相机run_time 控制过渡时长 self.move_camera(phi45*DEGREES, theta90*DEGREES, run_time3)三维空间感的建立往往依赖相机移动固定的俯视角会让 3D 退化成透视的 2D而一段平滑的环绕运动能立刻让观众理解物体的空间结构。仓库示例 examples/3d_visualization.py 中的CameraMovement3D场景还演示了通过zoom参数实现推拉# 放大zoom 1 self.move_camera(zoom1.5, run_time1) # 缩小 self.move_camera(zoom0.7, run_time1)持续环绕旋转begin_ambient_camera_rotation/stop_ambient_camera_rotation让相机以恒定角速度持续环绕适合在观众自由欣赏复杂曲面时提供 360° 的观察角度class RotatingCamera(ThreeDScene): def construct(self): axes ThreeDAxes() self.add(axes) self.set_camera_orientation(phi75*DEGREES, theta0) # 开始环境旋转rate 为每秒弧度数 self.begin_ambient_camera_rotation(rate0.2) self.wait(5) self.stop_ambient_camera_rotation()rate的单位是弧度/秒0.2左右约为每秒 11 度较为舒缓仓库示例常用的取值区间是0.1~0.3。注意规则文档与模板都反复提醒环绕旋转要克制使用详见文末最佳实践过快的环绕会让观众眩晕。三维几何体球体、立方体、圆柱、圆锥与圆环ManimCE 提供了完整的三维基本体均可直接set_color、设置fill_opacity并通过shift摆位。球体Sphereclass SphereExample(ThreeDScene): def construct(self): # radius: 半径resolution: 经纬网格密度越高越圆滑但越慢 sphere Sphere(radius1, resolution(20, 20)) sphere.set_color(BLUE) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(sphere)立方体与长方体Cube / Prismclass CubeExample(ThreeDScene): def construct(self): cube Cube(side_length2, fill_opacity0.8) cube.set_color(RED) # 长方体dimensions 依次为 x、y、z 边长 prism Prism(dimensions[3, 1, 2]) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(cube)三维物体的实心感来自fill_opacity设置为0.7~0.8既能看清体积又不至于遮挡背后的结构。圆柱与圆锥Cylinder / Coneclass CylinderCone(ThreeDScene): def construct(self): cylinder Cylinder(radius1, height2, fill_opacity0.8) cone Cone(base_radius1, height2, fill_opacity0.8) cylinder.shift(LEFT * 2) cone.shift(RIGHT * 2) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(cylinder, cone)注意圆锥的参数名是base_radius而非radius这是容易踩坑的细节。圆环Torusclass TorusExample(ThreeDScene): def construct(self): # major_radius: 环的总体半径minor_radius: 环管截面半径 torus Torus(major_radius2, minor_radius0.5) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(torus)仓库示例 examples/3d_visualization.py 的Basic3DScene展示了一次组合用法球、立方体、圆锥同屏摆放用Create逐个体动画出现再启动环境旋转让观众从各个角度观察sphere Sphere(radius1, colorBLUE) cube Cube(side_length1.5, colorRED, fill_opacity0.7) cone Cone(base_radius0.8, height1.5, colorGREEN) sphere.shift(LEFT * 3) cone.shift(RIGHT * 3) self.play(Create(sphere), Create(cube), Create(cone)) self.wait()三维坐标系ThreeDAxes 与轴标签ThreeDAxes是三维场景的坐标系骨架。与 2D 的Axes类似它通过x_range/y_range/z_range定义三个方向的数值范围与步长用x_length/y_length/z_length控制渲染尺寸class ThreeDAxesExample(ThreeDScene): def construct(self): axes ThreeDAxes( x_range[-4, 4, 1], y_range[-4, 4, 1], z_range[-4, 4, 1], x_length8, y_length8, z_length6, ) # 添加轴标签 x_label axes.get_x_axis_label(x) y_label axes.get_y_axis_label(y) z_label axes.get_z_axis_label(z) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(axes, x_label, y_label, z_label)一个关键技巧来自模板与示例轴标签会随三维场景一起旋转文字可能被转到难以阅读的角度。解决方式是用add_fixed_in_frame_mobjects把标签钉在屏幕上——它与 2D 覆盖文字一样不随 3D 相机旋转。仓库的ThreeDAxesExampleexamples/3d_visualization.py同时使用了两种风格# 随 3D 场景旋转的轴标签 x_label axes.get_x_axis_label(rx) ... self.play(Create(axes)) self.add_fixed_orientation_mobjects(x_label, y_label, z_label) # 或者用 get_axis_labels 一次性生成并直接 add模板风格 axis_labels axes.get_axis_labels(x_labelx, y_labely, z_labelz)此外axes.c2p(x, y, z)可以把坐标系中的数值坐标转换为场景中的像素坐标是在 3D 场景中精确放置点、线、点阵的核心 APIpoint Dot3D(axes.c2p(2, 1, 1.5), colorRED, radius0.1) self.play(Create(point))曲面绘图plot_surface 与 Surface曲面是ThreeDScene最具表现力的内容类型适合呈现二元函数z f(x, y)的形态。在坐标系上绘图plot_surfaceclass SurfacePlot(ThreeDScene): def construct(self): axes ThreeDAxes(x_range[-3, 3], y_range[-3, 3], z_range[-2, 2]) # 函数 z f(x, y) surface axes.plot_surface( lambda u, v: np.sin(u) * np.cos(v), u_range[-3, 3], v_range[-3, 3], resolution(30, 30), colorscale[BLUE, GREEN, YELLOW, RED], ) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(axes, surface)colorscale按高度着色能直观传达高程/数值变化这是规则文档推荐的做法。独立 Surface 类不依赖axes时可以直接构造Surface传入参数化函数(u, v) - (x, y, z)class SurfaceExample(ThreeDScene): def construct(self): def param_func(u, v): x u y v z np.sin(np.sqrt(u**2 v**2)) return np.array([x, y, z]) surface Surface( param_func, u_range[-3, 3], v_range[-3, 3], resolution(30, 30), fill_opacity0.8, ) surface.set_color_by_gradient(BLUE, GREEN) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(surface)常用参数说明参数含义建议u_range/v_range参数域范围与被展示函数的定义域一致resolution网格密度(u方向, v方向)细节越多越精细但渲染越慢20~30是常用区间fill_opacity面片不透明度0.6~0.8兼顾体积感与内部透视set_color_by_gradient按参数渐变着色比单色更能表现高度变化仓库示例中还有几个值得借鉴的曲面模式马鞍面lambda u, v: axes.c2p(u, v, u ** 2 - v ** 2)用c2p把函数值接入坐标系ParametricSurfaceExample参数化球面直接用球坐标参数式构造Surface并set_color_by_gradient(BLUE_E, BLUE, TEAL)SphereVisualization动态曲面用ValueTracker作时间参数、配合always_redraw实时重建曲面实现随时间传播的波动效果AnimatedSurfacetime ValueTracker(0) surface always_redraw( lambda: Surface( lambda u, v: axes.c2p( u, v, np.sin(np.sqrt(u ** 2 v ** 2) - time.get_value()) ), u_range[-3, 3], v_range[-3, 3], resolution(25, 25), ).set_color_by_gradient(BLUE, TEAL) ) self.play(time.animate.set_value(4 * PI), run_time8, rate_funclinear)三维参数曲线螺旋线与任意空间曲线用ParametricFunction可以绘制任意三维空间曲线其核心是返回[x(t), y(t), z(t)]的向量函数class ParametricCurve3D(ThreeDScene): def construct(self): # 螺旋线 curve ParametricFunction( lambda t: np.array([ np.cos(t), np.sin(t), t * 0.2 ]), t_range[-4*PI, 4*PI], colorYELLOW ) curve.set_shade_in_3d(True) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(ThreeDAxes(), curve)三维线条默认是平面描边的set_shade_in_3d(True)让线条根据其在空间中的朝向呈现明暗变化从而获得立体感——这是三维曲线以及所有三维物体获得真实感的关键开关。仓库的 examples/lorenz_attractor.py 展示了三维曲线的进阶用法用scipy.integrate.solve_ivp求解 Lorenz 混沌系统的 ODE把解点经axes.c2p换算后通过VMobject().set_points_smoothly(...)生成三维轨迹再配合Dot3D、MoveAlongPath与TracedPath制作小球沿混沌轨迹爬行并拖出尾迹的动画——这是 3D 场景与科学计算结合的完整范例。三维着色set_shade_in_3d平面填充物体如Sphere默认呈现均匀单色缺少立体感。开启着色后ManimCE 会根据物体表面法向与相机方向模拟光照产生明暗过渡class Shading3D(ThreeDScene): def construct(self): sphere Sphere() # 开启着色以获得真实光照效果 sphere.set_shade_in_3d(True) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(sphere)规则文档明确建议用set_shade_in_3d增强真实感它增加深度感知。这条原则同时适用于几何体、曲线与曲面示例中的螺旋线就开启了着色。三维向量Arrow3D 与 Line3D在三维空间中表达方向关系向量场、连接线、作用力方向时使用Arrow3D和Line3Dclass Vectors3D(ThreeDScene): def construct(self): axes ThreeDAxes() arrow Arrow3D(ORIGIN, [2, 1, 2], colorRED) line Line3D(ORIGIN, [-2, 1, 1], colorBLUE) self.set_camera_orientation(phi75*DEGREES, theta-45*DEGREES) self.add(axes, arrow, line)Arrow3D的参数是一对三维点坐标起点、终点与 2D 的Arrow起点、方向向量语义不同。仓库示例的VectorField3D场景演示了一个完整的三维向量场可视化遍历网格点用c2p定位起点按向量场公式F (-y, x, z)计算终点并用interpolate_color按 z 值在蓝红之间着色最后用LaggedStart让箭头逐个出现arrow Arrow3D( startstart, endend, colorinterpolate_color(BLUE, RED, (z 2) / 4), ) ... self.play(LaggedStart(*[Create(a) for a in arrows], lag_ratio0.02))让文字与公式钉在屏幕上3D 场景中的文字会随相机旋转除非你希望它作为空间中的标签存在。规则的配套资料模板 templates/threed_scene.py 与示例TextIn3D给出标准做法用add_fixed_in_frame_mobjects把标题、公式放到屏幕固定位置使其不随 3D 相机旋转title Text(3D Visualization, font_size48) title.to_corner(UL) self.add_fixed_in_frame_mobjects(title) equation MathTex(rz x^2 y^2) equation.to_corner(UR) self.add_fixed_in_frame_mobjects(equation)Lorenz 示例同样用add_fixed_in_frame_mobjects(equations)把微分方程组常驻在左上角让观众在看轨迹的同时始终能对照公式。渲染与落地在 OpenMontage 中运行 3D 场景质量档位与开发流程根据 rules/cli.md 与 skills/creative/manim-usage.mdManimCE 的质量档位如下标志分辨率帧率用途-ql854x48015开发/快速迭代-qm1280x72030草稿评审-qh1920x108060标准成片如 YouTube 横屏 1080p-qp2560x144060高质量导出-qk3840x2160604K 存档/高端推荐的开发流程是从快到慢先用manim -pql scene.py SceneName快速迭代再用-qm复查最终以-qh出片。若需要 GIF 便于嵌入演示可用manim --format gif -qm scene.py SceneName只想截取最后一帧做缩略图则用manim -s scene.py SceneName。通过 math_animate 工具直接渲染OpenMontage 的math_animate工具tools/graphics/math_animate.py封装了完整的 ManimCE 渲染链路Agent 可以直接把 3D 场景代码作为scene_code传入无需手工管理 CLI。该工具自动补充from manim import *若缺失自动检测场景类名支持Scene | ThreeDScene | MovingCameraScene | ZoomedScene见其_detect_scene_name实现通过quality参数low/medium/high/4k/preview映射到上表的质量标志并支持formatmp4/gif/png/webm、background_color、transparent等参数对调用方提供的场景代码执行静态安全检查默认拒绝os、subprocess、socket、网络库等危险导入以及eval、exec、open、__builtins__和各类反射 dunder 访问详见 tests/tools/test_math_animate_safety.py 的回归用例确需放行时才显式设置allow_unsafe_codetrue。这意味着把本文的任意ThreeDScene类作为scene_code传入math_animate即可在 OpenMontage 中生成三维数学动画且渲染完全本地、免费、无需 API Key工具的estimate_cost恒为0.0。性能注意事项从仓库资料看ManimCE 的 3D 走 Cairo 渲染路径CLI 中也可用--renderer opengl切换 OpenGL 渲染器以获得更快的 3D 预览整体比 2D 慢。因此默认 2D必要时才 3D——这是 manim-usage.md 的首要原则曲面resolution匹配所需细节即可文档建议高分辨率更慢渲染用-ql做开发迭代把-qh/-qk留给最终渲染math_animate工具内置 300 秒渲染超时复杂 3D 场景建议先用low或preview质量试跑。最佳实践清单规则文档 rules/3d.md 在文末给出了五条经验法则这里结合仓库配套资料逐条展开始终设置相机姿态——默认视角通常无法良好展现 3D 内容仓库中所有示例、模板的第一步都是set_camera_orientation。最稳妥的起步值是phi75*DEGREES, theta-45*DEGREES。用set_shade_in_3d增强真实感——它增加深度感知让球体、曲线、曲面呈现明暗过渡而非扁平色块规则与示例均将其作为标准步骤。克制使用环境旋转——begin_ambient_camera_rotation会持续旋转画面容易让观众眩晕用短时wait配合低速rate如0.1~0.2并在需要时stop_ambient_camera_rotation停住。相机规则文件rules/camera.md同样提醒3D 相机旋转要节制。分辨率匹配细节需求——Sphere(resolution...)、Surface(resolution...)越高越精细但渲染越慢先低后高避免迭代期卡死在渲染上。曲面用渐变色——colorscale或set_color_by_gradient能直观显示高程/数值变化比单色曲面信息量大得多。此外将 3D 场景整合进 OpenMontage 的视频管线时还应遵循 manim-usage.md 的通用规范深色背景BLACK或#1a1a2e、一次只揭示 3~4 个新视觉元素、大概念拆分成多个场景、关键呈现后self.wait(1.5)并让场景总时长与解说词分段时长对齐。相关资源索引规则文档.claude/skills/manimce-best-practices/rules/3d.md本文主体来源可运行示例.claude/skills/manimce-best-practices/examples/3d_visualization.py含马鞍面、参数球面、向量场、动态曲面、3D 文字等 9 个场景Lorenz 吸引子.claude/skills/manimce-best-practices/examples/lorenz_attractor.py3D 场景模板.claude/skills/manimce-best-practices/templates/threed_scene.py相机控制规则.claude/skills/manimce-best-practices/rules/camera.mdCLI 与渲染规则.claude/skills/manimce-best-practices/rules/cli.md技能总览.claude/skills/manimce-best-practices/SKILL.mdOpenMontage 内 ManimCE 使用规范skills/creative/manim-usage.md渲染工具实现tools/graphics/math_animate.py安全扫描测试tests/tools/test_math_animate_safety.py【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考