Skip to main content

PS1 Asset Optimizer

The PS1 Asset Optimizer creates a lower-poly runtime copy of a static OBJ or FBX while preserving the project source and a reproducible import recipe. It is intended for modern assets whose silhouette is useful but whose topology is too dense for a PlayStation 1 production budget.

The optimizer is a constrained simplifier, not a one-click art replacement. It stops before a requested target when reaching it would violate the enabled topology, UV, material, symmetry, normal, or vertex-displacement constraints.

Open the Optimizer

  1. Import an OBJ or static FBX into Assets/Models/.
  2. Select the source in the Project panel.
  3. In the Model Inspector, click Open PS1 Asset Optimizer.
  4. Choose the closest Asset Role.
  5. Start from Use Recommended Target, then adjust the logarithmic triangle slider if the asset needs a different trade-off.
  6. Inspect the source preview, compatibility report, and comparison counts in the same optimizer window, then click Generate Optimized Output.
  7. Keep the window open while generation runs. Compare Source and Generated with the shared preview controls, then adjust and generate another pass if needed.

The optimizer is a modeless, movable, and resizable workspace. It does not hide or lock the Inspector behind it, and it can always be closed with its title-bar X, Close Window, or Escape. Wide windows show preview/status and recipe side by side; compact windows switch them into tabs so controls are not clipped.

Generation runs as a background import. The optimizer keeps its action footer visible and shows progress plus a Cancel action; cancellation stops before a partial candidate is published. You may close the optimizer while the job continues. Other asset edits and imports wait for the model transaction, preventing two jobs from overwriting the asset database concurrently.

The Inspector automatically offers the optimizer for especially dense static models. Imported files chosen outside the project are copied into Assets/Models/ before processing. The source is never rewritten; only the generated .msh under Library/ is replaced.

Recommendations and Asset Roles

The recommendation combines the model role with the project's configured per-mesh triangle budget.

RoleIntended contentDefault guidance
AutoUnknown or mixed contentUses source triangle count and project budget
HeroClose-up focal objectUp to about 2,000 triangles
CharacterReadable animated-style silhouette, imported as staticUp to about 1,800 triangles
PropCommon world objectUp to about 800 triangles
EnvironmentModular level sectionUses the project per-mesh soft limit, capped at 2,048

These values are recommendations, not new hardware limits. Scene triangle count, material changes, texture pages, overdraw, ordering-table behavior, and CPU work still determine whether the asset is appropriate.

Quality and Preservation Controls

The optimizer uses deterministic quadric-error edge collapse on the OpenMesh topology kernel with explicit Polygon Engine constraints. OpenMesh is bundled under its BSD license and listed in the product's third-party notices.

ControlEffect
QualitySelects edge sensitivity plus conservative, balanced, or aggressive normal/error defaults
SymmetryAuto-detects or explicitly preserves an X, Y, or Z mirror plane
Preserve BoundariesPrevents open borders from being collapsed away
Preserve UV SeamsProtects incompatible UV islands and rejects surviving UV triangles that collapse, flip, or exceed the allowed area-ratio change
Preserve Hard EdgesProtects sharp normal discontinuities
Preserve Material BoundariesKeeps material regions separated
Max Normal DeviationStops collapses that rotate surfaces too far
Max Vertex DisplacementCaps accumulated collapsed-vertex displacement as a percentage of the source bounds diagonal

Auto symmetry enables paired collapses only when the source has a reliable mirrored vertex and face correspondence. An explicit symmetry axis fails closed if that correspondence cannot be guaranteed. Center-plane vertices remain on the plane.

The optimizer always preserves the number of connected components. When Preserve Boundary Loops is enabled, it also preserves the number of boundary-loop components. In that mode, “no new holes” means an accepted result does not create or remove those loop components. A non-manifold or invalid source is rejected with an actionable message instead of being guessed at.

Preview and Result

The optimizer window keeps the asset path, source/generated/recommended counts, complete PS1 compatibility report, import errors, preservation controls, and preview together. When no valid generated candidate exists, the first optimizer view selects Source automatically instead of showing an empty generated preview. After generation, switch between Source and Generated with the same orbit and display mode. Very dense sources are sampled deterministically to keep the comparison responsive. The sampled source preview is cached under Library/model_previews/, so the comparison remains available after restarting the editor and is regenerated whenever the model is reimported. Use:

  • Textured + Wireframe for topology over the final material;
  • Wireframe for density and long triangles;
  • Silhouette for the outer contour;
  • UV Density for relative UV coverage differences; magenta marks a degenerate geometric or UV triangle;
  • PS1 Quantized for the runtime-oriented vertex appearance.

The visible result status and stored metadata record whether the target was reached, detected symmetry, source/output vertices and triangles, the accumulated vertex-displacement bound, and a stop reason. If the target was not reached, lower the preservation constraints only after checking why the protected feature matters.

Source and Runtime Limits

The import working mesh uses 32-bit indices so a source above 65,535 vertices can be parsed and simplified. The generated PS1 .msh still uses 16-bit indices. Generation fails before replacing the prior output if the optimized mesh remains above 65,535 vertices or contains invalid indices.

The generated mesh is also capped at the runtime's 2,048 sortable triangles. This is a hard output contract even if a project raises its authoring soft limit. T-junction repair is accounted for after simplification; if repair raises the final count above the requested target, the result is marked as the best valid result, and a result above 2,048 is rejected.

T-junction repair and detailed PS1 topology diagnostics run after simplification. Extremely dense candidates may skip expensive diagnostics and report that decision rather than freezing the editor.

Reimport and Recipes

Optimization is part of the model import recipe. The following choices are stored in source metadata and included in the importer settings hash:

  • enabled state and requested triangle target;
  • role and quality;
  • symmetry mode;
  • boundary, UV seam, hard-edge, and material-boundary preservation;
  • normal-deviation and vertex-displacement limits.

Reimporting the source reproduces the recipe. Changing one of these settings invalidates the generated result. Mesh, optional new material, skeletal output, asset database, and metadata are published as a rollback-backed transaction. An invalid conversion or persistence failure keeps the previous generated set instead of mixing old and new artifacts.

Current Scope

  • Static triangle meshes only.
  • OBJ and static FBX sources supported by the normal model importer.
  • Existing positions, normals, UVs, and material regions are considered.
  • Sources with multiple material slots must keep Single Material enabled; material regions are protected during reduction, then collapsed to the one material currently published by the model importer.
  • Skinned FBX optimization is blocked because topology reduction would also require deliberate bone-weight and animation remapping.
  • The feature does not create UVs, retopologize arbitrary non-manifold input, optimize collision separately, or prove final draw ordering on hardware.

For animated content, reduce the mesh in the DCC and follow Skeletal Animation. For the runtime budget context, see PS1 Hardware Constraints & Budgets.

Troubleshooting

Target not reached

Read the stop reason. A protected boundary, material seam, UV seam, hard edge, symmetry pair, normal limit, or vertex-displacement limit may make the requested target unsafe. Raise the triangle target first. Disable a constraint only when you have inspected the relevant preview.

Symmetry cannot be preserved

Use Auto to let an asymmetric source proceed without symmetry, or correct the model's mirrored topology in the DCC. Explicit X/Y/Z modes intentionally reject an unreliable pair mapping.

Source is non-manifold or invalid

Remove degenerate faces, duplicate faces, non-manifold edges, invalid indices, and non-finite vertex data in the DCC, then reimport. The optimizer does not silently patch ambiguous topology.

The output is valid but looks wrong on PS1

Check long triangles, material count, texture filtering and palettes, UV islands, coplanar overlap, near-plane crossings, and ordering-table behavior. Use the PS1 Budget dashboard, a packaged DuckStation build, and representative real hardware before shipping.

Production Checklist

  • preserve the original source under Assets/Models/;
  • begin with the recommended target and review the stop reason;
  • inspect wireframe, silhouette, UV density, and PS1-quantized previews;
  • compare source/output counts and confirm material assignment;
  • re-check collision if it was authored from visual geometry;
  • review the full scene in the PS1 Budget dashboard;
  • validate packaged output in DuckStation and on intended hardware.