Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Headless Rendering

Flint can render scenes to PNG images without opening a window. This enables automated screenshots, visual regression testing, and CI pipeline integration.

The flint render Command

flint render levels/tavern.scene.toml --output preview.png

This loads the scene, renders a single frame with PBR shading and shadows, and writes the result to a PNG file.

Camera Options

Control the camera position with orbit-style parameters:

flint render levels/tavern.scene.toml \
    --output preview.png \
    --width 1920 --height 1080 \
    --distance 30 \
    --yaw 45 \
    --pitch 30
FlagDefaultDescription
--output <path>render.pngOutput file path
--width <px>1920Image width in pixels
--height <px>1080Image height in pixels
--distance <units>(auto)Camera distance from origin
--yaw <degrees>(auto)Horizontal camera angle
--pitch <degrees>(auto)Vertical camera angle
--target <x,y,z>(auto)Camera look-at point (comma-separated)
--fov <degrees>(auto)Field of view in degrees
--no-gridfalseDisable ground grid
--schemas <path>schemasPath to schemas directory (repeatable)

Post-Processing Flags

Control post-processing from the command line:

# Disable all post-processing (raw shader output)
flint render scene.toml --no-postprocess --output raw.png

# Custom bloom settings
flint render scene.toml --bloom-intensity 0.08 --bloom-threshold 0.8

# Adjust exposure
flint render scene.toml --exposure 1.5
FlagDefaultDescription
--no-postprocessfalseDisable entire post-processing pipeline
--bloom-intensity <f32>0.04Bloom mix strength
--bloom-threshold <f32>1.0Minimum brightness for bloom
--exposure <f32>1.0Exposure multiplier

Debug Rendering Flags

Render debug visualizations for diagnostics:

# Wireframe view
flint render scene.toml --debug-mode wireframe --output wireframe.png

# Surface normals
flint render scene.toml --debug-mode normals --output normals.png

# Other modes: depth, uv, unlit, metalrough
flint render scene.toml --debug-mode depth --output depth.png

# Wireframe overlay on solid geometry
flint render scene.toml --wireframe-overlay --output overlay.png

# Normal arrows
flint render scene.toml --show-normals --output arrows.png

# Raw linear output (no tonemapping)
flint render scene.toml --no-tonemapping --output linear.png
FlagDefaultDescription
--debug-mode <mode>(none)wireframe, normals, depth, uv, unlit, metalrough
--wireframe-overlayfalseDraw wireframe edges over solid shading
--show-normalsfalseDraw face-normal direction arrows
--no-tonemappingfalseDisable tonemapping for raw linear output
--no-shadowsfalseDisable shadow mapping
--shadow-resolution <px>1024Shadow map resolution per cascade

CI Pipeline Integration

Headless rendering works on machines without a display. Use it in CI to catch visual regressions:

# Example GitHub Actions step
- name: Render preview
  run: |
    cargo run --bin flint -- render levels/tavern.scene.toml \
      --output screenshots/tavern.png \
      --width 1920 --height 1080

- name: Upload screenshot
  uses: actions/upload-artifact@v4
  with:
    name: screenshots
    path: screenshots/

Visual Regression Testing

A basic visual regression workflow:

  1. Baseline — render a reference image and commit it:

    flint render levels/tavern.scene.toml --output tests/baseline/tavern.png
    
  2. Test — after changes, render again and compare:

    flint render levels/tavern.scene.toml --output tests/current/tavern.png
    # Compare with your preferred tool (ImageMagick, pixelmatch, etc.)
    
  3. Update — if the change is intentional, update the baseline:

    cp tests/current/tavern.png tests/baseline/tavern.png
    

Since Flint’s renderer is deterministic for a given scene file and camera position, identical inputs produce identical outputs.

Rendering Multiple Views

Script multiple renders for different angles:

#!/bin/bash
SCENE="levels/tavern.scene.toml"

for angle in 0 90 180 270; do
    flint render "$SCENE" \
        --output "screenshots/view_${angle}.png" \
        --yaw $angle --pitch 25 --distance 25 \
        --width 1920 --height 1080
done

Rendering Pipeline Details

Headless rendering uses the same wgpu PBR pipeline as the interactive viewer:

  • Cook-Torrance BRDF with roughness/metallic workflow
  • Cascaded shadow mapping for directional light shadows
  • glTF mesh rendering with full material support
  • Skinned mesh rendering with bone matrix upload (for skeletal meshes)

The only difference from interactive rendering is that the output goes to a texture-to-buffer copy instead of a swapchain surface.

Further Reading