render-clean-silent
Render_Clean_Silent: One-Shot Clean Render for Fusion Studio
Fusion Studio's render workflow requires three separate steps: clean up old outputs before rendering, render the comp, then finalize outputs after rendering. This script collapses all three into a single keystroke—pre-render cleanup, silent rendering, and post-render finalization—without manual intervention or popup dialogs interrupting the workflow.
The Problem
In my previous post on ClearSaverOutputs.lua, I explained how Fusion Studio lacks DaVinci Resolve's "Delete before render" feature, requiring manual cleanup of old frames and movie files before every render. I built ClearSaverOutputs to automate the pre-render cleanup step.
But that script is only one-third of the full workflow:
- Pre-render cleanup (ClearSaverOutputs.lua): Delete old frames, redirect movie outputs to temp files
- Rendering (Cmd+R): Fusion renders the comp
- Post-render finalization (separate PostRender script): Swap temp movie files to final names
This three-step process works, but it's still three manual actions:
- Run ClearSaverOutputs script
- Hit Cmd+R to render
- Wait for PostRender script to finalize outputs
And between steps, Fusion displays the "Render Completed" dialog, forcing me to click "OK" before continuing. When I'm rendering multiple comps in sequence or iterating on a motion graphics project, this dialog is pure friction—I already know the render completed because the progress bar finished.
Render_Clean_Silent.lua solves both problems by combining all three steps into one script and suppressing the completion dialog entirely.
The Solution
This script is a one-shot clean render that handles the entire workflow:
- Pre-render cleanup: Deletes old image sequence frames, redirects movie outputs to temp files (same logic as ClearSaverOutputs)
- Silent rendering: Renders the comp with
comp:Lock()to suppress the "Render Completed" popup - Post-render finalization: Swaps temp movie files to final names, restores Saver paths
The workflow is now:
- Make changes to the Fusion comp
- Hit Cmd+Shift+R (my custom keybinding for this script)
- Wait for render to complete
- Output files are finalized and ready—no popups, no manual cleanup
Total time: render duration + ~1 second for cleanup/finalization. Zero popups, zero manual steps, zero leftover temp files.
Technical Implementation
This script combines the logic from ClearSaverOutputs.lua (pre-render cleanup) with two new features: silent rendering and post-render finalization.
1. Pre-Render Cleanup (Same as ClearSaverOutputs)
The script starts by iterating through all Saver nodes and applying cleanup logic:
For movie outputs (.mov, .mp4, etc.):
- Redirect the Saver to render to a temp filename (e.g.,
output.rendering.1735025847234.mov) - Store a mapping of
temp → finalnames for post-render finalization
For image sequences (.exr, .dpx, .png, etc.):
- Delete existing frames in the render range
- Configurable policy: delete only in-range frames (
delete_range) or all frames (delete_all)
Opt-out mechanism:
- Put
[KEEP]in a Saver's Comments field to skip cleanup for that output
This is identical to ClearSaverOutputs—the code is the same. The difference is that this script continues instead of stopping at cleanup.
2. Silent Rendering with comp:Lock()
After cleanup, the script renders the comp using Fusion's Lua API:
comp:Lock() -- suppress UI popups (including "Render Completed")
local ok = comp:Render({ Start=R0, End=R1, Wait=true, RenderAll=true })
comp:Unlock()
What comp:Lock() does:
comp:Lock() freezes the Fusion UI while the script is running, preventing any dialogs from interrupting the render. This includes:
- "Render Completed" popup
- Warning dialogs
- Error popups (though these still print to the console)
The Wait=true parameter tells Fusion to render synchronously—the script waits for the render to finish before continuing. This ensures post-render finalization doesn't run until the output files are fully written.
After rendering, comp:Unlock() restores normal UI behavior.
Result: The render happens silently. No popups, no interruptions. If the render fails, the script prints an error to the console but doesn't display a dialog.
3. Post-Render Finalization: Swapping Temp → Final
After the render completes, the script finalizes movie outputs by swapping temp files to their final names:
for _, m in ipairs(maps) do
if bmd.fileexists(m.tmp) then
if clear_final(m.final) then
local moved = os.rename(m.tmp, m.final)
if not moved then
local okcopy = copy_file(m.tmp, m.final)
if okcopy then os.remove(m.tmp) end
end
print("[CleanRender] Finalized: "..m.final)
end
end
end
Step-by-step breakdown:
- Check if temp file exists:
bmd.fileexists(m.tmp)verifies the render actually produced the temp file. - Clear the final path:
clear_final(m.final)deletes the old output file (if it exists). - Rename temp → final:
os.rename(m.tmp, m.final)is an atomic operation—the file is moved, not copied, so there's no "half-moved" intermediate state. - Fallback to copy+delete: If
os.rename()fails (rare, but can happen on network drives), the script falls back tocopy_file()then deletes the temp.
Why clear_final() is defensive:
The clear_final() function doesn't just call os.remove(final) once—it retries with a short delay:
local function clear_final(final)
if not bmd.fileexists(final) then return true end
for _=1,3 do if os.remove(final) then return true end; nap(0.12) end
-- fallback: rename to .old
local old = string.format("%s.%s.%s.old", base, ext, now_ms())
if os.rename(final, old) then
os.remove(old)
return true
end
return false
end
Why the retries?
Network drives (SMB, NFS) sometimes hold file locks for a fraction of a second after a process closes the file. On a local SSD, os.remove() succeeds instantly. On a NAS, it might fail the first time, succeed after 120ms.
The retry loop with nap(0.12) (a 120ms sleep) gives the filesystem time to release the lock. If all retries fail, the script renames the old file to .old as a last resort, then cleans it up asynchronously.
This prevents the script from failing just because the NAS was slow to release a file lock—a real problem I encountered when rendering to client network drives at my 9-to-5.
4. Restoring Saver Paths
After finalizing outputs, the script restores any Saver nodes that still point to temp files:
for _, s in pairs(savers) do
local clip = s.Clip and s.Clip[comp.CurrentTime] or ""
for _, m in ipairs(maps) do
if clip == m.tmp then s.Clip = m.final end
end
end
This ensures the Fusion comp is left in a clean state—all Savers point to their final output paths, not temp files. If I reopen the comp later, the Savers show the correct paths.
Use Cases
Primary: One-Shot Clean Renders for Motion Graphics
When I'm rendering motion graphics comps in Fusion Studio (1-2 times per month), I use this script to:
- Clean up old outputs
- Render the comp
- Finalize outputs
- Suppress the "Render Completed" popup
All with one keystroke (Cmd+Shift+R).
Secondary: Batch Rendering Multiple Comps
If I have 5-10 Fusion comps to render (e.g., a series of lower thirds for a client project), I can:
- Open the first comp
- Hit Cmd+Shift+R (script runs, render completes silently)
- Open the next comp
- Repeat
Without the "Render Completed" popup interrupting me, I can batch-render comps faster. The script handles cleanup and finalization automatically, so I don't have to remember to delete old frames or swap temp files.
Why Not Just Use ClearSaverOutputs + Manual Render?
ClearSaverOutputs works great, but it's three manual steps:
- Run ClearSaverOutputs (pre-clean)
- Cmd+R to render
- Wait for PostRender script to finalize
And the "Render Completed" popup still interrupts the workflow.
Render_Clean_Silent collapses all three steps into one action and suppresses the popup. For someone who only uses Fusion Studio 1-2 times per month (I do most work in Resolve's Fusion page), having a single "just render it cleanly" script is easier to remember than a multi-step workflow.
Time Savings
Manual process:
- Navigate to output folders, delete old frames/movies: 15-30 seconds
- Return to Fusion, Cmd+R to render
- Wait for "Render Completed" popup, click OK: 2 seconds
- Run PostRender script to finalize temp files: 3-5 seconds
Total manual time: 20-37 seconds of overhead (not counting actual render duration).
Automated process: Hit Cmd+Shift+R, wait for render to complete. Total overhead: ~1 second (cleanup + finalization happen automatically, no popups).
Savings per render: 19-36 seconds.
I use this 1-2 times per month when working in Fusion Studio. At 2 renders per month, this saves 38-72 seconds (0.6-1.2 minutes) monthly.
But the real value is zero mental overhead. I don't have to remember the three-step workflow or deal with the "Render Completed" popup breaking my focus. The script handles everything, and I can move on to the next comp.
Implementation Notes
This script requires:
- Fusion Studio (standalone compositor, not the Fusion page in DaVinci Resolve)
- Lua scripting enabled (default in Fusion Studio)
Setting Up as a Render Script
To use this script:
Save
Render_Clean_Silent.luato your Fusion scripts folder:- macOS:
~/Library/Application Support/Blackmagic Design/Fusion/Scripts/Comp/ - Windows:
C:\Users\[USERNAME]\AppData\Roaming\Blackmagic Design\Fusion\Scripts\Comp\
- macOS:
Bind it to a keyboard shortcut:
- Open Fusion Studio
- Go to Fusion → Preferences → Global and Default Settings → Scripting
- Under Comp Scripts, assign a shortcut to
Render_Clean_Silent(I use Cmd+Shift+R)
To render a comp with automatic cleanup and finalization, hit your shortcut.
Customizing Sequence Cleanup Policy
The SEQ_POLICY variable controls how image sequences are cleaned:
local SEQ_POLICY = "delete_range"
Options:
delete_range: Delete only frames within the render range (default, safest)delete_all: Delete all frames matching the Saver's naming patternnone: Skip sequence cleanup entirely
I recommend delete_range for most workflows—it's the safest option for iterative rendering where you only re-render specific frame ranges.
Adding New File Formats
To add support for a new movie or image format, update the lookup tables:
local MOVIE_EXT = { mov=true, mp4=true, webm=true } -- Added webm
local IMAGE_EXT = { exr=true, dpx=true, tga=true }
Using the [KEEP] Opt-Out
To prevent cleanup for a specific Saver node:
- Select the Saver in the Flow view
- Open the Comments field (right panel, under "Comments")
- Add
[KEEP]anywhere in the comments (case-insensitive)
The script will skip cleanup for that Saver, preserving its existing output.
Comparison to ClearSaverOutputs
I maintain two Fusion render automation scripts:
| Script | Use Case | Steps | Popups | Finalization |
|---|---|---|---|---|
| ClearSaverOutputs.lua | Pre-render cleanup only (requires manual render + PostRender script) | 3 manual steps | "Render Completed" popup | Separate PostRender script |
| Render_Clean_Silent.lua | One-shot clean render (cleanup + render + finalization) | 1 keystroke | None (silent) | Built-in |
When to use ClearSaverOutputs:
- You want manual control over each step (cleanup, render, finalize)
- You need to review cleanup results before rendering
- You're integrating with a custom PostRender workflow
When to use Render_Clean_Silent:
- You want a single "just render it cleanly" command
- You're batch-rendering multiple comps and don't want popups
- You don't need to review cleanup results (trust the script)
I use Render_Clean_Silent 90% of the time because I trust the cleanup logic and prefer the faster one-shot workflow. ClearSaverOutputs is there for edge cases where I need more granular control.
Why This Matters
Fusion Studio is an incredible compositor, but its render workflow feels dated compared to DaVinci Resolve's streamlined Deliver page. Render_Clean_Silent bridges that gap by automating the entire render pipeline—cleanup, rendering, finalization—with one keystroke and zero popups.
For anyone working in Fusion Studio for complex motion graphics or VFX work—especially if you're coming from Resolve and expect a polished render workflow—this script eliminates friction and prevents the "mixed old/new frames" frustration that plagues iterative rendering.
The silent rendering with comp:Lock() is a quality-of-life improvement that shouldn't be underestimated. When you're batch-rendering multiple comps or rendering overnight, the "Render Completed" popup breaking your workflow (or staying on-screen until you manually dismiss it) is pure friction. Suppressing it entirely makes Fusion feel more like a modern render pipeline.
The defensive clear_final() function with retry logic is a real-world necessity for network drive rendering. On a local SSD, os.remove() succeeds instantly. On a NAS at my 9-to-5 (QuikTrip client projects), file locks can linger for 120-300ms after a process closes the file. The retry loop handles this gracefully instead of failing and leaving temp files scattered across the filesystem.
And the temp name redirection for movie outputs—rendering to .rendering.TIMESTAMP.ext then swapping to the final name—prevents partial overwrites, file lock issues, and data loss from failed renders. It's the same strategy browsers use for downloads ("Downloading… → Move to Downloads folder"), and it's just as valuable for rendering.
This script shows what's possible when you stop accepting software limitations and build the workflow you actually want. Fusion Studio doesn't have "Delete before render" or silent rendering out of the box, but the Lua API is powerful enough to add both. The entire script is ~160 lines—a small investment for eliminating manual cleanup, popup interruptions, and post-render finalization steps.