Nodes/SAM3D Cam Shot Toolkit/Cam Shot Toolkit: Render Offset View
ComfyUI Node

Cam Shot Toolkit: Render Offset View

The payoff node that puts your person back in the shot

By EnviralDesign·Created 5 months ago·Updated 11 days ago· 1
Cam Shot Toolkit: Render Offset View
  • mesh_data
  • reference_image
  • rendered_image
  • camera_info
render_width512
render_height512
enable_viewertrue
use_interactive_viewtrue
autofalse
show_viewer_hudfalse
focal_scale1.00
lighting_presetstudio
ambient_intensity0.35
key_intensity14.0
key_yaw35.0
key_pitch35.0
fill_intensity6.0
rim_intensity8.0
mesh_r235
mesh_g235
mesh_b235
bg_presetmid_gray
bg_r38
bg_g38
bg_b38
interactive_state{}

This is the node the whole pack is named after, and the reason a 3D reconstruction is worth doing at all. Process Image gives you a mesh of a person standing in some original photo; Render Offset View lets you move the camera around that mesh and render a new frame - same person, same world, different angle - while keeping the lens calibrated to the original shot. If you've ever tried to fake a new camera angle on a 2D image with ControlNet and watched it invent geometry, this is the version that doesn't have to guess.

How it works

Two inputs set the whole thing up. mesh_data comes straight from Process Image, and reference_image is the photo the person was reconstructed from. The node reads the reconstruction's focal length and uses the reference image's aspect ratio to compute matching intrinsics - fx, fy, and the principal point - scaled to your render_width/render_height. That's the "calibrated" part: the render behaves like a real camera that was at the original shoot, so a focal_scale of 1.0 puts the mesh back in roughly the same framing the photo had.

Then it renders. Here's the part worth appreciating: there's no PyOpenGL, no pyrender, no OSMesa, no EGL - nothing to compile. The pack ships a self-contained NumPy mesh rasterizer that projects vertices, shades faces, and composites the frame. It's deliberately simple (flat-ish studio shading, mesh color, background color), but it runs anywhere your Python runs and installs without a fight. That trade - boring shading for zero native-dependency pain - is the right one for a tool whose whole point is camera setup, not final beauty lighting.

The interactive viewer

The fun part is enable_viewer. When it's on, the node mounts a Three.js preview in the browser where you can orbit, pan, roll, and dolly the camera to scout your shot. The camera you settle on gets saved into the hidden interactive_state string, and on the next workflow run the backend rasterizer reproduces that exact pose - no live WebGL frame, just the saved state. Two switches govern this:

  • use_interactive_view (default on) - the browser camera overrides the parameter-based camera when saved state exists.
  • auto (default off) - ignore any saved viewer camera and realign from the current SAM 3D input on every run. This is the one to flip for API/batch workflows where you don't want a stale saved camera from a previous session steering your render.

For beginners, the honest workflow is: keep use_interactive_view on, scout in the viewer, and let the saved state do the work. The parameter camera (key/lighting/bg fields) matters more once you want reproducible shots without the viewer.

The inputs you'll actually touch

Beyond the camera logic above: lighting_preset (studio/flat/dramatic), bg_preset (mid_gray/black/white/custom), mesh_r/g/b to tint the mesh, and focal_scale to push the lens wider or tighter. Render size caps at 4096. The two outputs are rendered_image (a normal IMAGE you can preview, save, or feed back into a pipeline) and camera_info, a JSON string carrying the calibrated camera - focal lengths, principal point, camera position, target - which is gold if you're exporting the shot to Blender or Unreal later.

Installation and gotchas

Same pack install as everything else here:

cd ComfyUI/custom_nodes
git clone https://github.com/EnviralDesign/sam3d-body-comfyUI-camshottoolkit
python -m pip install -r sam3d-body-comfyUI-camshottoolkit/requirements.txt

Restart, then wire mesh_data and the original photo in. The two ways people trip: forgetting reference_image, which the node needs to define intrinsics (wire the same image you processed - it's required, so this is less a trap and more a "why won't it connect" moment), and expecting a photoreal render. This is a preview/blocking render, not a final beauty pass - it gets the camera right, and you take the camera_info out to a real renderer for the pretty version.

CategoryCamShotToolkit/visualization

Inputs (24)

NameTypeDefaultDescription
mesh_dataSAM3D_OUTPUTMesh data from SAM3DBodyProcess node
reference_imageIMAGEReference image used to define the original camera intrinsics
render_widthINT51264–4096
render_heightINT51264–4096
enable_viewerBOOLEANtrueMount the interactive preview viewer for this node.
use_interactive_viewBOOLEANtrueIf enabled, the browser viewer camera overrides the parameter-based camera when available.
autoBOOLEANfalseIgnore saved viewer camera state and align from the current SAM3D input on every run.
show_viewer_hudBOOLEANfalseShow the camera HUD overlay in the interactive viewer.
focal_scaleFLOAT1.000.1–4
lighting_presetCOMBOstudioQuick lighting profile
ambient_intensityFLOAT0.350–3
key_intensityFLOAT14.00–100
key_yawFLOAT35.0-180–180
key_pitchFLOAT35.0-89–89
fill_intensityFLOAT6.00–100
rim_intensityFLOAT8.00–100
mesh_rINT2350–255
mesh_gINT2350–255
mesh_bINT2350–255
bg_presetCOMBOmid_grayQuick background color preset
bg_rINT380–255
bg_gINT380–255
bg_bINT380–255
interactive_stateSTRING{}Hidden interactive camera state managed by the viewer.

Outputs (2)

NameTypeDescription
rendered_imageIMAGE
camera_infoSTRING