Nodes/ComfyUI_PHRenderFormerWrapper/RenderFormer Mesh Target
ComfyUI Node

RenderFormer Mesh Target

Make your object move, spin, or shift color over the shot

By paulh4x·Created about a year ago·Updated about a year ago· 37
RenderFormer Mesh Target
  • start_mesh
  • MESH
end_mesh_pos_x0.000
end_mesh_pos_y0.000
end_mesh_pos_z0.000
end_mesh_rot_x0.0
end_mesh_rot_y0.0
end_mesh_rot_z0.0
end_scale1.00
end_diffuse_rgb204, 204, 204
end_specular_rgb25, 25, 25
end_roughness0.70

The camera and light can move, so why shouldn't the thing you're rendering? RenderFormerMeshTarget animates a mesh itself: position, rotation, scale, and even its material (diffuse color, specular color, roughness) can all interpolate from the mesh's start state to a state you define. It's one of the 15 nodes in paulh4x/ComfyUI_PHRenderFormerWrapper, the "100% vibecoded" wrapper around Microsoft's RenderFormer (SIGGRAPH 2025), and it's the newest piece of the animation story (added in v0.4.0).

How it works

Same keyframe philosophy as the Camera/Lighting Target nodes: it takes your start_mesh, builds an end-state copy with your typed-in values, and outputs a dict of {"start_meshes": {...}, "end_meshes": {...}}. Because a MESH can contain multiple sub-meshes (from a Combine), the node creates a start/end pair for every sub-mesh and tags each with a UUID so downstream nodes can track which object is which. The Scene Builder handles the actual frame interpolation.

The inputs

  • start_mesh - a MESH (from LoadMesh, RandomizeColors, Remesh, etc.).
  • end_mesh_pos_x/y/z - where the object ends up (defaults 0, 0, 0).
  • end_mesh_rot_x/y/z - end rotation, −360 to 360. This is your "spinning object" lever.
  • end_scale - end size, default 1.
  • end_diffuse_rgb (default 204, 204, 204), end_specular_rgb (default 25, 25, 25), end_roughness (default 0.7) - the material end state. Color shifting over time is a genuinely fun effect and one this pack handles cleanly.

One output: MESH - which is actually the start/end sequence dict, typed as MESH so it can flow through the Mesh Combine node.

Wiring it in

The intended chain is: MeshTargetRenderFormerMeshCombineScene Builder. The Combine node understands both static MESH and this animated dict form, merges them, and emits a MESH_ANIMATED sequence for the Scene Builder's mesh_sequence input - while also filtering the animated object out of the static list so nothing renders twice. From there it's the usual num_frames > 1 on the Scene Builder.

Installing it

# ComfyUI Manager: search "ComfyUI_PHRenderFormerWrapper"
cd ComfyUI/custom_nodes/
git clone https://github.com/paulh4x/ComfyUI_PHRenderFormerWrapper.git
cd ComfyUI_PHRenderFormerWrapper
git clone https://github.com/microsoft/renderformer.git renderformer
pip install -r requirements.txt
python -c "import imageio; imageio.plugins.freeimage.download()"

Restart ComfyUI.

Common issues

  • "Invalid start_mesh input" - start_mesh must contain a mesh list. Feeding it the MESH_ANIMATED output of a Combine (instead of a static MESH) is the classic mistake - the Target wants a plain mesh, Combine handles sequences.
  • Object disappears partway through the animation - check the end position. If the end state is far outside the camera's view, the object visibly travels out of frame, which is "working as intended," just surprising.
  • Flicker with glossy objects - the known pack-wide animation caveat applies here too: high-roughness-shininess materials can flicker frame to frame.

It's the node that turns a static product shot into a spinning, drifting, color-shifting showcase - and it's the closest this pack gets to a motion graphics tool.

CategoryPHRenderFormer

Inputs (11)

NameTypeDefaultDescription
start_meshMESH
end_mesh_pos_xFLOAT0.000-10–10
end_mesh_pos_yFLOAT0.000-10–10
end_mesh_pos_zFLOAT0.000-10–10
end_mesh_rot_xFLOAT0.0-360–360
end_mesh_rot_yFLOAT0.0-360–360
end_mesh_rot_zFLOAT0.0-360–360
end_scaleFLOAT1.000.1–10
end_diffuse_rgbSTRING204, 204, 204
end_specular_rgbSTRING25, 25, 25
end_roughnessFLOAT0.700–1

Outputs (1)

NameTypeDescription
MESHMESH