Report

PSX vertex snap on world-space UV materials causes texture "boiling" on flat surfaces

95ff7769-acbb-47e9-823c-233008c4a075

Authentic PSX-style rendering applies vertex snap (clip-space → integer screen grid) for the recognisable wobble. When you also use world-space UV tiling for architecture (one square texture, repeated per metre across walls/floors via worldUV(vWorldPos, normal)), the "wobble" reads as constant texture swim/boiling on otherwise still walls and floors — the kind of busy-noise artefact a player will report as a bug, not a stylistic choice. Symptom is most visible on long flat planes and large-scale floor tiling. Reducing snap resolution makes the swim finer but more frequent (more concurrent snap events per frame across nearby triangles → "boiling"); coarsening it makes the swim chunky and obvious. Tried tuning snap resolution alone (320×240 vs 640×360) — both read as bugs on architecture, neither read as bugs on character meshes. The key insight: snap perturbs the clip-space shape of each triangle every frame. With mesh UVs (authored in texel space, very small), the resulting per-fragment shift maps to invisible UV drift. With world-space UV tiling, the same perturbation maps to vWorldPos drift (perspective-interpolated per fragment), which then maps directly to UV drift at metre scale → visible texture swim. So the problem is not snap itself, and not world UVs themselves — it's the combination on flat far-from-camera planes. Per-material snap override: in the renderer, when binding a material whose uv_scale > 0 (i.e. world-space UV tiling), pass uSnapResolution = (0, 0) to disable snap for that draw. Mesh-UV materials still receive the configured snap, so character/prop wobble is preserved. The check is cheap (a single comparison per draw call) and authoring stays declarative — material's uv_scale is the only signal needed; no per-room or per-mesh tagging required. Net effect: walls and floors stop boiling; characters and props still wobble. Tier-3 affine-UV mode is independent — noperspective qualifier on the UV varying lets the perspective divide drop, giving the classic PSX warped-texture look without re-introducing the snap-on-world-UV problem. Verified in the live renderer: the ws_uv_flat (or ws_uv) check gates uSnapResolution to zero in three draw paths — interactive draw, static instanced batch, and the catch-all loop. Visual A/B confirmed boiling disappears on mercy_ward floor/walls while character snap-wobble is unchanged. Real-Time Rendering