mfbonfigli / gocesiumtiler

A Cesium.js point cloud 3D tiles generator from LAS files written in Golang
GNU Lesser General Public License v3.0
185 stars 39 forks source link

Tileset disappears when zooming out due to low geometric error on root tile #18

Closed majos95 closed 2 years ago

majos95 commented 3 years ago

I'm trying to display the Point Cloud when zooming out without having to use maximumScreenSpaceError (=0) feature from Cesium. When using the grid algorithm I notice that the conversion has a very low geometric error on the root. My problem is that if I zoom out a small amount the tileset disappears. I do not want to use maximumScreenSpaceError = 0 otherwise all the tiles load which defeats the purpose of having LODs . I can manually edit the tileset.json but is there a way in which I could convert a .las file and produce a specific geometric error on the root?

mfbonfigli commented 3 years ago

I like the CR and the idea of a custom scale factor for the geometric root error but I'd like to understand a bit better about the use case before merging it.

Do you have an example I could see that reproduces the issue? The geometric error estimation that it's done at the root is basically equal to the maximum possible value, so I don't understand why you say that's very low. Do you think the estimation is wrong or there are use cases where you'd like Cesium to behave differently and tuning the geometricError helps you achieve the desired result?

majos95 commented 3 years ago

Tuning the geometric error helps me achieve the desired result. DEMO

As you can see in the video, as soon as I zoom out not a crazy amount the tileset becomes not visible. The only way without changing the geometric error and display the tileset in any zoom level is setting the maximumScreenSpaceError to zero but that defeats the purpose of having a well built structure. Notice the requests on the right. Without changing the maximumScreenSpaceError it behaves as desired, only loading more points as a higher LOD is requested. With maximumScreenSpaceError it just loads all the points in any LOD and that is something I want to highly avoid.

This is a DEMO of the same tileset but with a higher geometric error only in the root which mantains the loading behavior I enjoy and allows for the tileset to remain visible in lower LOD's.

I have an extra question, you are saying that the geometric error is equal to the maximum possible value. I don't understand how since all the Point Clouds I experimented with (around 10) produce a geometric error of 17.32050807568877 for the root and half of it (8.660254037844386) for the children.

Geometric error calculation: n.cellSize * math.Sqrt(3) * 2

Is it possible that all my Point Clouds have the same cellSize?

mfbonfigli commented 3 years ago

Interesting. I understand the use case, this sounds like a bug in the error computation of the cell size actually. Halving in 2 is expected but those numbers seem quite wrong. Wondering if the code is using the wrong SRID to compute the cell size, will try to check this weekend if possible

Il ven 23 lug 2021, 12:02 majos95 @.***> ha scritto:

Tuning the geometric error helps me achieve the desired result. DEMO https://youtu.be/crOzQYL40HA

As you can see in the video, as soon as I zoom out not a crazy amount the tileset becomes not visible. The only way without changing the geometric error and display the tileset in any zoom level is setting the maximumScreenSpaceError to zero but that defeats the purpose of having a well built structure. Notice the requests on the right. Without changing the maximumScreenSpaceError it behaves as desired, only loading more points as a higher LOD is requested. With maximumScreenSpaceError it just loads all the points in any LOD and that is something I want to highly avoid.

This is a DEMO https://youtu.be/1z2y_odSP6w of the same tileset but with a higher geometric error only in the root which mantains the loading behavior I enjoy and allows for the tileset to remain visible in lower LOD's.

I have an extra question, you are saying that the geometric error is equal to the maximum possible value. I don't understand how since all the Point Clouds I experimented with (around 10) produce a geometric error of 17.32050807568877 for the root and half of it (8.660254037844386) for the children.

return n.cellSize math.Sqrt(3) 2

Is it possible that all my Point Clouds have the same cellSize?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mfbonfigli/gocesiumtiler/issues/18#issuecomment-885562691, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACFVRJ4ELNQEGPJYUBZOWNDTZFD5ZANCNFSM5ANVXM7A .

majos95 commented 3 years ago

Thank you !

mfbonfigli commented 3 years ago

First of all, thanks for the great feedback heren, the videos are really helpful to understand the issue.

Coming back to my previous comment.. well apparently after a few months without coding I had forgotten how the system I wrote (lol) estimates the geometric error and I confirm that the estimation (it's just an approximation) works as intended.

However for the root tileset the calculation should probably be different. The 3D tiles specs state that:

7.1.3 Tileset.geometricError The error, in meters, introduced if this tileset is not rendered. At runtime, the geometric error is used to compute screen space error (SSE), i.e., the error measured in pixels.

So the root tileset should ideally have a geometricError that is roughly equal to the "size" of the point cloud because not rendering the first LOD basically means losing all the information on a scale equal to the size of the point cloud.. A good estimator might thus be the diagonal of the overall point cloud bounding box.

This would mean simply using a logic like the following:

func (n *GridNode) ComputeGeometricError() float64 {
    if n.IsRoot() {
        var w = math.Abs(n.boundingBox.Xmax - n.boundingBox.Xmin)
        var l = math.Abs(n.boundingBox.Ymax - n.boundingBox.Ymin)
        var h = math.Abs(n.boundingBox.Zmax - n.boundingBox.Zmin)
        return math.Sqrt(w * w + l * l + h * h)
    }
    // geometric error is estimated as the maximum possible distance between two points lying in the cell
    return n.cellSize * math.Sqrt(3) * 2
}

I think that is more reasonable, and we need to introduce this but also your scale factor to further tune the geometric error estimation at the first LOD according to the specific needs of a point cloud.

Could you test this change with your point cloud?

Thanks again for the great feedback!

mfbonfigli commented 2 years ago

The new release 1.2.1 fixes the geometric error computation issue for the first tile, hence closing this for now.