The Problem
Why calculate physics in Python when Rust exists?
We love Blender's Python API. It's flexible, accessible, and great for tooling. But when you're calculating millions of particle positions or complex wave functions per frame, Python's Global Interpreter Lock (GIL) and dynamic typing become a bottleneck.
The frame rate drops. The viewport stutters. The artist waits.
The Solution
GhostRender proposes a radical shift: The Pipeline Approach.
Instead of asking Blender to think, we only ask it to draw. We move the heavy lifting to Rust, a systems programming language known for blazing speed and memory safety.
Calculates math, generates scripts, and manages threads.
Splits 1800 frames into chunks for concurrent rendering.
Multiple headless instances render video parts.
The Code
Here is the heart of the engine. Rust spawns multiple Blender instances, each rendering a chunk of the animation in parallel.
// src/main.rs
for i in 0..CHUNKS {
let start_frame = i * frames_per_chunk;
let end_frame = (i + 1) * frames_per_chunk - 1;
// Spawn a thread for each chunk
let handle = thread::spawn(move || {
let output_path = format!("//part_{}_", i);
Command::new(&blender_bin)
.arg("-b")
.arg(BLEND_FILE)
.arg("-o").arg(&output_path)
.arg("-s").arg(start_frame.to_string())
.arg("-e").arg(end_frame.to_string())
.arg("-a") // Render animation
.spawn()
.expect("Failed to spawn blender worker");
});
handles.push(handle);
}
This approach saturates the CPU cores, drastically reducing render time for long animations.
The Evidence
Talk is cheap. Here is the artifact produced automatically by our CI pipeline on the latest commit.
10 cubes, 1800 frames (30s), rendered in parallel on 4 chunks.
The "Gotchas"
Building this wasn't free. We learned that headless rendering on Linux requires a virtual framebuffer (XVFB).
Error: "Unable to open a display"
We fixed this by installing xvfb and libgl1-mesa-dri in our CI environment, and running Blender with xvfb-run.
Another challenge was stitching the video parts. We used Blender's Sequence Editor (via another generated script) to concatenate the parallel chunks seamlessly.