fix(terrain): terrain invisible at high altitude and chunk loading holes - #113
Merged
Conversation
The occlusion search inherited Sodium's cylindrical render distance: besides the horizontal X/Z circle, sections were rejected when their vertical distance to the camera exceeded maxDistance (~ renderDistance * 16), both at section level (OcclusionCuller.isWithinRenderDistance) and region level (RegionCullCache.compute). Flying higher than that threshold above the ground culled the terrain directly underneath: render lists emptied and initial builds stopped being collected until the player descended again. Vanilla 1.12.2 has no vertical render-distance cull, and world height can be extended by mods such as Depths Update, so the vertical term is removed entirely; the legacy object-node API (HBM-CE mixin injection target) keeps its original semantics as it is not used by the render path.
…ed builds The section manager archived frame numbers from two independent counters: the vanilla frame counter on the terrain pass and ShadowRenderer's own counter, which restarts from zero on every shader-pipeline rebuild. Frames where the terrain setup ran but the shadow pass did not (pipeline rebuild windows, nested portal rendering) mixed both counters into one comparison space: - lattice visit stamps written by the larger counter made later searches with the smaller counter treat cells as already visited, so sections never re-entered render lists or rebuild queues; - filterChunkBuildResults misclassified fresh results as stale, and the dropped results never reached the token release in processChunkBuildResults, pinning the section's buildInFlight bit so the graph search skipped it permanently. Both entry points now normalize the external frame through SectionFrameClock, a strictly increasing sequence, and the stale-result discard path releases the build cancellation token (with a WARN carrying the section coordinates and frame numbers) instead of leaking it.
The tracker's only event sources are the loadChunk/unloadChunk hooks, so any chunk transition that bypasses them (chunk data written to a chunk the tracker never saw load, mods mutating the loaded-chunk map directly) leaves the tracker permanently out of sync: the affected chunks never satisfy the 3x3 neighbor-readiness gate, are never published to the renderer, and produce holes that approaching does not heal until the world is re-entered. ChunkTracker.reconcile diffs the tracked set against the world's authoritative loaded set and replays the difference through the regular event methods, and the client-chunk-manager mixin invokes it once per client tick; in steady state the diff is empty and no events fire.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
改了什么
三个独立提交,修复两类区块渲染/加载缺陷:
OcclusionCuller.isWithinRenderDistance与 region 级RegionCullCache.compute),只保留水平圆形距离判定,与 vanilla 1.12.2 行为对齐。RenderSectionManager两个入口(update/updateForShadowPass)的外部帧号统一经新增的SectionFrameClock归一化为严格递增序列;filterChunkBuildResults丢弃「过期」结果时补放buildCancellationToken并输出 WARN 日志。ChunkTracker.reconcile()每 client tick 与ChunkProviderClient.loadedChunks对账,经原有事件通道重放差异(稳态下 diff 为空、零事件)。为什么改
renderDistance × 16格后正下方地形被整片裁掉,渲染列表清空且 INITIAL_BUILD 停止收集。vanilla 1.12.2 无垂直视距裁剪;且 Depths Update 等模组可扩展世界高度(本仓库已有DepthsUpdateCompat),任何固定垂直截断在扩展高度世界同样错误。frameCountvs 阴影 pass 自建且管线重建即归零的celeritasShadowFrame)导致 lattice 访问戳毒化(搜索永久跳过 cell)与构建结果误丢后 token 泄漏(buildInFlight卡死、section 永不再被收集)。另对ChunkTracker与世界加载集可能脱节(非 full-chunk 包、模组绕过loadChunk直写)增加了对账自愈。如何验证
./gradlew check --no-daemon与./gradlew build --no-daemon全绿(含 remap jar 结构校验、compatBridge 契约测试、模块边界校验)。OcclusionCullerRenderDistanceTest(高空/负高度/水平超界)、SectionFrameClockTest(单调性/回退/饱和)、ChunkTrackerReconcileTest(补缺失/清多余/幂等/孤立不就绪)。兼容性
OcclusionCullerlegacy object-node API 与RenderSectionManager.update()的 CameraTransform getfield 内联均原样保留,HbmCameraRedirectContractTest通过。CeleritasCompatBridgeJarTest通过。相关 issue