import type { RenderBounds } from "./bounds.js"; import type { CameraView } from "./frustum.js"; export interface OcclusionInput { readonly camera: CameraView; readonly bounds: RenderBounds; /** Candidate blockers already known to be in front of the object (nearer to the camera). */ readonly occluders: Iterable; } /** * Optional occlusion stage. Kept behind a feature flag and disabled by default: a fragile * occlusion test that wrongly hides a visible object is worse than no occlusion at all. * Any tester here MUST be conservative — it may return false (visible) for a truly hidden * object, but must never return true (hidden) for an object the player can actually see. */ export interface OcclusionTester { readonly enabled: boolean; isOccluded(input: OcclusionInput): boolean; } /** The safe default: never occludes anything. */ export declare const noOcclusion: OcclusionTester; export interface AxisOccluderOptions { enabled?: boolean; /** An occluder is only trusted when its bounding sphere is at least this large (world units). Default 8. */ minOccluderRadius?: number; } /** * A deliberately conservative bounding-volume occlusion tester. It hides an object only when a * single large occluder's AABB fully contains the object's AABB on every axis AND sits strictly * nearer the camera on the dominant view axis — the object is then provably in the occluder's * shadow. Full containment (not just the two perpendicular axes) makes it stricter than it needs * to be, which is the safe direction: it never hides a partially-visible object. * * This is the architecture/interface for occlusion, not a production hierarchical-Z implementation. * It stays disabled by default; enable only where the scene has genuine large blockers. */ export declare function createAxisAlignedOcclusionTester(options?: AxisOccluderOptions): OcclusionTester;