Cách 3Blue1Brown tạo hoạt hình [Video]
(youtube.com)- Các hình ảnh trực quan của 3Blue1Brown được mã hóa bằng thư viện Python Manim do Grant Sanderson tạo ra, và video theo sát quy trình sản xuất thực tế cùng Ben Sparks
- Manim đã tách thành môi trường làm việc cá nhân của Grant và Manim Community với tài liệu, kiểm thử và xử lý issue được củng cố hơn; người mới bắt đầu thường phù hợp với bản cộng đồng hơn
- Công việc gần với cách nối Sublime Text và terminal Python để chạy ngay từng đoạn mã, đồng thời dùng checkpoint paste để lưu cache trạng thái trung gian và lặp thử nghiệm
- Bản demo tính Lorenz attractor bằng SciPy rồi kết hợp đường cong, điểm, updater, camera 3D và hiệu ứng vệt để cho thấy các điều kiện đầu gần nhau phân kỳ như thế nào
- Cảnh cuối được render ra MP4 sau khi pre-run để kiểm tra lỗi và độ dài, rồi tiếp tục được đưa vào công cụ biên tập cho quy trình làm video YouTube
Điểm khởi đầu của Manim và hai nhánh phiên bản
- Công cụ cốt lõi của hoạt hình 3Blue1Brown là thư viện Python Manim do chính Grant Sanderson tạo ra
- Manim xây dựng mọi cảnh theo cách lập trình, và đã phát triển thành công cụ tùy biến phù hợp với phong cách sản xuất của 3Blue1Brown
- Vào khoảng lúc sắp tốt nghiệp đại học, Grant đã viết mã Python để trực quan hóa phép biến đổi của các hàm toán học tốt hơn, và đoạn mã này bắt đầu cùng những video đầu tiên của kênh
- Khi số lượng video tăng lên, công cụ cũng được cải thiện, và công cụ được cải thiện lại tiếp tục cho phép làm ra những video phức tạp hơn
- Các hiệu ứng hình ảnh trong video hologram gần đây nếu là 2~3 năm trước thì sẽ khó hơn rất nhiều, nhưng nhờ cải thiện workflow trong nhiều năm mà độ khó sản xuất đã giảm xuống
Manim Community và phiên bản cá nhân của Grant
- Grant đã công khai mã dùng trong video và chính Manim lên GitHub
- Tuy vậy, khi vừa làm video vừa quản lý mã nguồn mở, việc phản hồi issue và Pull Request không thể đầy đủ
- Cộng đồng đã fork repository để tạo ra công cụ vững chắc hơn, và phiên bản này là Manim Community
- Phản hồi issue và Pull Request tích cực hơn
- Có kiểm thử và tài liệu đầy đủ hơn
- Thường được khuyến nghị cho người mới bắt đầu
- Bản demo trong video dùng phiên bản mà Grant trực tiếp sử dụng
- Trong vài năm gần đây đã được cải thiện để tương tác hơn và chạy nhanh hơn
- Nếu coi trọng tài liệu hóa và kiểm thử thì bản cộng đồng phù hợp hơn
Cách sản xuất: viết mã và kiểm tra ngay lập tức
- Mỗi cảnh trong Manim được viết dưới dạng class Python, và mã cần render nằm trong phương thức
construct - Có thể thêm các đối tượng như hình tròn, hình chữ nhật, văn bản vào màn hình, rồi dùng phương thức
playđể chạy các animation nhưWrite,Transform - Phần lớn đối tượng mặc định được đặt ở giữa màn hình, và vị trí được đổi bằng các thao tác như
to_edge,shift - Môi trường làm việc của Grant là dùng song song Sublime Text và terminal Python
- Sao chép một dòng mã và chạy trong terminal sẽ được phản ánh ngay vào cảnh hiện tại
- Phím tắt của Sublime tự động hóa quá trình sao chép và thực thi đoạn mã được chọn
- Vì terminal được nối với cảnh hiện tại nên có thể kiểm tra kết quả chỉnh sửa ngay lập tức
- Với các cảnh dài, khả năng chỉ lặp thử một đoạn giữa thay vì chạy lại toàn bộ mã là rất quan trọng
- Ví dụ video hologram là một đoạn mã Python dài tạo ra file MP4 dài 4 phút 30 giây
- Cảnh dài chia sẻ nhiều ngữ cảnh và biến cục bộ nên cách để trong một file là hữu ích
checkpoint pastelưu cache trạng thái cảnh tại một vị trí comment cụ thể, rồi quay lại trạng thái đó và chạy đoạn mã được chọn- Cách này gần với một workflow lai giữa file văn bản thuần và Jupyter notebook
Cảm giác cơ bản của hoạt hình Manim
- Một triết lý quan trọng của Manim là “bất cứ thứ gì cũng có thể biến đổi thành bất cứ thứ gì khác”
- Ví dụ, có thể tạo cảnh biến chữ
Hđầu tiên trong văn bảnhello worldthành một hình tròn- Không cần thêm trực tiếp hình tròn vào cảnh, vẫn có thể định nghĩa nó làm đối tượng đích của phép biến đổi
- Văn bản là một nhóm ký tự nên có thể lấy từng chữ cái ra để thao tác
Transformmặc định dùng rate function mượt mà- Giá trị mặc định là
smooth, cho cảm giác chuyển động mềm dựa trên cubic bezier - Nếu dùng
linearthì phần đầu và cuối sẽ cứng hơn - Khi cần thể hiện đúng tiến trình thời gian theo toán học thì
linearlà cần thiết
- Giá trị mặc định là
- Những tinh chỉnh chi tiết như vậy tạo nên khác biệt giữa một “cảnh chuyển động” và một “cảnh đẹp mắt”
- Các animation quen thuộc trong video 3Blue1Brown như
Writecũng có thể được gọi bằng hàm tích hợp sẵn của Manim
Demo Lorenz attractor
- Ví dụ trung tâm của bản demo là Lorenz attractor
- Đây là một dạng xuất hiện từ hệ phương trình vi phân ba chiều
- Nó xác định bằng quy tắc tất định cách một điểm trong không gian 3D thay đổi theo thời gian
- Khi thay đổi nhiều điều kiện đầu sẽ tạo ra kết quả trực quan thú vị
- Khi tạo phần tính toán toán học, Grant đã nhờ ChatGPT viết hàm Python
- Có sử dụng
integratecủa SciPy và hàm giải bài toán giá trị ban đầu - Mã được tạo ban đầu dựa trên render bằng Matplotlib rồi sau đó điều chỉnh cho phù hợp với Manim
- Có sử dụng
- Trạng thái của phương trình Lorenz có các tọa độ
x,y,z, và được biểu diễn bằng một hàm tính đạo hàm tại mỗi thời điểm - Kết quả giải số cho ra giá trị thời gian cùng các giá trị
x,y,z, và Grant đặt một wrapper để dễ xử lý hơn- Cách biểu diễn phía SciPy dùng
ynhư đầu ra nên có thể hơi gây nhầm lẫn - Anh ấy điều chỉnh mảng trạng thái và dạng chuyển vị theo cách thuận tiện hơn cho mình
- Cách biểu diễn phía SciPy dùng
- Nếu đặt điều kiện đầu là
(0, 0, 0)thì mọi giá trị đều ra 0 nên không phù hợp; sau khi đổi một tọa độ thành 10 thì tạo ra các điểm thú vị hơn - Trong Manim, để biến các điểm đã tính thành đường cong, anh dùng
set_points_as_corners - Để đổi hệ tọa độ của trục sang hệ tọa độ của Manim, anh dùng
c2p, dạng viết tắt củacoords_to_point - Cú pháp
*của Python được dùng để bung iterable thành các đối số hàm- Trong ví dụ, nó tách danh sách tọa độ
x,y,zrồi truyền vào hàm
- Trong ví dụ, nó tách danh sách tọa độ
Cảnh các điều kiện đầu gần nhau phân kỳ
- Điểm cốt lõi của trực quan hóa Lorenz attractor là các điều kiện đầu rất gần nhau lúc đầu chuyển động tương tự, nhưng về sau thì tách hẳn ra
- Grant tạo một danh sách điều kiện đầu và đặt tọa độ
zkhác nhau một lượng nhỏepsilon- Ban đầu anh bắt đầu với 2 điều kiện
- Sau đó tăng lên 10 điều kiện
- Để chứa nhiều đường cong, anh dùng
VGroup- Khi cho biết đó là nhóm đối tượng vector hóa, việc render có thể nhanh hơn
- Ở điểm cuối của mỗi đường cong có gắn một glow dot
GlowDotlà đối tượng được tạo ra để hiển thị đẹp hơn các điểm đang di chuyển- Mỗi điểm có một updater để ở mỗi frame nó di chuyển đến điểm cuối của đường cong
zipđược dùng khi cần duyệt song song các danh sách tương ứng như điểm và đường cong, hay trạng thái và màu sắc- Nếu hai danh sách khác độ dài thì nó dừng ở chỗ danh sách ngắn hơn kết thúc
color_gradienttạo số màu bằng với số trạng thái để khớp độ dài
- Khi vẽ đường cong bằng
ShowCreation, nếu dùng smoothing mặc định thì tiến trình thời gian thực có thể bị méo, nên ở phần cần giữ nguyên động lực học người ta dùng linear rate function - Các điều kiện đầu gần nhau lúc đầu gần như đi cùng nhau, nhưng theo thời gian sẽ lan ra như ở những vị trí hoàn toàn khác nhau
- Lorenz attractor không phải một điểm đơn hay chu kỳ đơn giản, mà được xem là một strange attractor: bị hút về một hình dạng nhất định nhưng vị trí chính xác lại rất nhạy với điều kiện đầu
Mã lách trong chế độ tương tác và hiệu ứng cảnh
- Trong demo xuất hiện đoạn mã “bị nguyền rủa” như
globals().update(locals()) - Đây là cách lách tạm thời để tránh vấn đề trong môi trường IPython embed của Manim, nơi hàm không nhìn thấy biến ở scope bên ngoài
- Trong script Python thông thường thì cùng đoạn mã đó chạy bình thường
- Nhưng trong môi trường tương tác nhúng của Manim có thể phát sinh
NameError - Cách này đưa biến cục bộ vào dictionary biến toàn cục để lách lỗi
- Nếu là mã thư viện thực tế thì cách này không phù hợp, nhưng trong một phiên tương tác tạm thời để phát triển cảnh thì rủi ro tương đối thấp
- Cách tốt hơn là để hàm nhận rõ ràng các biến cần thiết qua tham số đầu vào
- Để làm đường cong biến mất theo thời gian có thể dùng
FadeOut- Nếu đặt
run_timecủaplaykhớp với evolution time, đường cong sẽ mờ dần trong đúng khoảng thời gian đó
- Nếu đặt
- Hiệu ứng để lại vệt phía sau điểm được thực hiện bằng
TracingTail- Có thể tạo đuôi bám theo một điểm
- Nếu tăng
time_tracedtừ 1 giây lên 3 giây thì sẽ thấy vệt dài hơn - Gắn đuôi cho cả 10 điểm sẽ làm nhiều quỹ đạo tỏa ra hiện rõ hơn
Camera 3D và xử lý công thức
- Cảnh Manim về cơ bản có thể mang tọa độ 3D, nhưng phần lớn cảnh của 3Blue1Brown được dựng trông như bảng đen 2D vì lý do sư phạm
- Lorenz attractor cần 3D nên thêm các trục 3D
- Trong khung hình 3D, hiệu ứng camera xoay hoặc di chuyển chậm giúp giữ cảm giác chiều sâu
- Grant dùng một phím tắt để lưu vị trí camera hiện tại vào clipboard
- Dùng dạng
frame.animate.reorient(...)để animate khung camera tới một vị trí cụ thể
- Công thức có thể được thêm vào cảnh dưới dạng đối tượng LaTeX
- Có thể dùng MathPix để OCR phương trình trên màn hình rồi lấy ra LaTeX hoặc SVG
- Nếu muốn cố định công thức trên màn hình trong cảnh 3D thì dùng
fix_in_frame
- Có thể tô màu cho các biến cụ thể trong công thức LaTeX
- Trong ví dụ,
x,y,zđược gán các màu khác nhau - Khả năng tách văn bản thành các thành phần toán học để nhấn mạnh hoặc biến đổi rất hữu ích cho việc giải thích toán học
- Trong ví dụ,
- Manim còn có các transform đặc biệt để khớp theo chuỗi ký tự
- Các hạng như
A^2,B^2có thể di chuyển tự nhiên đến vị trí chuỗi tương ứng ở dòng sau - Việc khớp theo chuỗi cũng cho phép tạo hiệu ứng kiểu anagram, đưa các chữ đến vị trí tương ứng
- Các hạng như
- Các animation như
flash around,indicatecó thể dùng để nhấn mạnh ký tự hoặc hạng cụ thể trong công thức
Render và quy trình sản xuất thực tế
- Khi đã ưng ý với cảnh, người dùng render bằng lệnh Manim với file Python và tên cảnh được chỉ định
pre-runlà bước duyệt trước toàn bộ animation trước khi dùng thật- Ước lượng tổng độ dài
- Giúp bắt lỗi trước thay vì phát hiện giữa chừng trong lúc render
Wlà tùy chọn ghi ra file, còn các tùy chọn liên quan đến Finder được dùng để mở file kết quả trong Finder của macOS- Kết quả cuối cùng được render thành file MP4
- Grant thường render ở 4K nên có thể mất nhiều thời gian hơn
- File đã render sau đó được đưa vào công cụ biên tập để chỉnh sửa tiếp
- Cách dùng Manim trước đây chủ yếu là lặp giữa render cảnh từ dòng lệnh rồi mở MP4 để kiểm tra
- Về sau, gần cùng thời điểm chuyển sang triển khai OpenGL, workflow dựa trên interactive shell xuất hiện, cho phép bôi đen mã và xem kết quả ngay
- Workflow cụ thể của Grant phụ thuộc vào script của Sublime Text và extension Terminus
- Trong các trình soạn thảo văn bản khác cũng có thể mô phỏng hành vi tương tự
- Trong các môi trường kiểu Visual Studio cũng có thể tạo ra luồng làm việc tương tự
- Khi cần tìm tính năng, có thể tham khảo các scene mẫu, thư mục
animationcủa thư viện, và repository GitHub3b1b/videoschứa mã từ các video cũ - Grant thích kiểu tự động hoàn thành đơn giản hơn là Copilot
- Trong Manim, anh thường đã biết sẵn hành vi mình muốn
- Việc diễn đạt yêu cầu bằng mã thấy tự nhiên hơn bằng tiếng Anh
1 bình luận
Ý kiến trên Hacker News
3B1B đang làm một việc thật sự tuyệt vời
Cá nhân tôi đã được giúp đỡ rất nhiều từ các video YouTube của anh ấy, và ước gì toán học được dạy theo cách này ở trường phổ thông hoặc các trường kỹ thuật
https://sinerider.com/ cũng đáng xem
Đây là một trò chơi do một người bạn thỉnh thoảng hỗ trợ Grant Sanderson trong các công việc của 3B1B tạo ra; một game giáo dục toán học xuất sắc, nơi bạn tạo đường chạy như LineRider nhưng bằng công thức
Cả 3B1B lẫn SineRider đều có ảnh hưởng lớn hơn bất cứ thứ gì khác đến việc giúp tôi hiểu trực quan về hợp thành hàm
Cảnh anh ấy phát hiện bug của engine render theo thời gian thực rồi còn tìm ra cách đi vòng thật ấn tượng
https://youtu.be/rbu7Zu5X1zI?feature=shared&t=693
Dù vậy vẫn là một công việc ấn tượng
Việc biết vị trí và nguyên nhân, rồi nghĩ ra cách né ngay khi đang live, cho thấy anh ấy dành thời gian cải thiện công cụ của mình, và không chỉ thỉnh thoảng mà là rất chủ động
Tôi vẫn thấy điều đó rất ngầu
Tôi đã tò mò không biết Python REPL tương tác ở góc dưới bên phải hoạt động thế nào
Sửa: có vẻ là một quy trình làm việc hoàn toàn tùy biến: https://github.com/3b1b/videos?tab=readme-ov-file#workflow
Sau nhiều năm chỉ nghe giọng mà không thấy mặt, giờ nhìn thấy mặt anh ấy khiến tôi buồn cười vì đột nhiên có cảm giác như rơi vào giữa thung lũng kỳ lạ
Trong vài video gần đây, anh ấy hành xử như người dẫn chương trình, người phỏng vấn và người thuyết minh
Cũng thấy lạ khi có các creator khác thay mặt làm một số video, như veratasium
Nếu nói về một màn công khai thật sự lớn thì chắc là AvE
Khi đó phần lớn bình luận dưới video nói về tên kênh và biểu tượng, và thực tế một bên mắt của anh ấy trông đúng như vậy
Dù vậy, ngay cả trong các kênh ngách như thế này thì thị hiếu cũng có vẻ khá khác nhau
Giọng của anh ấy thật sự rất hay. Điềm tĩnh và dễ chịu, đến mức có thể bật bên cạnh khi làm việc nhà mà vẫn học được điều gì đó
Những creator như vậy xứng đáng được công nhận
Video hologram mới nhất thuộc nhóm video YouTube có chất lượng tốt nhất mà tôi từng xem
Sẽ thật tuyệt nếu dùng công cụ này để làm một video giải thích thuật toán bridging[1]
Từ năm 2016, tôi đã là fan của cách thuật toán này được dùng trong các quy trình dân chủ có sự tham gia với những công cụ như Pol.is, và tôi muốn góp phần nâng cao hiểu biết về phần toán học nền tảng của nó
Nếu tôi biết đến Manim vào thời điểm Summer of Math Exposition[2] diễn ra thì chắc chắn tôi đã tham gia
[1]: https://bridging.systems/
[2]: https://some.3b1b.co/
Website của tôi có trong hồ sơ, nên nếu một ngày nào đó bạn làm, mong bạn gửi link cho tôi qua mạng xã hội
Liên kết Manim: https://github.com/3b1b/manim
Tôi ngạc nhiên vì khối lượng sản xuất trong mỗi video của anh ấy quá lớn. Anh ấy xứng đáng nhận nút Play của YouTube
Cũng như blog, nếu không gặp may thì phần lớn công sức đó sẽ bị lãng phí. Nhưng blog ít nhất còn có nhiều cơ hội được chú ý. Nó có thể lên trang đầu HN, hoặc lan truyền trên X hay nơi khác. Ngay cả trong một nền tảng, thường cũng có nhiều cơ hội
Ngược lại, trên YouTube, thuật toán về cơ bản chỉ quyết định một lần. Nếu bạn chưa có lượng người đăng ký khổng lồ, video sẽ gần như được hiển thị ngẫu nhiên cho vài người; nếu họ không phản ứng, mọi chuyện kết thúc ở đó