-
Ethan Fisher authored5eb5866f
video.py 7.82 KiB
from manim import *
from matplotlib.lines import Line2D
SCREEN_WIDTH = 14.2
SCREEN_HEIGHT = 8
class Slide:
def __init__(self, objects, durations):
self.objects = objects
self.durations = durations
class Slides(Scene):
def construct(self):
def get_spaced_text(text, im, spacing=0.5, font_size=90):
spacer = Text("d",font_size=90).scale(spacing).align_to(im,DOWN)
return Text(text,color="white",font_size=font_size).scale(0.5).next_to(spacer, UP)
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)
cheapo_group = self.get_image_group(["monte_carlo_one.png", "monte_carlo_vando.png", "monte_carlo_many.png"])
cheapo_group_text = "one sample random samples many samples"
cheapo_group_description = "too simple just right too expensive"
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)
'''
slides = [
### INTRODUCTION ###
# title slide here [5]
Slide([self.get_image_group(["raster_vs_raytrace.webp"])], [8]),
### RASTERIZATION ###
# rasterization animation here [34]
### PROBLEMS ####
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]),
### RAYTRACING ###
# raytracing animation goes here [15]
Slide([self.get_image_height("different_materials.png")], [7]),
### PHYSICS ###
Slide([self.get_image_group(["vindow_light_transfer.jpg"])], [12]),
Slide([self.get_image_group(["vindow_light_same.jpg"])], [9]),
Slide([self.get_image_group(["vindow_function_angle.jpg"])], [15]),
Slide([self.get_image_group(["rendering_eq.png"])], [24]),
### MONTE CARLO INTEGRATION ###
Slide([self.get_image_height("monte_carlo_img.png")], [10]),
Slide([self.get_image_group(["monte_carlo_eq1.png", "monte_carlo_eq2"])], [22]),
### MONTE CARLO RAYTRACING ###
Slide([self.get_image_height("monte_carlo_integral.png")], [10]),
Slide([self.get_image_height("monte_carlo_question_mark.png")], [21]),
Slide([self.get_image_height("monte_carlo_vando.png")], [8]),
Slide([cheapo_group, get_spaced_text(cheapo_group_text, cheapo_group, spacing=1, font_size=60),get_spaced_text(cheapo_group_description, cheapo_group, spacing=0, font_size=60)], [3,3,17]),
Slide([self.get_image_height("monte_carlo_bouncing.png")], [10]),
Slide([self.get_image_height("monte_carlo_bouncing_infinite.png")], [10]),
Slide([self.get_image_height("different_materials.png")], [7]),
Slide([self.get_image_group(["mirror.png"])], [13]),
get_sphere_slide("happy_sphere.png", "\"I'm smooth!\" :)", [3, 15]),
Slide([self.get_image_group(["motion_blur.jpg"])], [10]),
### PATH TRACING ###
Slide([self.get_image_height("monte_carlo_path_tracing.png")], [23]),
# raytracing animation goes here [15]
### CONCLUSION ###
# title slide here [5]
Slide([self.get_image_group(["raster_vs_raytrace.webp"])], [7]),
]
self.slideshow(slides)
def slideshow(self, slides, fade_in_fade_out_time=1):
for slide in slides:
for i in range(0, len(slide.objects)):
self.play(FadeIn(slide.objects[i]), run_time=fade_in_fade_out_time)
self.wait(slide.durations[i])
self.play(FadeOut(*slide.objects), run_time=fade_in_fade_out_time)
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
def get_image_height(self, path):
return ImageMobject(path).scale_to_fit_height(SCREEN_HEIGHT)
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)
self.wait(1.5)
self.play(FadeOut(t0,t1,t3,t4),lag_ratio=0.1,run_time=0.5)
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])
self.play(Create(rect), run_time=1)
self.play(Create(cube), run_time=1)
camera_plane = Text("camera plane",color="white",font_size=30)
camera_plane.shift([1.5, 3, -4])
self.play(Create(camera_plane), run_time=1)
self.wait(7)
normal = Line3D(start=[0.25, 0.25, 0], end=[0.25, 0.25, -1])
normal.shift([-0.5, -0.5, 2.5])
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])
self.play(Create(triangle), run_time=1)
self.wait(2)
self.play(Create(normal), run_time=1)
self.wait(10)
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])
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)
self.play(Transform(triangle, plane_triangle))
self.wait(3)
self.move_camera(phi=PI, theta=0, gamma= PI / 2)
self.wait(5)
class RaytracingScene(Scene):
def construct(self):
square = Square(side_length=3)
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)
self.play(Create(square), run_time=1)
self.play(Create(circle), run_time=1)
self.play(Create(triangle), run_time=1)
self.wait(3)
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:
self.play(Create(Line3D(start=ray[0], end=ray[1], color=YELLOW)), run_time=1)
self.wait(5)