A generated helmet looks correct in the studio preview and correct in Blender’s material preview. Then you put a decal on the left side plate in-engine, and it smears across the cheek guard at roughly half the size it should be, rotated about eight degrees off vertical. The mesh is fine. The baked texture is fine. The UV layout sitting underneath both of them is the problem.
This is the single most common reason an asset that looks finished is not finished. Photogrammetry, scan cleanup and AI mesh generation share a characteristic: geometry is produced first, and UVs are produced afterwards by an automatic unwrapper that has no idea what the object is, which side faces the camera, or where a human will later want to place text, wear, dirt or a tiling material.
What the generator actually hands you
In almost every case you get a single 0–1 UV tile containing one atlas of automatically cut and packed islands, plus one texture set baked into that atlas. The unwrapper is usually angle-based: it walks the mesh, cuts where curvature exceeds a threshold, relaxes each shell with an LSCM or ABF solver, then feeds the shells to a rectangle packer.
That pipeline is optimised for exactly one goal, which is getting the generated colour onto the surface without visible stretching at the resolution it was baked at. It is not optimised for anything you do afterwards. Four things go wrong, in roughly this order of frequency.
1. Texel density varies wildly across the model
Texel density is pixels of texture per centimetre of surface. Automatic packers maximise area usage, not consistency, so a large flat shell and a small curved shell often end up at completely different scales in UV space.
Here is a measurement from a generated 1.7 m humanoid with a single 2048 × 2048 texture. Total surface area is about 3.4 m², so a perfect pack would give roughly 11 px/cm everywhere. Actual measured values:
| Shell | Surface area | Texel density | Ratio to target |
|---|---|---|---|
| Torso front | 0.31 m² | 14.2 px/cm | 1.29× |
| Torso back | 0.29 m² | 13.8 px/cm | 1.25× |
| Upper legs | 0.42 m² | 9.6 px/cm | 0.87× |
| Hands | 0.06 m² | 3.1 px/cm | 0.28× |
| Face | 0.04 m² | 5.4 px/cm | 0.49× |
The hands get 28% of the density of the torso. On a third-person character the hands are frequently the closest thing to the camera, so you have the resolution distributed backwards. Nothing in the preview reveals this, because the baked texture was generated in the same broken space and therefore matches perfectly.
2. Seams land where you will see them
Curvature-based cutting has no concept of a hairline. It will happily run a seam down the bridge of the nose, across a forehead, or along the top edge of a shoulder pauldron. Baked colour hides this at mip 0. Then you compress to BC7, the encoder blocks straddle the island padding, mip 3 starts bleeding neighbouring islands together, and a dark line appears down the face at medium distance.
3. Overlapping and mirrored shells
Packers sometimes stack shells to save space, and some generators deliberately mirror symmetric halves. Both are harmless for the original bake and destructive for everything else. Overlapping UVs break lightmap baking outright, make unique asymmetric damage impossible, break decal placement, and produce garbage when you try to author ID masks in Substance or Mari.
4. There is no second UV channel
Unity and Unreal both want a separate, non-overlapping UV set for baked lighting. Both engines will generate one for you at import, and the generated result is mediocre on dense irregular meshes: a 90k-triangle generated rock can produce 400+ lightmap charts, each needing padding, which wastes most of a 512 lightmap.
Symptom to cause, quickly
| What you see | Cause | Fix | Time |
|---|---|---|---|
| Decal stretched or rotated | Non-uniform or rotated shells | Re-unwrap that region, align to grid | 10 min |
| Blurry hands, sharp torso | Texel density variance | Repack at fixed density | 25 min |
| Dark seam appears at distance | Padding under 4 px, mip bleed | Repack with 8 px padding at 2048 | 10 min |
| Lightmap has black splotches | Overlapping shells in channel 1 | Generate a clean second channel | 5 min |
| Normal map creases along a cut | Tangent basis mismatch across seam | Rebake normals with Mikktspace | 15 min |
| Tiling material looks scrambled | Shells not axis-aligned | Manual unwrap with straightened shells | 40 min |
When to leave it alone
Most generated assets do not need any of this. If the object is a background prop that never exceeds 60 pixels on screen, never receives a decal, never gets baked lighting and never gets a tiling material, the automatic layout is completely adequate and re-unwrapping it is wasted hours.
The second pass earns its cost on: hero props the player can hold or inspect, anything that carries branding or text, anything that will be lightmapped, anything you will re-texture in Substance Painter, and modular kit pieces that must share texel density with their neighbours.
The second pass, step by step
The key idea is that you do not repaint anything. You build better UVs, then transfer the existing texture onto them with a bake. Ten minutes of setup saves you an afternoon of hand-painting.
- Finish the geometry first. Any remesh, decimate or boolean invalidates the UVs you are about to author. Lock the mesh before you touch UV space.
- Duplicate the object. The original, with its original UVs and its original texture assigned, becomes the bake source. The duplicate becomes the target.
- Clear and re-seam the target. Put cuts where a human would: under arms, behind ears, along the inside of limbs, along existing hard edges and panel lines. Symmetric objects get one half unwrapped and mirrored, then the mirrored half offset by exactly 1.0 in U so it occupies its own tile during the bake.
- Unwrap and straighten. Angle-based unwrap, then relax, then straighten any shell that will receive a tiling or directional material. Straight shells are the difference between a usable wood grain and a swirl.
- Pack to a fixed density. Pick a number and hold it across the whole asset and its neighbours. Padding of 8 px at 2048 and 4 px at 1024 survives a full mip chain without bleeding.
- Bake source to target. In Blender that is Selected to Active with Cage enabled and an extrusion around 0.02 m for a human-scale object. Bake base colour, normal, roughness, metallic and AO as separate passes. Set the normal bake to tangent space and confirm your tangent basis matches your engine.
- Verify with three checks. A checker map at 1024 to confirm density; forcing mip 4 to confirm padding; and a test decal on a curved region to confirm the layout behaves.
By hand this runs 20 to 45 minutes per asset. With RizomUV auto-seams plus a packer like UVPackmaster it drops to about 5 minutes for anything that is not organic.
Density targets that work
| Asset class | Target density | Texture at 1 m² | Typical map size |
|---|---|---|---|
| Hero character, close cutscene | 20.5 px/cm | 2048² | 4096 for the body |
| Player-held prop | 20.5 px/cm | 2048² | 2048 |
| Interactive environment prop | 10.2 px/cm | 1024² | 1024–2048 |
| Modular architecture | 5.1 px/cm | 512² | 2048 for a 4 m wall |
| Distant set dressing | 2.6 px/cm | 256² | 512 |
| Mobile or standalone VR | 5.1 px/cm | 512² | 1024 hard cap |
Pick one row per asset class and write it down somewhere the whole team reads. Consistency matters more than the specific number: a scene where everything sits at 5.1 px/cm reads better than a scene mixing 20.5 and 2.6.
Do and don’t
- Do bake the old texture onto the new layout instead of repainting. It is nearly free and preserves the generated detail exactly.
- Do keep the original file untouched. You will want the source atlas again.
- Do offset mirrored shells by a full UV tile before baking, then move them back afterwards.
- Don’t re-unwrap before you have finished decimating or remeshing. You will redo it.
- Don’t trust the engine’s automatic lightmap UV generator on a mesh above about 50k triangles without checking the chart count.
- Don’t use padding below 4 px on any texture that ships with mips. The artefact only appears at distance, which is exactly when nobody is testing.
- Don’t re-unwrap every asset on principle. Most of them do not need it, and the time is better spent on the six models the player actually looks at.
Where to start tomorrow
Open the last three generated models you shipped and apply a 1024 checker map to each. Anything where the checker squares visibly change size across the surface is a candidate. Sort those by how close the player gets to them, take the top two, and run the bake-transfer workflow above on those only.
Then set your density standard before the next batch of models arrives. If you are generating assets in a studio like MeshyFlix and exporting GLB, the automatic layout you receive is the baseline you are measuring against, and knowing your own target number turns “does this need work?” into a thirty-second measurement instead of an argument.