fix(render): re-land near plane 0.1m (retail Render::znear) — #110 resolved, closes the §4 corner see-through; close #105/#110
The137b4f2payload, re-landed now that #110 is resolved: the missing-indoor- textures correlation was the pre-existing #105 staged-texture-flush drop (fixed inc787201), not a near-plane mechanism. znear=0.1 merely raised #105's trigger probability — a closer near plane makes close-up geometry newly visible, inflating per-frame prepare/upload pressure indoors and growing the never-flushed tail. Exactly the handoff's only-credible-link hypothesis, verified instead of assumed. Retail: Render::SetFOVRad sets znear=0.1 flat (decomp :342173, initializer :1101867). 0.1 < the 0.3m camera-collision sphere, so a wall the collided eye presses against no longer falls inside the near plane — the §4 corner see-through-wall closes. Verification on the 0.1 arm (the arm that struck 2-of-3 on 2026-06-10): nearplane-reland-1.log — [tex-flush] after=0 on all 45 lines, 68,291 [shell] lines with zero zh>0 batches, all four dat tripwires silent, no [wb-error]. ISSUES.md: #105 + #110 moved to Recently closed with root cause + evidence. Pending user re-gate: corner press (wall stays solid) + distance scan for z-shimmer (none expected; retail ships 0.1 with D24). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
c78720127a
commit
d4b5c71e66
5 changed files with 66 additions and 82 deletions
116
docs/ISSUES.md
116
docs/ISSUES.md
|
|
@ -44,48 +44,6 @@ Copy this block when adding a new issue:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #105 — Intermittent silent dat-load failure: white/missing cottage walls until relaunch
|
|
||||||
|
|
||||||
**Status:** OPEN
|
|
||||||
**Severity:** HIGH
|
|
||||||
**Filed:** 2026-06-09
|
|
||||||
**Component:** render, dat, streaming
|
|
||||||
|
|
||||||
**Description:** Intermittently (twice user-confirmed: once under heavy probe logging
|
|
||||||
2026-06-08, once on a completely clean launch 2026-06-09), the Holtburg cottage wall surfaces
|
|
||||||
render as background/clear color while the cells' static objects (paintings, furniture,
|
|
||||||
windows) draw normally. Once broken, broken for the whole session — the failed result is
|
|
||||||
cached (mesh batches build once, hydration runs once). The failure has never produced a single
|
|
||||||
log line: every dat-read failure on the walls-relevant paths exits silently.
|
|
||||||
|
|
||||||
**Root cause / status:** LARGELY SUPERSEDED BY #106 (2026-06-09 evening): the live capture
|
|
||||||
pinned "whole interior missing / enter house and see outside" to the cross-landblock outdoor
|
|
||||||
membership freeze — most "broken house" reports were that. What REMAINS under #105 is the
|
|
||||||
narrower residual observed twice earlier: a single wall section missing (sky/clear color)
|
|
||||||
**while membership and viewer cell were demonstrably correct and INDOOR** (`viewerCell=0171`,
|
|
||||||
props drawn, collision present). All data/upload/registration layers are exonerated for it:
|
|
||||||
four rounds of tripwires (`[dat-miss]`/`[tex-miss]`/`[tex-skip]`/`[cell-miss]`,
|
|
||||||
`[geom-null]`/`[geom-misroute]`/`[up-null]`, `[finalize-replace]`/`[late-register]`) were
|
|
||||||
silent across every reproduction, the dat library is exonerated (`DatConcurrencyStressTests`,
|
|
||||||
~1.1M concurrent reads), and the capture analysis shows no never-flooding building and no
|
|
||||||
empty indoor floods. The teardown dispose-during-read AccessViolation was fixed nearby
|
|
||||||
(`8fadf77`). Known-benign noise: `[up-null]` for `0x010002B4`/`0x010008A8` (deterministic,
|
|
||||||
legitimately empty meshes). If the residual reproduces, the remaining suspects are the
|
|
||||||
draw-level clip path (the §4 edge-on clip family) — note `BuildFromExterior` has NO pv-trace
|
|
||||||
hook yet (add one for attribution). Keep all tripwires until this closes.
|
|
||||||
|
|
||||||
**Files:** `src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs` (texture chains),
|
|
||||||
`src/AcDream.App/Rendering/Wb/DatCollectionAdapter.cs` (`DatDatabaseWrapper.TryGet`),
|
|
||||||
`src/AcDream.App/Rendering/TextureCache.cs` (`DecodeFromDats`),
|
|
||||||
`src/AcDream.App/Rendering/GameWindow.cs` (`BuildInteriorEntitiesForStreaming` hydration).
|
|
||||||
|
|
||||||
**Research:** `docs/research/2026-06-09-dat-reader-thread-safety-investigation.md`.
|
|
||||||
|
|
||||||
**Acceptance:** the next white-wall occurrence is attributed by a tripwire line (or by their
|
|
||||||
collective silence, pointing GL-side); the attributed root cause is fixed; walls survive 10+
|
|
||||||
launches including heavy-load ones. Tripwires can then be stripped (or kept as permanent
|
|
||||||
anomaly logging — decide at close).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #104 — Scene VFX particles not clipped to the PView visible cell set
|
## #104 — Scene VFX particles not clipped to the PView visible cell set
|
||||||
|
|
@ -3768,35 +3726,59 @@ stable now; this is a draw-order/depth oscillation localized to the door surface
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## #110 — Near plane 0.1 m (retail znear) correlates with missing indoor textures; corner see-through blocked on it
|
|
||||||
|
|
||||||
**Status:** OPEN
|
|
||||||
**Severity:** HIGH (blocks the §4 corner see-through fix)
|
|
||||||
**Component:** render / camera projection (+ possibly texture upload / #105 interaction)
|
|
||||||
|
|
||||||
Retail runs `Render::znear = 0.1` (decomp :342173, initializer :1101867); ours is 1.0 m.
|
|
||||||
Because the camera-collision sphere holds the eye 0.3 m from walls, the 1.0 m near plane
|
|
||||||
clips away any wall the camera presses against — the §4 "camera clipping into the wall"
|
|
||||||
corner background (user-gated 2026-06-10, unchanged by the flood fix `dac8f6a`).
|
|
||||||
|
|
||||||
Landing 0.1 (`137b4f2`) fixed the geometry relationship but correlated with MISSING INDOOR
|
|
||||||
TEXTURES on two consecutive runs; the 1.0 bisect run immediately rendered clean, and the
|
|
||||||
change was reverted same-day. The #105 dat-miss tripwires were SILENT on the bad runs
|
|
||||||
(GL-side per the #105 protocol). No mechanism is known by which the near plane affects
|
|
||||||
texturing — candidates: (a) coincidence with the intermittent #105 (2/2-then-1/1 is a small
|
|
||||||
sample), (b) a depth-precision interaction (near 0.1 + far 5000 = 50k ratio) breaking a
|
|
||||||
depth-dependent pass indoors, (c) something in the visible-set/prepare path scaling with
|
|
||||||
the wider near frustum. Investigation: re-land 0.1 locally, reproduce, RenderDoc the
|
|
||||||
missing-texture frame; or flip-test 0.1↔1.0 over N runs to settle (a) statistically.
|
|
||||||
User question pending: did the missing textures render WHITE (upload path) or INVISIBLE
|
|
||||||
(visibility/depth)?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Recently closed
|
# Recently closed
|
||||||
|
|
||||||
|
## #105 — Intermittent white/missing indoor wall textures — [DONE 2026-06-10 · c787201]
|
||||||
|
|
||||||
|
**Status:** DONE (probe-verified both directions; visual gate pending user)
|
||||||
|
**Closed:** 2026-06-10
|
||||||
|
**Commit:** `c787201` (fix + the `ACDREAM_PROBE_TEXFLUSH` apparatus)
|
||||||
|
**Component:** render (GL texture upload)
|
||||||
|
|
||||||
|
**Root cause:** `TextureAtlasManager.AddTexture` only STAGES texture content (PBO write +
|
||||||
|
`ManagedGLTextureArray._pendingUpdates`); the actual `TexSubImage3D` copies + mipmap
|
||||||
|
regeneration happen in `ProcessDirtyUpdates`, which WB drives once per frame via
|
||||||
|
`ObjectMeshManager.GenerateMipmaps()` from its render loop (WB `GameScene.cs:975`).
|
||||||
|
GameScene is the file the N.4/O-T4 extraction replaced with `GameWindow`, so the per-frame
|
||||||
|
driver was silently dropped. Staged updates only reached the GPU as a side effect of PBO
|
||||||
|
growth; every layer staged after an array's LAST growth kept undefined `TexStorage3D`
|
||||||
|
content behind a valid resident bindless handle — white/garbage walls, `zh==0`, all dat
|
||||||
|
tripwires silent (the dat→decode→stage side had delivered correctly). Only
|
||||||
|
`ObjectRenderBatch.BindlessTextureHandle` consumers were affected (EnvCellRenderer cell
|
||||||
|
shells = indoor walls); entities resolve via `TextureCache` (immediate) and terrain via
|
||||||
|
`TerrainAtlas` (immediate) — which is why only indoor walls ever struck. Intermittency =
|
||||||
|
background decode-completion order shuffling which textures land in the never-flushed tail.
|
||||||
|
|
||||||
|
**Fix:** `WbMeshAdapter.Tick()` now calls `GenerateMipmaps()` after the staged-upload
|
||||||
|
drain (Tick runs before all draw passes — the WB-equivalent position).
|
||||||
|
|
||||||
|
**Evidence:** pre-fix `texflush-prefix.log`: pending updates climb 0→48→…→142 and park at
|
||||||
|
126 across 34/34 atlas arrays forever at standstill. Post-fix `texflush-postfix.log` +
|
||||||
|
`nearplane-reland-1.log`: `after=0` on every line. The earlier exonerations (dat reads
|
||||||
|
safe, membership healthy, "not the probes") all stand — this was the predicted
|
||||||
|
"between staging and the draw" GL-side loss.
|
||||||
|
|
||||||
|
**Tripwires:** the four dat-side tripwires stay (permanent anomaly logging);
|
||||||
|
`ACDREAM_PROBE_TEXFLUSH` stays env-gated (zero cost off).
|
||||||
|
|
||||||
|
## #110 — Near plane 0.1 m vs missing indoor textures — [DONE 2026-06-10 · c787201 + re-land]
|
||||||
|
|
||||||
|
**Status:** DONE (mechanism resolved; near plane exonerated and re-landed)
|
||||||
|
**Closed:** 2026-06-10
|
||||||
|
**Component:** render / camera projection
|
||||||
|
|
||||||
|
**Resolution:** the missing-texture correlation was the pre-existing #105
|
||||||
|
(staged-texture-flush drop, see above), NOT a near-plane mechanism. `znear=0.1` merely
|
||||||
|
raised #105's trigger probability exactly as the handoff's only-credible-link predicted:
|
||||||
|
a closer near plane makes close-up geometry newly visible → more prepare/upload pressure
|
||||||
|
indoors → a larger never-flushed tail. With #105 fixed, retail `Render::znear = 0.1`
|
||||||
|
(decomp :342173, initializer :1101867) is re-landed on all four cameras — closing the §4
|
||||||
|
corner see-through (the 0.3 m-collided eye no longer near-clips the pressed wall).
|
||||||
|
User re-gate: corner press (wall stays solid) + distance scan for z-shimmer (none
|
||||||
|
expected; retail ships 0.1 with D24).
|
||||||
|
|
||||||
## #106 — Outdoor membership freezes at landblock boundaries — [DONE 2026-06-09 · 7078264 + 23adc9c + 6dbbf95 + e6913ac]
|
## #106 — Outdoor membership freezes at landblock boundaries — [DONE 2026-06-09 · 7078264 + 23adc9c + 6dbbf95 + e6913ac]
|
||||||
|
|
||||||
**Status:** DONE (user-verified: collision + solid walls everywhere; probe-verified crossings)
|
**Status:** DONE (user-verified: collision + solid walls everywhere; probe-verified crossings)
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,9 @@ public sealed class ChaseCamera : ICamera
|
||||||
public Matrix4x4 View =>
|
public Matrix4x4 View =>
|
||||||
Matrix4x4.CreateLookAt(Position, _lookAt, Vector3.UnitZ);
|
Matrix4x4.CreateLookAt(Position, _lookAt, Vector3.UnitZ);
|
||||||
|
|
||||||
// Near plane: retail is 0.1 m, parked pending #110 (see RetailChaseCamera.Projection).
|
// Near plane 0.1 m = retail Render::znear (see RetailChaseCamera.Projection).
|
||||||
public Matrix4x4 Projection =>
|
public Matrix4x4 Projection =>
|
||||||
Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 1f, 5000f);
|
Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 0.1f, 5000f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update the camera position to follow the player. <paramref name="isOnGround"/>
|
/// Update the camera position to follow the player. <paramref name="isOnGround"/>
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,9 @@ public sealed class FlyCamera : ICamera
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Near plane: retail is 0.1 m, parked pending #110 (see RetailChaseCamera.Projection).
|
// Near plane 0.1 m = retail Render::znear (see RetailChaseCamera.Projection).
|
||||||
public Matrix4x4 Projection
|
public Matrix4x4 Projection
|
||||||
=> Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 1f, 5000f);
|
=> Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 0.1f, 5000f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integrate position for one frame based on WASD + vertical keys.
|
/// Integrate position for one frame based on WASD + vertical keys.
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public sealed class OrbitCamera : ICamera
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Near plane: retail is 0.1 m, parked pending #110 (see RetailChaseCamera.Projection).
|
// Near plane 0.1 m = retail Render::znear (see RetailChaseCamera.Projection).
|
||||||
public Matrix4x4 Projection
|
public Matrix4x4 Projection
|
||||||
=> Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 1f, 5000f);
|
=> Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 0.1f, 5000f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,16 +38,18 @@ public sealed class RetailChaseCamera : ICamera
|
||||||
public float Aspect { get; set; } = 16f / 9f;
|
public float Aspect { get; set; } = 16f / 9f;
|
||||||
public float FovY { get; set; } = MathF.PI / 3f;
|
public float FovY { get; set; } = MathF.PI / 3f;
|
||||||
public Matrix4x4 View { get; private set; } = Matrix4x4.Identity;
|
public Matrix4x4 View { get; private set; } = Matrix4x4.Identity;
|
||||||
// ⚠️ Near plane SHOULD be retail Render::znear = 0.1 m (decomp :342173/:1101867), and
|
// Near plane = retail Render::znear = 0.1 m (decomp :342130/:342173/:1101867 —
|
||||||
// must eventually be smaller than the 0.3 m camera-collision sphere — at 1.0 m a wall
|
// Render::SetFOVRad sets 0.1 flat; the legacy set_vdst variant is max(0.1, vdst·0.25)).
|
||||||
// the collided eye sits 0.3 m from falls INSIDE the near plane and is clipped away
|
// MUST be smaller than the 0.3 m camera-collision sphere (PhysicsCameraCollisionProbe.
|
||||||
// (the §4 corner see-through, user-gated 2026-06-10). The 0.1 change was landed
|
// ViewerSphereRadius): with a 1.0 m near, a wall the collided eye sits 0.3 m from
|
||||||
// (137b4f2) and REVERTED the same day: two consecutive runs lost indoor textures on
|
// falls INSIDE the near plane and is clipped away — pressing the camera into a corner
|
||||||
// 0.1 and recovered on the 1.0 bisect run. Mechanism not yet understood (a near-plane
|
// let you see straight through the wall (§4 corner residual). History: 0.1 landed
|
||||||
// change shouldn't touch texturing; the intermittent #105 may have coincided). Issue
|
// (137b4f2), was reverted (8bd3492) after correlating with missing indoor textures,
|
||||||
// #110 tracks the investigation — do not re-land 0.1 without it.
|
// and re-landed once #110 resolved: the textures were the pre-existing #105
|
||||||
|
// staged-texture-flush drop (WbMeshAdapter.Tick), and 0.1 merely raised its trigger
|
||||||
|
// probability by making more close-up geometry visible (more uploads in flight).
|
||||||
public Matrix4x4 Projection =>
|
public Matrix4x4 Projection =>
|
||||||
Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 1f, 5000f);
|
Matrix4x4.CreatePerspectiveFieldOfView(FovY, Aspect, 0.1f, 5000f);
|
||||||
|
|
||||||
// ── Public tunables (per-instance) ──────────────────────────────
|
// ── Public tunables (per-instance) ──────────────────────────────
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue