ManimCommunity / ManimCommunity/manim

Significant performance issues compared to manimgl with the opengl renderer.

Open
#1,957 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

issue:bug opengl performance
Dominant language
Python
Stars
40.9k
Forks
3.1k
Avg merge
3d 12h
Merged PRs (30d)
25

Description

## Description of bug / unexpected behavior

Running the [ SinCurveUnitCircle example](https://docs.manim.community/en/stable/examples.html#sinecurveunitcircle
) with manimce using the following input:
```py
manim mkt.py --renderer=opengl SineCurveUnitCircle --write_to_movie --disable_caching
```
Results in the video taking an extremely long time to render, at around 36 seconds total. Interestingly enough, a 1 second `self.wait()` call took 4 seconds to render. This is even slower than cairo, which clocks in at ~24 seconds. See below for the videos I recorded of the rendering process.

### manimgl speeds
Comparing these speeds to manimgl, it becomes a little more apparent how slow our opengl rendering is. Writing to file takes ~8 seconds on manimgl, meaning that our opengl rendering is ~5x slower than manimgl in this particular case on my machine.

While these specific times may vary due to background tasks etc... , manimgl universally performs much better than manimce by a very large margin.

## Expected behavior

Comparable speeds between manimgl and manimce's opengl rendering. At the very least faster than cairo.

## How to reproduce the issue

Here's the manimgl compatible code if you're interested in running the scene in manimgl.

Code for reproducing the problem

```py
class SineCurveUnitCircle(Scene):
# contributed by heejin_park, https://infograph.tistory.com/230
def construct(self):
self.show_axis()
self.show_circle()
self.move_dot_and_draw_curve()
self.wait()

def show_axis(self):
x_start = np.array([-6,0,0])
x_end = np.array([6,0,0])

y_start = np.array([-4,-2,0])
y_end = np.array([-4,2,0])

x_axis = Line(x_start, x_end)
y_axis = Line(y_start, y_end)

self.add(x_axis, y_axis)
self.add_x_labels()

self.origin_point = np.array([-4,0,0])
self.curve_start = np.array([-3,0,0])

def add_x_labels(self):
x_labels = [
Tex("\pi"), Tex("2 \pi"),
Tex("3 \pi"), Tex("4 \pi"),
]

for i in range(len(x_labels)):
x_labels[i].next_to(np.array([-1 + 2*i, 0, 0]), DOWN)
self.add(x_labels[i])

def show_circle(self):
circle = Circle(radius=1)
circle.move_to(self.origin_point)
self.add(circle)
self.circle = circle

def move_dot_and_draw_curve(self):
orbit = self.circle
origin_point = self.origin_point

dot = Dot(radius=0.08, color=YELLOW)
dot.move_to(orbit.point_from_proportion(0))
self.t_offset = 0
rate = 0.25

def go_around_circle(mob, dt):
self.t_offset += (dt * rate)
# print(self.t_offset)
mob.move_to(orbit.point_from_proportion(self.t_offset % 1))

def get_line_to_circle():
return Line(origin_point, dot.get_center(), color=BLUE)

def get_line_to_curve():
x = self.curve_start[0] + self.t_offset * 4
y = dot.get_center()[1]
return Line(dot.get_center(), np.array([x,y,0]), color=YELLOW_A, stroke_width=2 )

self.curve = VGroup()
self.curve.add(Line(self.curve_start,self.curve_start))
def get_curve():
last_line = self.curve[-1]
x = self.curve_start[0] + self.t_offset * 4
y = dot.get_center()[1]
new_line = Line(last_line.get_end(),np.array([x,y,0])).set_color(YELLOW_D)
self.curve.add(new_line)

return self.curve

dot.add_updater(go_around_circle)

origin_to_circle_line = always_redraw(get_line_to_circle)
dot_to_curve_line = always_redraw(get_line_to_curve)
sine_curve_line = always_redraw(get_curve)

self.add(dot)
self.add(orbit, origin_to_circle_line, dot_to_curve_line, sine_curve_line)
self.wait(8.5)

dot.remove_updater(go_around_circle)

```

## Additional media files

ManimCE + ManimGL rendering videos below:
Images/GIFs

https://user-images.githubusercontent.com/70682032/130609421-5437cfb3-f631-4914-83d3-e30a843de657.mp4

https://user-images.githubusercontent.com/70682032/130609444-a6587558-346c-4fb4-9203-10b80ab7e52e.mp4

## System specifications

- OS: Windows 11
- Python version: 3.9

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the SineCurveUnitCircle example from mkt.py with --renderer=opengl and --disable_caching, then compare its render time with cairo. Investigate the OpenGL rendering path around the updater and always_redraw usage shown in the reproduction. Done means the example renders at least faster than cairo and approaches the reported manimgl performance.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.