fix(dashboard): white pines, see-through hills and fighting surfaces in the 3D views

- Shader 94 ("Basic") draws with vertex colors: its class's technique setup
  names Technique_Basic_Lighting_VertColor, as 38 "Basic VC" does. The views
  treated it as having none, so Nimbus Station's glom pines (tag S84) came
  out as their grey texture, white. The other shader looks in use were
  checked the same way (33, 35, 37, 70, 82, 84, 105 hold).
- Two layer shaders: NiTexturingProperty's dark texture and the UV set each
  texture's flags name are read, and the views draw "Two Layers Blended" as
  the dark texture under the base one by the vertex alpha (no longer as
  opacity) and "Two Textures Added" as in TwoLayersAdded_PS. Avant Gardens'
  snowy grass mounds were see-through hills. The client ships no technique
  for the blended ones, so that blend follows the meshes' data.
- The near plane follows how far out the camera is (distance / 400, 0.5 to
  20) instead of a fixed 0.5 over a far plane in the thousands, so ground
  overlays, floor rings and road pieces stop fighting in far views.
- Conversion format 3 (new model data), so kept conversions are made again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-28 09:07:35 -05:00
parent 966a12f4af
commit 7c6c4bc232
9 changed files with 272 additions and 77 deletions

View File

@@ -19,6 +19,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
import { buildTerrainChunks, TERRAIN_LOOKS } from '/js/lddviewer.js';
import { createScenery } from '/js/scenery.js';
import { nearPlaneFor } from '/js/scenery-core.js';
import { Track, replayPosition, trailSegments, heatFrames, heatLevel, heatColor, formatSpan, coreBounds, isPlaceholderTerrain } from '/js/world3d-core.js';
const LIVE_DELAY = 1.2; // seconds live players are drawn behind the newest report
@@ -76,6 +77,14 @@ const scenery = createScenery({
onScenes: renderScenes
});
// The near plane follows how far out the camera is, so far views keep their depth precision (no fighting surfaces)
function fitNearPlane(cam, target) {
const near = nearPlaneFor(cam.position.distanceTo(target));
if (Math.abs(near - cam.near) / cam.near < 0.15) return;
cam.near = near;
cam.updateProjectionMatrix();
}
// ---- scenes: which of the zone's scenes the scenery shows (scenery.js setSceneMode) ----
function renderScenes(info) {
@@ -1112,6 +1121,7 @@ function animate() {
}
}
controls.update();
fitNearPlane(camera, controls.target);
scenery.update(dt);
flairs.update(dt);
renderer.render(scene, camera);