Files
calesthioandHanzo Dev 7ffb943132 Initial release — OpenMontage: the first open-source agentic video production system
11 production pipelines, 47 tools, 124 agent skills.
Supports cloud APIs (fal.ai, OpenAI, ElevenLabs, Suno, HeyGen, Runway) and
free local providers (diffusers, Piper TTS, WAN 2.1, Hunyuan, CogVideo).

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-29 08:25:17 -07:00

5.9 KiB

name, description, metadata
name description metadata
3d ThreeDScene, 3D objects, surfaces, and 3D camera
tags
3d, threedscene, surface, sphere, cube, camera

3D Graphics in Manim

Create 3D visualizations with ThreeDScene.

ThreeDScene Basics

from manim import *

class Basic3D(ThreeDScene):
    def construct(self):
        # Set camera angle
        self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)

        # Add 3D axes
        axes = ThreeDAxes()
        self.add(axes)

Camera Orientation

class CameraOrientation(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()

        # phi: angle from z-axis (0 = top view, 90 = side view)
        # theta: rotation around z-axis
        # gamma: roll angle

        self.set_camera_orientation(
            phi=75 * DEGREES,
            theta=-45 * DEGREES,
            gamma=0
        )

        self.add(axes)

Animated Camera Movement

class AnimatedCamera(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.add(axes)

        self.set_camera_orientation(phi=75*DEGREES, theta=0)

        # Animate camera movement
        self.move_camera(phi=45*DEGREES, theta=90*DEGREES, run_time=3)

Continuous Camera Rotation

class RotatingCamera(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()
        self.add(axes)

        self.set_camera_orientation(phi=75*DEGREES, theta=0)

        # Start ambient rotation
        self.begin_ambient_camera_rotation(rate=0.2)
        self.wait(5)
        self.stop_ambient_camera_rotation()

3D Primitives

Sphere

class SphereExample(ThreeDScene):
    def construct(self):
        sphere = Sphere(radius=1, resolution=(20, 20))
        sphere.set_color(BLUE)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(sphere)

Cube / Prism

class CubeExample(ThreeDScene):
    def construct(self):
        cube = Cube(side_length=2, fill_opacity=0.8)
        cube.set_color(RED)

        # Rectangular prism
        prism = Prism(dimensions=[3, 1, 2])

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(cube)

Cylinder / Cone

class CylinderCone(ThreeDScene):
    def construct(self):
        cylinder = Cylinder(radius=1, height=2, fill_opacity=0.8)
        cone = Cone(base_radius=1, height=2, fill_opacity=0.8)

        cylinder.shift(LEFT * 2)
        cone.shift(RIGHT * 2)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(cylinder, cone)

Torus

class TorusExample(ThreeDScene):
    def construct(self):
        torus = Torus(major_radius=2, minor_radius=0.5)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(torus)

3D Axes

class ThreeDAxesExample(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes(
            x_range=[-4, 4, 1],
            y_range=[-4, 4, 1],
            z_range=[-4, 4, 1],
            x_length=8,
            y_length=8,
            z_length=6,
        )

        # Add axis labels
        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(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(axes, x_label, y_label, z_label)

Surface Plots

class SurfacePlot(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes(x_range=[-3, 3], y_range=[-3, 3], z_range=[-2, 2])

        # Function 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(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(axes, surface)

Surface Class (standalone)

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_opacity=0.8,
        )
        surface.set_color_by_gradient(BLUE, GREEN)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(surface)

3D Parametric Curves

class ParametricCurve3D(ThreeDScene):
    def construct(self):
        # Helix
        curve = ParametricFunction(
            lambda t: np.array([
                np.cos(t),
                np.sin(t),
                t * 0.2
            ]),
            t_range=[-4*PI, 4*PI],
            color=YELLOW
        )
        curve.set_shade_in_3d(True)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(ThreeDAxes(), curve)

Shading in 3D

class Shading3D(ThreeDScene):
    def construct(self):
        sphere = Sphere()

        # Enable shading for realistic lighting
        sphere.set_shade_in_3d(True)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(sphere)

Arrow3D and Line3D

class Vectors3D(ThreeDScene):
    def construct(self):
        axes = ThreeDAxes()

        arrow = Arrow3D(ORIGIN, [2, 1, 2], color=RED)
        line = Line3D(ORIGIN, [-2, 1, 1], color=BLUE)

        self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES)
        self.add(axes, arrow, line)

Best Practices

  1. Always set camera orientation - Default view may not show 3D well
  2. Use set_shade_in_3d for realism - Adds depth perception
  3. Use ambient camera rotation sparingly - Can be disorienting
  4. Match resolution to detail needed - Higher res = slower render
  5. Use colorscale for surfaces - Shows elevation/value changes