Forge: texture from views

texture_from_views (agent tool) and f.textureFromViews (Forge recipe call) give any model one painted base-colour texture from a reference sheet: the views a picture model (Nano Banana) or an artist drew of the object, on a plain backdrop. All of it is our own code (Sources/TTRForgeKernel/ViewPaint).

What happens:

  1. Automatic UVs. The model is cut into charts that each face roughly one way, every chart is flattened as-rigid-as-possible (each triangle keeps its real size and shape as far as the surface allows), charts that would stretch, flip or fold are split, and everything is packed into one 0–1 atlas with padding. Measured on every run: area stretch (95th percentile), overlapping texels, atlas fill.
  2. Cameras from outlines. Each panel of the sheet is keyed off its backdrop, and its camera is found by matching the model's rendered outline to the panel's (intersection over union). Which way a side view faces and which way a top view points is decided by the outline, as is the model's front. Three-quarter views get an orbit camera (yaw/pitch searched, then a perspective camera — field of view, distance, offset, yaw, pitch — when drawn or shot in perspective, which a straight orthographic fit misjudges by up to ~8° of yaw); turnarounds solve one start angle and turning direction for the whole set (front/back ambiguity on symmetric objects is settled by colour agreement between neighbouring views).
  3. Projection painting. For every texel: which surface point it shows; for every view: is that point visible (depth test), how squarely does the view see it, how far is it from the picture's outline and from depth jumps. Views are harmonised (one exposure gain per view and channel, least squares over the surface they share), then blended in two bands: broad colour with wide weights (no visible hand-over), fine detail from the squarest view (no ghosting). Unseen texels are inpainted over the mesh; the empty atlas is dilated from the charts.
  4. Measures. Colour error (CIE76 and CIEDE2000 ΔE, unlit "neutral light" render from each view's camera vs the view), an optional held-out view (hold_out: painted without it, measured on it), and the DetailCritic seam score (DetailCritic.seam, gate ≤ 1.2) from four angles around the object, for UV-island seams and for seams between regions painted from different pictures.

Sheets

layoutpanels
sheet_2x2 (default)front, side, top, three-quarter (the Nano Banana 2 × 2 sheet)
grid + columns, rows, viewsnamed views in reading order: front, back, side, top, bottom, three_quarter, skip
turnaround + columns, rowsviews at equal steps around the object

Use the delit / albedo version of a sheet when you have one (the shading in a drawn sheet gets painted in otherwise). symmetric: true (default) also paints the side view mirrored onto the other flank.

Agent tool

{"name": "texture_from_views", "arguments": {"model": "Forge/racer_carved.glb",
 "sheet": "References/ultracode-1014/racer_views/racer_albedo_A.jpg", "layout": "sheet_2x2", "hold_out": "three_quarter"}}

Writes Assets/Forge/<name>.glb (the painted model, texture embedded), <name>_basecolor.png, <name>.viewpaint.json (every measure) and pictures in Renders/viewpaint/<name>/: each sheet view beside the painted model from the same camera, and the four test angles.

Recipe call

// Beside the recipe: statue.glb and statue_sheet.png (front, side, back, top in one row)
const r = f.textureFromViews({model: "statue.glb", sheet: "statue_sheet.png",
                              views: ["front", "side", "back", "top"], columns: 4, rows: 1, size: 2048});
log("colour error", r.delta_e76, "worst seam", r.worst_seam);

Options (both): front / up [x, y, z], symmetric, hold_out, size (512…4096), backdrop [r, g, b] 0…1, chart_angle, padding, facing_power, oblique_trust (weight of three-quarter views, default 0.5), two_band (blur radius in pixels, 0 = one band), perspective (default true: three-quarter views also try perspective cameras, fields of view 12°–56°, refined on the outline; kept only when the outline fits ≥ 0.01 IoU better than orthographic), roughness, metallic.

Limits

The paint can only be as right as the shape. On a carved silhouette hull (no concavities) surfaces that the true object has elsewhere get painted by whichever view sees them squarest, so a view whose surfaces the hull misplaces (the racer's front) reproduces worse than the others. Better shape (part A/B of the Tripo-level run) lowers it.

Arcwright Beta 2 (0.4.0) · generated from the engine source (25e375c86)Something wrong or missing? Tell us
Download Arcwright free