Remotion vs Manim — 数学・科学解説動画にはどちらを使うべきか
Remotion vs Manim — 数学・科学解説動画にはどちらを使うべきか
3Blue1Brownの動画を見て「こういう解説動画を自分でも作りたい」と思ったことがあれば、ほぼ確実にManimにたどり着いているはずです。Grant Sandersonが自身のチャンネルのために作ったPython製アニメーションエンジンです。一方、コードで動画を生成するWeb開発者なら、Reactコンポーネントをそのまま MP4 にレンダリングするフレームワークRemotionを知っているでしょう。
どちらも「コードから動画を作る」ツールですが、生まれた目的も、エコシステムも、アニメーションの考え方も異なります。この記事では、言語・アニメーションモデル・数式表現・レンダリングの4つの軸で両者を比較し、最後にManim風の解説動画をReactに移植する場合に実際何が起きるのかまで踏み込みます。
それぞれのツールが生まれた目的
Manimは「数学をアニメーションさせる」ために存在します。3Blue1Brown チャンネルの個人ツールとして始まり、その後コミュニティがフォークした**Manim Community Edition(Manim CE)**が現在の標準的なインストール対象です。プリミティブが数学そのものであることが特徴です——座標軸、関数プロット、幾何図形、LaTeX数式、ベクトル場、そしてそれらの間の変換。有名な「ひとつの数式が別の数式にモーフィングする」演出が1行で書けます。
Remotionは「動画制作をWeb開発の問題にする」ために存在します。すべてのフレームはReactコンポーネントのレンダリング結果であり、ヘッドレスChromiumがそれをキャプチャして動画ファイルにエンコードします。プリミティブはWebのプリミティブです——HTML、CSS、SVG、canvas、そしてnpmエコシステム全体。パーソナライズされたバリエーション、APIトリガーのレンダリング、Webのスキルをそのままモーションデザインに転用する——プログラマティックでデータ駆動の動画のために設計されています。
この記事を一文に要約するとこうなります。Manimは動画を出力する数学アニメーションエンジン。Remotionはブラウザが表示できるものなら何でも——数学を含めて——レンダリングできる動画エンジンです。
言語とエコシステム:Python vs React/TypeScript
ManimはPythonです。 Scene を継承したクラスを書き、ジオメトリ計算はNumPyに依存しています。科学計算・データサイエンス・アカデミアの出身なら完全にホームグラウンドです。分析に使っているのと同じ言語でアニメーションを駆動でき、NumPy配列をそのままプロットに渡せます。
RemotionはReactとTypeScriptです。 コンポジションはコンポーネントであり、アニメーションの状態は現在フレームから導出され、propsは普通のReactアプリと同じように流れます。Web開発者なら学習コストはごく浅く、毎日書いているJSXに useCurrentFrame() と useVideoConfig() というフックが加わるだけです。
構文の違いより重要なのはエコシステムの違いです。Manimには数学向けのプラグイン(ナレーション補助・スライドツール・物理拡張)があります。Remotionにはnpmがあります——チャートライブラリ、three.js、Markdownレンダラー、これまでに書いたすべてのReactコンポーネント。スタイル付きのテーブル、シンタックスハイライトされたコードスニペット、UIモックアップはブラウザモデルではネイティブに描画できますが、Manimのmobjectで組み立てるのは本当に骨が折れます。
アニメーションモデルの比較:SceneとMobject vs フレームとコンポーネント
両ツールの最も深い違いは「時間の捉え方」です。
Manimは命令的・逐次的です。 Scene サブクラスの construct() の中で、各 self.play(...) は完了してから次に進みます。
from manim import *
class SineIntro(Scene):
def construct(self):
axes = Axes(x_range=[0, 10], y_range=[-1.5, 1.5])
curve = axes.plot(lambda x: np.sin(x), color=BLUE)
label = MathTex(r"f(x) = \sin(x)").to_corner(UR)
self.play(Create(axes), run_time=2)
self.play(Create(curve), Write(label), run_time=3)
self.wait()
「次に何が起きるか」を記述し、タイムラインの管理はManimに任せる。脚本のように読めるコードで、直線的な解説動画には非常に相性がいいモデルです。
Remotionは宣言的・フレームベースです。 「play」はありません。あるのは現在のフレーム番号だけで、コンポーネントはその純粋関数です。同じサインカーブをSVGで漸進的に描画すると、次のようになります。
import {
AbsoluteFill,
useCurrentFrame,
useVideoConfig,
interpolate,
Easing,
} from 'remotion';
const buildSinePath = (progress: number): string => {
const totalPoints = 200;
const visible = Math.floor(totalPoints * progress);
const commands: string[] = [];
for (let i = 0; i <= visible; i++) {
const t = i / totalPoints;
const x = 160 + t * 1600;
const y = 540 - Math.sin(t * Math.PI * 4) * 220;
commands.push(`${i === 0 ? 'M' : 'L'} ${x} ${y}`);
}
return commands.join(' ');
};
export const SineWaveDraw: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// 3秒かけて 0 → 1 に進行(描画の進捗率)
const progress = interpolate(frame, [0, 3 * fps], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.bezier(0.33, 1, 0.68, 1),
});
return (
<AbsoluteFill style={{ backgroundColor: '#0d1117' }}>
<svg viewBox="0 0 1920 1080">
<line x1={160} y1={540} x2={1760} y2={540} stroke="#3d444d" strokeWidth={2} />
<line x1={160} y1={100} x2={160} y2={980} stroke="#3d444d" strokeWidth={2} />
<path
d={buildSinePath(progress)}
stroke="#58a6ff"
strokeWidth={6}
fill="none"
strokeLinecap="round"
/>
</svg>
</AbsoluteFill>
);
};
シーンの連結は <Sequence> で行います。コンテンツが登場するタイミングをオフセットする仕組みです。
import { AbsoluteFill, Sequence, useVideoConfig } from 'remotion';
export const SineExplainer: React.FC = () => {
const { fps } = useVideoConfig();
return (
<AbsoluteFill style={{ backgroundColor: '#0d1117' }}>
<Sequence durationInFrames={3 * fps}>
<TitleCard title="サイン波はなぜ至るところに現れるのか" />
</Sequence>
<Sequence from={3 * fps} durationInFrames={6 * fps}>
<SineWaveDraw />
</Sequence>
<Sequence from={9 * fps}>
<EquationReveal tex={'f(x) = \\sin(x)'} />
</Sequence>
</AbsoluteFill>
);
};
トレードオフはこうです。Manimの命令的モデルは「これをやって、次にこれ」というナレーション主導の解説に自然です。Remotionのフレームベースモデルは、並行して重なり合うモーションやデータ駆動の演出に自然で、しかもすべてのフレームがフレーム番号の純粋関数であるため、スクラブ・プレビュー・分散レンダリングが自動的に手に入ります。複数シーンの時間設計のパターンはSequenceとタイミング制御のガイドにまとめています。
数式表現:ManimのLaTeX vs RemotionのKaTeX
数学解説動画において数式の品質は妥協できない要素であり、ここはManimの最強のカードです。
Manimは本物のLaTeXをレンダリングします。 MathTex と Tex のmobjectは実際のLaTeXディストリビューション(TeX LiveまたはMiKTeXのインストールが必要)でコンパイルされるため、LaTeXが組版できるものはすべてアニメーションできます。数式はベクターグリフのmobjectになるので、TransformMatchingTex でひとつの数式を別の数式にモーフィングし、共通するシンボルを滑らかに移動させられます。3Blue1Brownの代名詞である「数式が自分で並び替わる」演出が組み込みで手に入ります。
代償は依存関係です。数GBのLaTeXインストール、時折発生するdvisvgmの問題、数式の再コンパイルによるイテレーションの遅さがつきまといます。
Remotionはブラウザベースの数式レンダリングを使います。 代表格はKaTeXで、npmからインストールしてプロジェクトにバンドルします(CDNは不要です。KaTeXはフォントをパッケージ内に同梱しているため、出力は自己完結します)。
import {
AbsoluteFill,
useCurrentFrame,
useVideoConfig,
spring,
interpolate,
} from 'remotion';
import katex from 'katex';
import 'katex/dist/katex.min.css';
export const EquationReveal: React.FC<{ tex: string }> = ({ tex }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const enter = spring({
frame,
fps,
config: { mass: 0.6, stiffness: 120, damping: 14 },
});
const translateY = interpolate(enter, [0, 1], [40, 0]);
const opacity = interpolate(enter, [0, 1], [0, 1], {
extrapolateRight: 'clamp',
});
const html = katex.renderToString(tex, {
displayMode: true,
throwOnError: false,
});
return (
<AbsoluteFill
style={{
backgroundColor: '#0d1117',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
fontSize: 72,
color: '#e6edf3',
transform: `translateY(${translateY}px)`,
opacity,
}}
dangerouslySetInnerHTML={{ __html: html }}
/>
</AbsoluteFill>
);
};
KaTeXは瞬時にレンダリングでき、一般的な数式記法の大部分をカバーしますが、あくまでLaTeXのサブセットです。マイナーなパッケージや特殊な環境は使えません。より重要なのは、KaTeXの出力がスタイル付きHTMLであり、グリフ単位でアドレス可能なmobjectではないことです。数式全体のアニメーション(フェード・スライド・スケール・ハイライト)は簡単ですが、2つの数式の間をシンボル単位でモーフィングさせるには、式を手動でフラグメントに分割して個別にアニメーションさせる必要があります。シンボル単位の数式演出が動画の核なら、このセクションはManimの完勝です。
レンダリングパイプライン・速度・出力形式
ManimはデフォルトでCairoバックエンドを使い(ManimGLやManim CEのOpenGLレンダラーは、忠実性の保証と引き換えにリアルタイムプレビューを提供します)、FFmpegでフレームを動画に結合します。CLIは品質フラグ駆動です——manim -pql scene.py SineIntro で低解像度の高速プレビュー、-qh で1080p60の本番レンダリング。部分動画ファイルがキャッシュされるため、変更していないシーンの再レンダリングは高速です。出力はデフォルトでMP4、GIFや透過形式も選べます。
レンダリングはローカルの単一マシンで完結します。「1本レンダリングしてYouTubeにアップロードする」ワークフローなら全く問題ありませんが、クラウドスケールのレンダリングや1日に大量のバリエーションを生成する公式の仕組みはありません。
RemotionはヘッドレスChromiumでレンダリングし、FFmpegでエンコードします。出力はH.264/H.265のMP4、WebM、ProRes、GIF、画像シーケンス、透過動画をカバーします。Manimと比較して際立つ点が3つあります。
- Remotion Studio(
npx remotion studio)は、propsをライブ編集できるスクラブ可能なタイムラインプレビューを提供します。Manimの「レンダリングして見る」サイクルでは得られないイテレーション速度です。 - Remotion Lambdaによる分散レンダリングは、1本のレンダリングを多数のクラウド関数に分割します。同じコンポジションを毎回異なるpropsでAPIからレンダリングでき、自動化パイプラインの背骨になります。詳細はReactとRemotionによるプログラマティック動画制作を参照してください。
- Playerを使えば、ファイルをレンダリングする前に、同一のコンポジションをWebページ内でインタラクティブに動かせます。
美しい動画を1本作るだけなら、レンダリング速度の差は誤差です。動画を量産するシステムを作るなら、Remotionのパイプラインは別のカテゴリにいます。
Manimが勝つ場面 / Remotionが勝つ場面
Manimを選ぶべきとき
- 動画のテーマが数学そのもの:証明、導出、幾何、微積分の可視化
- 完全なLaTeXとシンボル単位の数式モーフィング(
TransformMatchingTex)が必要 - 自分(またはチーム)の主戦場がPythonとNumPy
- チャンネル向けに、直線的なナレーション主導の解説動画を1本ずつ作る
- 組み込みの数学オブジェクト(座標軸・ベクトル場・3Dサーフェス)が絵コンテにそのまま対応する
Remotionを選ぶべきとき
- 数式は多くの素材のひとつ:チャート、UIモックアップ、コードスニペット、ブランドレイアウト、ミクストメディア
- データ駆動・自動化された動画が欲しい——大量のバリエーション、APIトリガーのレンダリング、CIパイプライン
- チームがすでにReact/TypeScriptで開発しており、Webと動画でスキルセットを一本化したい
- CSSが提供する(mobjectにはない)スタイリングの深さ——タイポグラフィ、レイアウト、グラデーション、ブレンドモード——が必要
- 成果物がファイルだけでなく、インタラクティブなPlayer埋め込みとしてWeb上でも動く必要がある
使いやすい判断基準を挙げるなら:リファレンスが3Blue1BrownならManimから始める。洗練されたプロダクト解説、データストーリー、スケールが必要な教育シリーズならRemotionから始める——後者はRemotionによる教育・eラーニング動画制作で詳しく扱っています。
Manim風の解説動画をReactに移行する
Manimで作った解説動画をRemotionで作り直したいとします——バリエーションを自動化したい、あるいはWebプロダクトに組み込みたい。概念の対応は思ったよりも素直です。
| Manimの概念 | Remotionでの対応 |
|---|---|
Scene + construct() | <Sequence> ブロックを持つコンポジションコンポーネント |
self.play(Create(...)) | interpolate() で漸進的なSVGパスやクリップを駆動 |
self.play(Write(tex)) | KaTeXレンダリング + opacity/translateアニメーション |
run_time=2 | フレーム範囲:[0, 2 * fps] |
rate_func=smooth | Easing.bezier(...) または spring() |
ValueTracker + updater | useCurrentFrame() から導出される任意の値 |
Axes.plot(fn) | 同じ関数から計算したSVGパス |
ValueTracker の行は、「点が曲線に沿って移動する」系のアニメーションのほとんどの背後にあるパターンです。Remotionでは、フレームそのものがValueTrackerになります。
import { useCurrentFrame, useVideoConfig, interpolate } from 'remotion';
// 座標軸やカーブと同じ <svg> 要素の中に配置して使う
export const MovingPoint: React.FC = () => {
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
// t はコンポジション全体で 0 → 4π を掃引する(ValueTrackerと同じ役割)
const t = interpolate(frame, [0, durationInFrames - 1], [0, Math.PI * 4]);
const x = 160 + (t / (Math.PI * 4)) * 1600;
const y = 540 - Math.sin(t) * 220;
return (
<>
<circle cx={x} cy={y} r={14} fill="#f0883e" />
<text x={x + 24} y={y - 24} fill="#f0883e" fontSize={36}>
{`sin(${t.toFixed(2)}) = ${Math.sin(t).toFixed(2)}`}
</text>
</>
);
};
updaterの登録も可変状態もありません。位置とラベルはフレームから再計算されます——これこそがレンダリングを並列化可能にしている性質そのものです。
きれいに移行できないものも明確です。シンボル単位の数式モーフィング(該当箇所はクロスフェードや段階的リビールとして再設計する)、Manim組み込みの3Dシーンカメラ(React Three Fiberを使う)、next_to() や arrange() のようなレイアウトヘルパー(flexboxを使う——正直、こちらの方が上位互換です)。数値の読み上げ表示・棒グラフ・カウンターは特に移植しやすい部類で、Remotionのデータビジュアライゼーションアニメーションのテクニックがそのまま使えます。
移行の工数はシーンのタイプで見積もるのが実用的です。プロット+注釈系のシーンは1シーンあたり1〜2時間で移植できます。数式の振り付けが中心のシーンは、単純な移植ではなく再設計が必要です。
Remotion向けの科学・教育系テンプレートパック
Manimのエコシステムには視覚的な伝統があります——Manimの動画はManimの動画に見えます。Remotionは白紙のキャンバスから始まります。自由ですが、その分の作業も発生します。
科学・教育向けの既成テンプレートは、このギャップを埋めます。座標軸、注釈コールアウト、ステップバイステップのリビール、数式カードをゼロからデザインする代わりに、タイミング調整済み・型付きpropsのコンポーネントを配置してコンテンツに集中できます。普通のRemotionコンポジションなので、同じ自動化パイプラインにそのまま組み込めます——同じテンプレートからレッスンを1本でも100本でもレンダリングできます。
比較早見表
| 項目 | Manim | Remotion |
|---|---|---|
| 言語 | Python | React / TypeScript |
| アニメーションモデル | 命令的なシーン(self.play) | 宣言的・フレームベースのコンポーネント |
| 数式表現 | 完全なLaTeX・シンボル単位モーフィング | KaTeX/MathJaxのサブセット・ブロック単位アニメーション |
| レンダリング | ローカルのCairo/OpenGL + FFmpeg | ヘッドレスChromium・ローカルまたは分散(Lambda) |
| プレビュー | レンダリングして確認(GLでリアルタイム) | Remotion Studioでpropsライブ編集 |
| スタイリングの深さ | mobjectの属性 | CSS・SVG・canvas・npmエコシステム全体 |
| 自動化・バリエーション | 自前でスクリプト | ファーストクラス(API・props・クラウドレンダリング) |
| Web埋め込み | ファイルを書き出す | 任意のReactアプリに <Player> で埋め込み |
| 最適な用途 | 純粋な数学解説・単発の動画 | ミクストメディア教育・スケールするデータ駆動動画 |
よくある質問(FAQ)
Q: Remotionで3Blue1Brownのルックは再現できますか?
視覚的にはおおむね可能です。ダークな背景、ベクタープロット、注釈付き数式はSVGとKaTeXで問題なく作れます。最も難しいのはシンボル単位の数式モーフィングで、Manimなら組み込みで手に入るものを、Remotionでは自前で作り込む必要があります。
Q: ManimにはLaTeXのインストールが必要ですか?
Tex と MathTex オブジェクトを使うなら必要です——TeX LiveやMiKTeXなどの動作するLaTeXディストリビューションが要ります。プレーンな Text オブジェクトはPango経由でレンダリングされるためLaTeX不要です。RemotionのKaTeXにはシステム依存がなく、他のパッケージと同様にnpmからインストールするだけです。
Q: 1つのプロジェクトで両方を使えますか?
使えます。数式が濃いセグメントをManimで透過動画としてレンダリングし、それを <OffthreadVideo> コンポーネント経由でRemotionコンポジションに合成して、ブランドレイアウトやデータグラフィックと組み合わせる構成が可能です。
Q: RemotionでKaTeXの代わりにMathJaxを使うのはどうですか?
MathJaxはKaTeXよりカバーするLaTeX範囲が広い代わりに低速です。動画レンダリングでは、KaTeXの同期的な renderToString の方が予測可能な選択です。いずれにせよ、ライブラリはCDNから読み込むのではなくプロジェクトにバンドルしてください。レンダリングが決定論的かつ自己完結になります。
白紙のキャンバスをスキップする
数学・科学コンテンツにRemotionを選んだなら、RenderCompが本番品質のRemotionテンプレートを提供しています——アニメーションチャート、カウンター、ステップバイステップのリビールレイアウト、教育向けフォーマット。すべてTypeScriptのpropインターフェースと編集可能なソースコード付きで、初日からレンダリングできます。
コレクションは rendercomp.com からどうぞ →