video.py 7.66 KB
Newer Older
Shiven Bhatt's avatar
Shiven Bhatt committed
1
from manim import *
Shiven Bhatt's avatar
Shiven Bhatt committed
2
from matplotlib.lines import Line2D
Shiven Bhatt's avatar
Shiven Bhatt committed
3

Shiven Bhatt's avatar
Shiven Bhatt committed
4
SCREEN_WIDTH = 14.2
Ethan Fisher's avatar
Ethan Fisher committed
5
SCREEN_HEIGHT = 8
Shiven Bhatt's avatar
Shiven Bhatt committed
6

Shiven Bhatt's avatar
Shiven Bhatt committed
7
8
9
10
11
class Slide:
    def __init__(self, objects, durations):
        self.objects = objects
        self.durations = durations

12
class Slides(Scene):
Shiven Bhatt's avatar
Shiven Bhatt committed
13
    def construct(self):
Shiven Bhatt's avatar
Shiven Bhatt committed
14
        def get_spaced_text(text, im, spacing=0.5, font_size=90):
Ethan Fisher's avatar
Ethan Fisher committed
15
            spacer = Text("d",font_size=90).scale(spacing).align_to(im,DOWN)
Shiven Bhatt's avatar
Shiven Bhatt committed
16
            return Text(text,color="white",font_size=font_size).scale(0.5).next_to(spacer, UP)
17
18
19
20
21
22
23
24

        def get_sphere_slide(im_path, text, durations):
            im = ImageMobject(im_path).scale_to_fit_height(SCREEN_HEIGHT)
            return Slide([
                im,
                get_spaced_text(text, im)
            ], durations)

Ethan Fisher's avatar
Ethan Fisher committed
25
        cheapo_group = self.get_image_group(["monte_carlo_one.png", "monte_carlo_vando.png", "monte_carlo_many.png"])
Shiven Bhatt's avatar
Shiven Bhatt committed
26
27
28
29
30
31
32
33
        cheapo_group_text = "one sample                           random samples                            many samples"
        
        guru_text = '''
        “It is generally not so much about the fact that rasterisation couldn't do the things. 
         It probably could, but it would most likely need several rendering passes 
         and all kinds of dirty tricks to accomplish things that depend on nonlocal effects.” 
                                                                        - (stackexchange guru joojaa)
        '''
Ethan Fisher's avatar
anims    
Ethan Fisher committed
34
        
35
        slides = [
Shiven Bhatt's avatar
Shiven Bhatt committed
36
37
38
39
40
            ### INTRODUCTION ###
            # title slide here
            Slide([self.get_image_group(["raster_vs_raytrace.webp"])], [8]),

            ### RASTERIZATION ###
Ethan Fisher's avatar
anims    
Ethan Fisher committed
41
            # rasterization animation here [34]
Shiven Bhatt's avatar
Shiven Bhatt committed
42
43
            
            ### PROBLEMS ####
Shiven Bhatt's avatar
Shiven Bhatt committed
44
45
46
            get_sphere_slide("sad_sphere.png", "\"I'm not smooth\" :(", [3, 7]),
            Slide([self.get_image_group(["shadow.png", "glass.png"])], [25]),
            Slide([Text(guru_text,color="white",font_size=20)], [18]),
Shiven Bhatt's avatar
Shiven Bhatt committed
47
48

            ### RAYTRACING ###
Ethan Fisher's avatar
anims    
Ethan Fisher committed
49
50
            # raytracing animation goes here [15]
            Slide([self.get_image_group(["different_materials.png"])], [7]),
Shiven Bhatt's avatar
Shiven Bhatt committed
51
52
53

            ### PHYSICS ###
            Slide([self.get_image_group(["vindow_light_transfer.jpg"])], [1]),
Ethan Fisher's avatar
temp    
Ethan Fisher committed
54
55
            Slide([self.get_image_group(["vindow_light_transfer.jpg"])], [1]),
            Slide([self.get_image_group(["vindow_light_same.jpg"])], [1]),
Ethan Fisher's avatar
Ethan Fisher committed
56
            Slide([self.get_image_group(["vindow_function_angle.jpg"])], [1]),
Shiven Bhatt's avatar
Shiven Bhatt committed
57
58
59
60
61
62
63
64
65
            Slide([self.get_image_group(["rendering_eq.png"])], [1]),

            ### MONTE CARLO INTEGRATION ###
            Slide([self.get_image_group(["monte_carlo_img.png"])], [1]),
            Slide([self.get_image_group(["monte_carlo_eq1.png", "monte_carlo_eq2"])], [1]),

            ### MONTE CARLO RAYTRACING ###
            # graphic with integral over angle of incoming light????????

Ethan Fisher's avatar
Ethan Fisher committed
66
67
            Slide([self.get_image_height("monte_carlo_vando.png")], [1]),
            Slide([self.get_image_height("monte_carlo_bouncing.png")], [1]),
Shiven Bhatt's avatar
Shiven Bhatt committed
68
            Slide([cheapo_group, get_spaced_text(cheapo_group_text, cheapo_group, spacing=0, font_size=40)], [1,1]),
Ethan Fisher's avatar
Ethan Fisher committed
69
70
            Slide([self.get_image_height("monte_carlo_bouncing_infinite.png")], [1]),
            Slide([self.get_image_height("monte_carlo_path_tracing.png")], [1]),
Shiven Bhatt's avatar
Shiven Bhatt committed
71
72
73
74
75
76
77
78
79
80
81
82
83
            Slide([self.get_image_height("monte_carlo_path_tracing.png")], [1]),

            Slide([self.get_image_group(["different_materials.png"])], [1]),
            Slide([self.get_image_group(["mirror.png"])], [1]),
            get_sphere_slide("happy_sphere.png", "\"I'm smooth!\" :)", [1, 1]),
            Slide([self.get_image_group(["motion_blur.png"])], [1]),

            ### PATH TRACING ###
            # raytracing animation goes here

            ### CONCLUSION ###
            # title slide here
            Slide([self.get_image_group(["raster_vs_raytrace.webp"])], [1]),
84
85
        ]
        self.slideshow(slides)
Shiven Bhatt's avatar
Shiven Bhatt committed
86

Shiven Bhatt's avatar
Shiven Bhatt committed
87
    def slideshow(self, slides, fade_in_fade_out_time=1):
Shiven Bhatt's avatar
Shiven Bhatt committed
88
        for slide in slides:
Shiven Bhatt's avatar
Shiven Bhatt committed
89
            for i in range(0, len(slide.objects)):
Shiven Bhatt's avatar
Shiven Bhatt committed
90
                self.play(FadeIn(slide.objects[i]), run_time=fade_in_fade_out_time)
Shiven Bhatt's avatar
Shiven Bhatt committed
91
92
                self.wait(slide.durations[i])

Shiven Bhatt's avatar
Shiven Bhatt committed
93
            self.play(FadeOut(*slide.objects), run_time=fade_in_fade_out_time)
Shiven Bhatt's avatar
Shiven Bhatt committed
94

Shiven Bhatt's avatar
Shiven Bhatt committed
95
96
97
98
99
100
101
102
103
104
105
    def get_image_group(self, images):
        image_width = SCREEN_WIDTH / (len(images))
        all_images = []
        for image in images:
            im = ImageMobject(image)
            im.scale_to_fit_width(image_width)
            all_images.append(im)
    
        group = Group(*all_images)
        group.arrange()
        return group
Ethan Fisher's avatar
Ethan Fisher committed
106

Ethan Fisher's avatar
Ethan Fisher committed
107
108
109
    def get_image_height(self, path):
        return ImageMobject(path).scale_to_fit_height(SCREEN_HEIGHT)

Ethan Fisher's avatar
temp    
Ethan Fisher committed
110
111
112
113
114
115
116
117
118
119
120
121
class Title(Scene):
    def construct(self):
        t2 = Text("d",color="black",font_size=90).scale(0.25)
        t1 = Text("Carlo",color='#8080ff',font_size=90).scale(1).next_to(t2,UP)
        t0 = Text("Monte",color="pink",font_size=90).scale(1).next_to(t1,UP)
        t3 = Text("Ray",color="purple",font_size=90).scale(1).next_to(t2,DOWN)
        t4 = Text("Tracing",color="green",font_size=90).scale(1).next_to(t3,DOWN)
        self.wait(1)
        self.play(FadeIn(t0),lag_ratio=0.1,run_time=0.5)
        self.play(FadeIn(t1),lag_ratio=0.1,run_time=0.5)
        self.play(FadeIn(t3),lag_ratio=0.1,run_time=0.5)
        self.play(FadeIn(t4),lag_ratio=0.1,run_time=0.5)
Shiven Bhatt's avatar
Shiven Bhatt committed
122
        self.wait(1.5)
Ethan Fisher's avatar
anims    
Ethan Fisher committed
123
        self.play(FadeOut(t0,t1,t3,t4),lag_ratio=0.1,run_time=0.5)
Shiven Bhatt's avatar
merge    
Shiven Bhatt committed
124
        
Shiven Bhatt's avatar
Shiven Bhatt committed
125
126
127
128
129
130
131
class RasterizationTriangleScene(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=PI / 4, theta=PI / 6, gamma= PI / 2)
        cube = Cube(side_length=1)
        cube.shift([0, 0, 3])
        rect = Rectangle(width=7, height=5)
        rect.shift([-1, 0, -4])
Shiven Bhatt's avatar
Shiven Bhatt committed
132
133
        self.play(Create(rect), run_time=1)
        self.play(Create(cube), run_time=1)
134
135
        camera_plane = Text("camera plane",color="white",font_size=30)
        camera_plane.shift([1.5, 3, -4])
Shiven Bhatt's avatar
Shiven Bhatt committed
136
137
        self.play(Create(camera_plane), run_time=1)
        self.wait(7)
Shiven Bhatt's avatar
Shiven Bhatt committed
138

139
140
        normal = Line3D(start=[0.25, 0.25, 0], end=[0.25, 0.25, -1])
        normal.shift([-0.5, -0.5, 2.5])
Shiven Bhatt's avatar
Shiven Bhatt committed
141

Shiven Bhatt's avatar
Shiven Bhatt committed
142
143
        triangle = Polygon([0, 0, 0], [0, 1, 0], [1, 0, 0], stroke_width = 1, stroke_color=RED)
        triangle.shift([-0.5, -0.5, 2.5])
Shiven Bhatt's avatar
Shiven Bhatt committed
144
145
146
147
148
        self.play(Create(triangle), run_time=1)
        self.wait(2)
        self.play(Create(normal), run_time=1)
        self.wait(10)
        
Shiven Bhatt's avatar
Shiven Bhatt committed
149
150
        plane_triangle = Polygon([0, 0, 0], [0, 0.7, 0], [0.7, 0, 0], stroke_width = 1, stroke_color=RED)
        plane_triangle.shift([-0.35, -0.35, -4])
151
152
153
154
155

        remain_triangle = Polygon([0, 0, 0], [0, 1, 0], [1, 0, 0], stroke_width = 1, stroke_color=RED)
        remain_triangle.shift([-0.5, -0.5, 2.5])

        self.add(remain_triangle)
Shiven Bhatt's avatar
Shiven Bhatt committed
156
        self.play(Transform(triangle, plane_triangle))
Shiven Bhatt's avatar
Shiven Bhatt committed
157
        self.wait(3)
Shiven Bhatt's avatar
Shiven Bhatt committed
158
        self.move_camera(phi=PI, theta=0, gamma= PI / 2)
Shiven Bhatt's avatar
Shiven Bhatt committed
159
        self.wait(5)
Shiven Bhatt's avatar
Shiven Bhatt committed
160
161

class RaytracingScene(Scene):
162
163
    def construct(self):
        square = Square(side_length=3)
Shiven Bhatt's avatar
Shiven Bhatt committed
164
165
166
167
168
169
170
171
172
173
174
        square.shift([1, 1, 0])

        circle = Circle(radius=1.5)
        circle.shift([-3, -2, 0])

        triangle = Triangle()
        triangle.shift([1.5, -3, 0])

        lightbulb = ImageMobject("lightbulb.png")
        lightbulb.shift([-0.75, -3.5, 0])
        self.add(lightbulb)
Ethan Fisher's avatar
anims    
Ethan Fisher committed
175
176
177
178
        self.play(Create(square), run_time=1)
        self.play(Create(circle), run_time=1)
        self.play(Create(triangle), run_time=1)
        self.wait(3)
Shiven Bhatt's avatar
Shiven Bhatt committed
179
180
181
182
183
184
185
186
187

        light_rays = [
            ([-2, 5, 0], [-2, -0.85, 0]),
            ([-2, -0.85, 0], [1.4, -2.2, 0]),
            ([1.4, -2.2, 0], [0, -0.5, 0]),
            ([0, -0.5, 0], [-0.7, -3.3, 0])
        ]

        for ray in light_rays:
Ethan Fisher's avatar
anims    
Ethan Fisher committed
188
            self.play(Create(Line3D(start=ray[0], end=ray[1], color=YELLOW)), run_time=1)
Shiven Bhatt's avatar
Shiven Bhatt committed
189

Ethan Fisher's avatar
anims    
Ethan Fisher committed
190
        self.wait(5)
Shiven Bhatt's avatar
Shiven Bhatt committed
191