create3000 / cobweb

Cobweb is now X_ITE
https://github.com/create3000/x_ite
Other
10 stars 5 forks source link

far clipping #11

Closed andreasplesch closed 8 years ago

andreasplesch commented 8 years ago

I put together a rough geospatial scene of earthquake faults in Calfornia:

https://9a1a1f7091a1f53adbc002bf8336127f7d36bb15.googledrive.com/host/0BwIhFzkLaQ9XQ1NnaV93bWRHQzg/CFM5_cobweb.html

Overall looks good (there are some overlapping elements, eg. a scene problem) but there is a far clipping plane which seems too close.

create3000 commented 8 years ago

In my eyes it looks awful, lot of z-fighting and far clipping. I will look what I can do. Thank you for this example.

andreasplesch commented 8 years ago

The z-fighting is due to overlapping, identical triangles of very similar IFSs. So do not worry about the flickering/z-fighting. Is there a way to control the clipping ? x3dom has zfar.

create3000 commented 8 years ago

This scene uses a »normal« Viewpoint to display the scene. A Viewpoints clipping planes are controlled by a NavigationInfo nodes avatarSize first field and the visibilityLimit field, where the zNear is avatarSize [0] / 2 and zFar is visibilityLimit, if the visibilityLimit is 0 a unlimited zFar should be used, this is not possible in WebGL, thus Cobweb uses 100000 for zFar. These are hard coded values, and exactly as the spec describes it, don't know if there are better approaches. The distance between zNear and zFar controls the amount of z-fighting. But for large scale scenes a GeoViewpoint is more appropriate, this viewpoint automatically adjusts zNear and zFar depending on the hight of the viewer. If you would use a GeoViewpoint for this scene z-fighting and far-clipping will disappear, or use a NavigationInfo's fields to adjust the clipping planes manually.

andreasplesch commented 8 years ago

Nice. I.will give it a quick.try.

Would increasing the infinite visibilityLimit to 500000 or 1000000 cause precision problems ?

How do you scale based on height with GeoViewpoint ? It is possible to calculate the distance to the horizon.

andreasplesch commented 8 years ago

Ok. I updated the example to use both, a GeoViewpoint and a regular Viewpoint with NavigationInfo. Somehow I had a few FF crashes but these were not reproducible and now both Viewpoints work as expected.

create3000 commented 8 years ago

Would increasing the infinite visibilityLimit to 500000 or 1000000 cause precision problems?

Only increasing the visibilityLimit will lower the precision of the z-buffer, as higher the visibilityLimit as lower the precision of the z-buffer, and a low z-buffer precision will increase z-fighting. To avoid this you must also increase the zNear. If you increase the visibilityLimit by a factor of 10 you must also increase zNear by a factor of 10 to get almost the same precision.

How do you scale based on height with GeoViewpoint?

I do a linear interpolation depending on the elevation, this mean if you are close to the earth surface zNear and zFar will be taken from NavigationInfo without a change. As higher you are above the surface as more increases zNear and zFar.

var
    geoZNear = Math .max (Algorithm .lerp (Math .min (zNear, 1e4), 1e4, this .elevation / 1e7), 1),
    geoZFar  = Math .max (Algorithm .lerp (1e6, Math .max (zFar, 1e6),  this .elevation / 1e7), 1e6);

Where zNear and zFar are the clipping planes from the NavigationInfo and elevation is the distance above (or below) the earth surface.

It is possible to calculate the distance to the horizon.

Yes, it would be possible to calculate the distance to the horizon, at least approximately. For a static scene this can be done by calculating the bounding box of the entire scene. But a scene is not always static, Inline nodes can be loaded later, animations can be placed somewhere in the scene. This would mean that the bbox must be calculated for every frame, but this is extremely expensive. There are probably ways to lower calculations.

andreasplesch commented 8 years ago

ok. This seems to work well. A estimated distance to the horizon based on the earth's curvature for larger heights (>10km?) could be calculated from this triangle: snapshot1

eg.

zFar = sqrt((radius+height)^2 - radius^2)
or perhaps
zFar = (radius+height) * sin ( acos (radius/(radius+height) )
or perhaps
zFar = radius * tan ( acos (  radius/(radius+height) )

On the other hand, one may want to look at the moon in the very far distance as well.

create3000 commented 8 years ago

Great idea, and very easy and cheap to implement.

On the other hand, one may want to look at the moon in the very far distance as well.

Such a optimized formula cannot coverer all special circumstances how a X3D file is build. An author can yet use a NavigationInfo node's visibilityLimit field to specifiy a father zFar.