Distance visibility: near and far models
Switch representations by distance while understanding LOD limits: processing, physics and resources remain active.
When to use it
VisibilityRangeBegin and VisibilityRangeEnd can show detailed geometry nearby and simpler geometry farther away. The sample uses a white sphere and blue cube so the transition is unmistakable. It selects different prepared meshes; it does not automatically reduce triangles in one mesh.
Run the transition
Take all three files from the camera example, run dotnet build and attach ViewLab3D.cs to the Entity3D root of a .rscene level. Use SDK 1.0.0 and net10.0. Leave UseWall=false before startup, otherwise the wall shortens camera distance and the far model may never appear.
| Object | Begin | End | Result |
|---|---|---|---|
| NearModel: white sphere | 0 | 12 | Visible nearby; zero disables the lower bound |
| FarModel: blue cube | 12 | 0 | Visible farther away; zero disables the upper bound |
Press down to move outward and up to move inward. Distance 6 shows the sphere; distance 18 shows the cube. Distance is measured to the transformed geometry AABB center, not necessarily the entity origin. Both sample meshes are symmetric and share a position, making comparison predictable.
Both frames come from the current local engine, Compatibility/OpenGL, viewport 512×384. They demonstrate selection, not FPS or world-scale performance.
Configure the boundary
The sample disables transparent fading and uses zero margins. At the exact shared threshold of 12, both geometry checks can pass: do not assume exactly one mesh is always visible. Different AABB centers also move effective boundaries. Inspect the transition during real camera movement; overlapping identical surfaces can cause z-fighting.
With fading disabled, VisibilityRangeBeginMargin and VisibilityRangeEndMargin supply hysteresis: switching depends on the previous state to avoid rapid toggling around a threshold. They do not enable transparency on their own. Coordinate neighboring ranges and inspect for gaps and visible jumps.
Source configuration requires Forward+ for transparent Self/Dependencies modes. This example does not verify them or promise them in Compatibility or Mobile. Test smooth transitions, lighting and shadows separately in the target renderer.
What keeps running
The range-culled NearModel continued _Process in the test, while Visible and IsVisibleInTree remained true. The complete tested class is:
LodVisual3D.cs
using Reckfell;
public partial class LodVisual3D : MeshInstance3D
{
public int ProcessTicks { get; private set; }
public override void _Process(double delta) => ProcessTicks++;
}Geometry ranges do not disable the separate StaticBody3D: a physics ray still hit the target body while the far model was shown. They do not delete entities, release mesh resources or unload a level.
| Requirement | Additional solution |
|---|---|
| Reduce distant rendering cost | Simpler far mesh, suitable materials and ranges |
| Stop expensive gameplay logic | Explicit processing policy consistent with gameplay |
| Reduce physics cost | Separate body activation and physics-detail policy |
| Unload world sections | Chunk loading, resource ownership and state persistence |
| Automatically simplify one mesh | Separate mesh LOD mechanism and supported import |
Do not stop simulation merely because an object is unseen: gameplay may require continued movement, timers or network state.
Diagnosis
- Both models always appear: check ranges on the actual GeometryInstance3D and distance from the active camera.
- Far mesh never appears: check actual camera position, arm constraints and AABB centers.
- Object disappears between ranges: ranges leave a gap or model centers differ.
- FPS barely changes: scripts, physics, materials or draw calls may dominate instead of triangles. Profile the target level.
Checks cover hard switching, actual rendered pixels and continued processing/physics. Streaming, transparent fading and performance gains are not verified.