ManimGL

repository·master·Indexed 13 days ago

https://github.com/3b1b/manim

A programmatic animation engine designed by 3Blue1Brown for creating precise mathematical explanatory videos. ManimGL uses Python and OpenGL to leverage the GPU for higher efficiency, faster rendering speeds, and support for real-time rendering and interactive sessions.

Tokens
13.4K
Snippets
40
Records
60
Agent score
99%

What's inside ManimGL

  1. Understand Manim's directory structure

    master

    The manimlib/ directory contains the core logic of the library. Key subdirectories and files include:

    • scene/: Contains the base classes for creating animations, such as Scene (the basic class) and ThreeDScene.
    • mobject/: Contains all mathematical objects (Mobjects). This includes VMobject (vectorized mobjects), PMobject (point-based mobjects), SVGMobject, and specialized objects like Tex and Text.
    • animation/: Contains the logic for animating Mobjects, categorized by type (e.g., creation.py, movement.py, rotation.py, transform.py).
    • camera/: Handles the Camera and CameraFrame logic.
    • shaders/: Contains GLSL scripts used for rendering, including vertex and fragment shaders for surfaces, images, and curves.
    • utils/: A collection of utility functions for colors, bezier curves, file operations, and more.
    • default_config.yml: The default configuration file for the library.
    • config.py: Handles the processing of CLI flags.
    • tex_templates/: Preset LaTeX templates for rendering mathematical text.
  2. Understand the difference between 3b1b/manim and ManimCommunity/manim

    master

    There are two primary versions of Manim available. Choosing between them depends on your rendering needs and community preference:

    1. 3b1b/manim (the version this documentation refers to): Maintained by Grant Sanderson. It utilizes OpenGL and GLSL to leverage the GPU for rendering. This version is optimized for higher efficiency, faster rendering speeds, and supports real-time rendering and interactive sessions.

    2. ManimCommunity/manim: Maintained by the Manim Community Dev Team. It uses multiple backend rendering options and features more extensive documentation and an open contribution community.

  3. Understand frame, pixel, and buff constants

    master

    Several constants in manimlib/constants.py are dynamically determined by your configuration files (default_config.yml or custom_config.yml).

    Frame and Pixel Shape (determined by camera config):

    • ASPECT_RATIO
    • FRAME_HEIGHT, FRAME_WIDTH
    • FRAME_Y_RADIUS, FRAME_X_RADIUS
    • DEFAULT_PIXEL_HEIGHT, DEFAULT_PIXEL_WIDTH
    • DEFAULT_FPS

    Buffs (determined by size config):

    • SMALL_BUFF, MED_SMALL_BUFF, MED_LARGE_BUFF, LARGE_BUFF
    • DEFAULT_MOBJECT_TO_EDGE_BUFF
    • DEFAULT_MOBJECT_TO_MOBJECT_BUFF
  4. Identify core Animation types

    master

    Animations in Manim are used to change the state of Mobjects over time. They are located in manimlib/animation/ and include:

    • Creation: Animations related to creating an object (e.g., Create).
    • Movement: Animations related to moving objects.
    • Rotation: Animations related to rotating objects.
    • Transformations: Animations that morph one object into another (e.g., transform.py, transform_matching_parts.py).
    • Fading: Animations related to opacity (fading in/out).
    • Indication: Animations used for emphasis.
    • Update: Animations that realize updates from a function.
  5. Use coordinate constants for positioning

    master

    Manim uses three-dimensional coordinates represented as numpy.ndarray. You can use these constants to position Mobjects relative to the origin, axes, or frame edges.

    Directional Vectors:

    • ORIGIN: (0, 0, 0)
    • UP, DOWN, LEFT, RIGHT, IN, OUT
    • X_AXIS, Y_AXIS, Z_AXIS

    Diagonal Abbreviations:

    • UL (Upper Left): UP + LEFT
    • UR (Upper Right): UP + RIGHT
    • DL (Down Left): DOWN + LEFT
    • DR (Down Right): DOWN + RIGHT

    Frame Edges:

    • TOP: Top edge of the frame
    • BOTTOM: Bottom edge of the frame
    • LEFT_SIDE: Left edge of the frame
    • RIGHT_SIDE: Right edge of the frame
    # Example usage of coordinate constants
    obj.move_to(UP * 2 + RIGHT)
    obj.move_to(UL)
    obj.move_to(TOP)
  6. Work with Coordinate Systems and Axes

    master

    The Axes class allows you to create a coordinate system for placing Mobjects. You can define ranges for the x and y axes, set dimensions, and configure the appearance of the axes using axis_config or specific axis configurations like y_axis_config.

    Key features include:

    • Coordinate Mapping: Use axes.c2p(x, y) (short for coords_to_point) to convert mathematical coordinates to screen points, and axes.p2c(point) (short for point_to_coords) to do the reverse.
    • Labels: Use axes.add_coordinate_labels() to add numerical labels to the axes.
    • Dynamic Lines: Use axes.get_h_line(point) and axes.get_v_line(point) to create horizontal and vertical lines relative to a point. Wrapping these in always_redraw ensures they update as the point moves.
    • Coordinate Systems: Besides Axes, you can use ThreeDAxes, NumberPlane, and ComplexPlane.
    axes = Axes(
        x_range=(-1, 10),
        y_range=(-2, 2, 0.5),
        height=6,
        width=10,
        axis_config={
            "stroke_color": GREY_A,
            "stroke_width": 2,
        },
        y_axis_config={
            "include_tip": False,
        }
    )
    axes.add_coordinate_labels(font_size=20, num_decimal_places=1)
    
    dot = Dot(fill_color=RED)
    dot.move_to(axes.c2p(0, 0))
    
    # To keep lines attached to a moving dot:
    h_line = always_redraw(lambda: axes.get_h_line(dot.get_left()))
    v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom()))
  7. Use interactive mode with self.embed()

    master

    You can enable an interactive IPython terminal session at the end of your scene by calling self.embed() inside the construct() method. This allows you to execute commands live while the OpenGL window is open.

    When in interactive mode, self.play can be abbreviated to play.

    Example interactive commands:

    • play(circle.animate.stretch(4, dim=0))
    • play(Rotate(circle, TAU / 4))
    • play(circle.animate.shift(2 * RIGHT), circle.animate.scale(0.25))
    • play(circle.animate.apply_complex_function(lambda z: z**2))
    • exit() to close the session.
    from manimlib import *
    
    class SquareToCircle(Scene):
        def construct(self):
            circle = Circle()
            self.add(circle)
            # ... other code ...
            self.embed()
  8. Use Updaters to create dynamic Mobjects

    master

    Updaters allow you to run code every frame to ensure a Mobject responds to changes in other objects or its own properties.

    Common Updater Patterns

    1. .add_updater(func): The most direct way. The function func is called every frame. It can take one argument (the mobject itself) or two (the mobject and the time elapsed since the last frame).

      • Example: mob1.add_updater(lambda mob: mob.next_to(mob2))
    2. always(f, x): A convenience function that executes f(x) every frame. This is useful for positioning.

      • Example: always(label.next_to, brace, UP)
    3. f_always(f, g): Similar to always, but it executes f(g()) every frame. This is useful when the argument to the function is itself a method call that needs to be re-evaluated.

      • Example: f_always(number.set_value, square.get_width)
    4. always_redraw(func, *args): Creates a new Mobject from scratch every single frame. This is ideal for complex shapes (like a Brace) that need to be recalculated based on the geometry of another object.

    # 1. always_redraw for a brace that follows a square
    brace = always_redraw(Brace, square, UP)
    
    # 2. always for positioning a label
    always(label.next_to, brace, UP)
    
    # 3. f_always for updating a value based on a method call
    f_always(number.set_value, square.get_width)
    
    # 4. Manual add_updater for custom logic
    square.add_updater(lambda m: m.set_width(w0 * math.cos(self.time - now)))
  9. Identify core Mobject types

    master

    Mobjects (Mathematical Objects) are the building blocks of Manim. They are organized into several types within manimlib/mobject/:

    • VMobject: Vectorized Mobjects (found in vectorized_mobject.py).
    • PMobject: Point-based Mobjects (found in point_cloud_mobject.py), which are composed of points.
    • SVGMobject: Mobjects created from SVG files.
    • Tex/Text: Mathematical text implemented via LaTeX (tex_mobject.py) or standard text implemented via ManimPango (text_mobject.py).
    • Specialized Mobjects: Includes ParametricFunction, NumberLine, VectorField, and Matrix.
  10. Choose between ManimGL and Manim Community

    master

    Before contributing, determine which version of Manim your changes are intended for:

    • ManimGL (this repository): Use this if your changes are specific to OpenGL rendering, interactive workflows, or the specific needs of 3Blue1Brown videos. Note that pull request reviews may take longer here.
    • Manim Community: Use ManimCommunity/manim for broad community features, packaging changes, or beginner-oriented documentation. This version has a larger contributor workflow and more active community review.
  11. Configure Coordinate Systems and NumberLines using ranges

    master

    Coordinate systems (including Axes, ThreeDAxes, NumberPlane, and ComplexPlane) and NumberLine no longer use individual min/max parameters. Instead, use the x_range and y_range parameters.

    These parameters must be a numpy.array containing three values: [Minimum, Maximum, Step Size].

    Example for Axes:

    axes = Axes(x_range=[ -5, 5, 1], y_range=[ -3, 3, 0.5])

    For NumberLine, the x_range follows the same [min, max, step] format. Note that tip_width and tip_height have been replaced by a tip_config dictionary.

    axes = Axes(x_range=[-5, 5, 1], y_range=[-3, 3, 0.5])