Skip to content

Dynamic far rework#2699

Open
airnez wants to merge 3 commits intoiTowns:masterfrom
airnez:fix/dynamic-near-far-rework
Open

Dynamic far rework#2699
airnez wants to merge 3 commits intoiTowns:masterfrom
airnez:fix/dynamic-near-far-rework

Conversation

@airnez
Copy link
Contributor

@airnez airnez commented Feb 13, 2026

Description

I am trying to asses issues pointed out by @gchoqueux about horizon clipping with the dynamic near / far option enabled.
For now, this work only targets GlobeView and GlobeLayer, because the way it is computed does not make sense in planarView.
It would be nice to have a uniform 'dynamic far' api for both of them in the end. That's why this PR is marked as draft.

Fixes #2619

New far computation

I implemented a new far computation method that applies a varying factor to horizon distance instead of aplying a linear coefficient to camera sea level altitude. This looks more natural near the ground.
It has 3 parameters :

  • farFactor - Value between 0 and 1. Lower values reduce far distance near the ground. It is the lowest factor applied to the real horizon distance, at sea level. For instance, a factor of 0.3 will induce a far distance corresponding to 30% of real horizon distance when camera is at sea level (if minimum distance mentionned bellow allows it)
  • maxFarAltitude - the altitude at which the horizon is fully visible (meters).
  • minFarDistance - the minimum horizon distance (meters). This is prevents shrinking too much the horizon bellow a decent value, 5km here.

This method is not mathematicaly perfect, as it is scaling horizon distance in spherical unit earth referencial, then re-multiplying it by max globe radius. It won't exactly match culled horizon distance. But this seemed sufficient to me, horizon culling being quite conservative.
I added some sliders to default example gui to play with those parameters: please pull this branch and try by yourself :)

549534485-4422008f-bdd6-4823-b82c-27a0703fe3b9 image

Culling tiles at the reduced horizon distance

The dynamic far distance was not related to horizon culling in Globe layer. This meant that textures would still be downloaded while the related tile was not rendered. I implemented this horizon scaling behavior by scaling-down the camera position to get expected horizon distance. I could not just cull tiles based on a cutoff distance because horizon culling is actually applied to a single pre-computed point depending on tile curvature and elevation. It behaves like a "mountain" that should not be culled when crossing horizon.
I used cesium reference to find how to compute the target camera squared length that would scale-down the horizon by a provided factor : https://cesium.com/blog/2013/04/25/horizon-culling/

$\alpha$ being the horizon scaling fac, we are looking for the target scaled camera position

$$ V' \mid \lVert\vec{V'H}\lVert = \alpha \lVert\vec{VH}\lVert $$ knowing that $$ \lVert\vec{VH}\lVert^2 = \lVert\vec{VC}\lVert^2 -1 $$ this leads to $$ \lVert\vec{V'C}\lVert^2 = \alpha^2(\lVert\vec{VC}\lVert^2 - 1) + 1 $$ we have then the camera scaling ratio $$ \lambda = \sqrt{\dfrac{\lVert\vec{V'C}\lVert^2}{\lVert\vec{VC}\lVert^2}} = \sqrt{\dfrac{\alpha^2(\lVert\vec{VC}\lVert^2 - 1) + 1}{\lVert\vec{VC}\lVert^2}} $$

549541541-2aef29ea-8d03-4656-a24f-3058678b2159

Setting far at a fixed distance in two conditions

I am setting far distance as the furthest point on the globe (on the other side) in two situations :

  • When camera altitude is above maxFarAltitude. This removes the fog while keeping a close-enough distance to benefit from depth-buffer resolution.
  • When RealisticLighting is enabled. For now, at the far plane, it seems that three-geospatial is having issues identifying what is background. The geometries very close to the far plane are not processed the same by aerial perspective and this create a visual artifact. Aerial perspective is already strong enough to hide tile culling. This still imply to render more tiles. This can be removed when fixing this artifact issue.
image

@gchoqueux
Copy link
Contributor

And just multiply vhMagnitudeSquared by factor could work ?

@airnez
Copy link
Contributor Author

airnez commented Feb 23, 2026

And just multiply vhMagnitudeSquared by factor could work ?

@gchoqueux I agree that simpler computation is better. We are also using camera position for the dot product, simply multiplying the vhMagnitudeSquared (or magnitudeSquared in code) by a factor does not work I think.

We need to synchronize the far plane with the horizon culling distance. To make this simpler and remove this ugly square root, my intuition tells me that there is maybe something possible by scaling-up scaledHorizonCullingPoint or vtMagnitudeSquared but it's not obvious to me.

@gchoqueux
Copy link
Contributor

Sorry, I meant: apply a factor to magnitudeSquared
I tested, It seems to work

@jailln jailln requested a review from mgermerie March 9, 2026 16:58
@jailln jailln marked this pull request as ready for review March 9, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clipping horizon

2 participants