feat(render): Phase W Stage 4 — sky/weather portal-clip seal (LScape through the doorway)
The sky + weather (rain cylinder) are retail's LScape — 'the outside seen through the exit portal.' Retail PView::DrawCells (pseudo_c:432709) draws LScape clipped to the OutsideView when outside_view.view_count>0, then does a conditional Z-buffer-ONLY clear (432731) before the indoor cells. acdream now does the same: - sky.vert writes gl_ClipDistance against the SAME binding=2 TerrainClip UBO the terrain reads. The OutsideView planes are screen-space (NDC) half-spaces encoded as clip-space planes (nx,ny,0,dw); the test dot(plane,gl_Position)>=0 reduces after perspective divide to nx*ndcX+ny*ndcY+dw>=0 — projection-INDEPENDENT — so the same plane set clips the sky EXACTLY despite its separate dome projection. count==0 (outdoor) → all distances +1 → full-screen, bit-identical. Lighting/fog math untouched. - GameWindow: relocated the sky pre-scene + weather post-scene draws to their retail LScape positions, each in a local 8-plane clip bracket so sky.vert confines them to the doorway indoors / full-screen outdoors. Added the conditional doorway depth-ONLY Z-clear (no color → no blue hole), scissored to the OutsideView AABB. drawSkyThisFrame = seen_outside policy AND (outdoor OR exit-portal-in-view) — a sealed interior with no exit portal in view draws no sky (kills the full-screen-sky interim regression). Sky pre/post particle passes (particle.vert has no gl_ClipDistance) scissored to the doorway bbox. - ClipFrameAssembly gains HasOutsideView + OutsideViewNdcAabb (the doorway NDC AABB, computed for BOTH Planes and Scissor terrain modes — unlike TerrainScissorNdcAabb which is Scissor-only). - The pre-login goto SkipWorldGeometry moved BELOW the sky draw so the live sky still renders during the EnterWorld handshake (clipAssembly is null/no-clip pre-login → full-screen). Build green; App tests 160/160. Stage 4 tests + verify-annotations follow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
55e1b30553
commit
ce2edad66a
3 changed files with 194 additions and 30 deletions
|
|
@ -95,6 +95,22 @@ public sealed class ClipFrameAssembly
|
|||
/// <see cref="TerrainMode"/> is <see cref="TerrainClipMode.Scissor"/>. Unused otherwise.</summary>
|
||||
public required Vector4 TerrainScissorNdcAabb { get; init; }
|
||||
|
||||
/// <summary>True ⇒ the OutsideView (the exit-portal screen region) is meaningfully visible this
|
||||
/// frame — the camera can see outdoors through a portal chain (<see cref="TerrainMode"/> is
|
||||
/// <see cref="TerrainClipMode.Planes"/> or <see cref="TerrainClipMode.Scissor"/>). False ⇒ a
|
||||
/// sealed interior with no exit portal in view (<see cref="TerrainClipMode.Skip"/>). Drives the
|
||||
/// Stage 4 sky/weather draw + the conditional doorway Z-clear. Always false on the outdoor root
|
||||
/// (the caller does not invoke <see cref="ClipFrameAssembler.Assemble"/> there).</summary>
|
||||
public required bool HasOutsideView { get; init; }
|
||||
|
||||
/// <summary>NDC AABB (minX,minY,maxX,maxY) of the OutsideView screen region — the doorway
|
||||
/// opening's bounding box. Computed whenever <see cref="HasOutsideView"/> is true, for BOTH the
|
||||
/// Planes and Scissor terrain modes (unlike <see cref="TerrainScissorNdcAabb"/>, which is valid
|
||||
/// only in Scissor mode). Stage 4 scissors the conditional doorway depth-only Z-clear (retail
|
||||
/// PView::DrawCells:432731) and the sky/weather particle passes to this region. Degenerate
|
||||
/// (<see cref="Vector4.Zero"/>) when <see cref="HasOutsideView"/> is false.</summary>
|
||||
public required Vector4 OutsideViewNdcAabb { get; init; }
|
||||
|
||||
// ---- Probe data (ACDREAM_PROBE_VIS / RenderingDiagnostics.EmitVis) --------
|
||||
|
||||
/// <summary>Plane count the OutsideView reduced to (0 ⇒ scissor or empty).</summary>
|
||||
|
|
@ -196,6 +212,17 @@ public static class ClipFrameAssembler
|
|||
scissorFallbacks++;
|
||||
}
|
||||
|
||||
// Stage 4: the doorway screen-space AABB (the OutsideView union bounds), available for
|
||||
// BOTH Planes and Scissor modes — the sky/weather particle scissor + the conditional
|
||||
// doorway Z-clear need it regardless of how the OutsideView reduced to a gate.
|
||||
// TerrainScissorNdcAabb above is only valid in Scissor mode; the OutsideView CellView
|
||||
// always tracks its Min/Max as polygons accumulate, so it is the single source here.
|
||||
bool hasOutsideView = terrainMode != TerrainClipMode.Skip;
|
||||
Vector4 outsideViewNdcAabb = (hasOutsideView && !pvFrame.OutsideView.IsEmpty)
|
||||
? new Vector4(pvFrame.OutsideView.MinX, pvFrame.OutsideView.MinY,
|
||||
pvFrame.OutsideView.MaxX, pvFrame.OutsideView.MaxY)
|
||||
: Vector4.Zero;
|
||||
|
||||
return new ClipFrameAssembly
|
||||
{
|
||||
Frame = frame,
|
||||
|
|
@ -204,6 +231,8 @@ public static class ClipFrameAssembler
|
|||
OutdoorVisible = outdoorVisible,
|
||||
TerrainMode = terrainMode,
|
||||
TerrainScissorNdcAabb = terrainScissor,
|
||||
HasOutsideView = hasOutsideView,
|
||||
OutsideViewNdcAabb = outsideViewNdcAabb,
|
||||
OutsidePlaneCount = ov.Count,
|
||||
PerCellPlaneCounts = perCellPlaneCounts,
|
||||
ScissorFallbacks = scissorFallbacks,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue