Skip to content

Commit 521e3fd

Browse files
committed
Merge pull request #1067 from AnalyticalGraphicsInc/ellipsoidPrecision
Ellipsoid precision
2 parents 7af95f4 + 7b47568 commit 521e3fd

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ var geometry = BoxGeometry.createGeometry(box);
5252
* `Viewer` now automatically sets its clock to that of the first added `DataSource`, regardless of how it was added to the `DataSourceCollection`. Previously, this was only done for dropped files by `viewerDragDropMixin`.
5353
* Upgraded Knockout from version 2.2.1 to 2.3.0.
5454
* Fixed triangulation for polygons that cross the international date line.
55+
* Fixed `EllipsoidPrimitive` rendering for some oblate ellipsoids. [#1067](https://github.com/AnalyticalGraphicsInc/cesium/pull/1067).
5556
* `CameraFlightPath` now automatically disables and restores mouse input for the flights it generates.
5657
* Added an `onCancel` callback to `CameraFlightPath` functions that will be executed if the flight is canceled.
5758

Source/Shaders/EllipsoidFS.glsl

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,44 @@ vec4 computeEllipsoidColor(czm_ray ray, float intersection, float side)
2929

3030
void main()
3131
{
32-
czm_ellipsoid ellipsoid = czm_ellipsoidNew(czm_modelView[3].xyz, u_radii);
32+
// PERFORMANCE_TODO: When dynamic branching is available, compute ratio of maximum and minimum radii
33+
// in the vertex shader. Only when it is larger than some constant, march along the ray.
34+
// Otherwise perform one intersection test which will be the common case.
35+
36+
// Test if the ray intersects a sphere with the ellipsoid's maximum radius.
37+
// For very oblate ellipsoids, using the ellipsoid's radii for an intersection test
38+
// may cause false negatives. This will discard fragments before marching the ray forward.
39+
float maxRadius = max(u_radii.x, max(u_radii.y, u_radii.z)) * 1.5;
3340
vec3 direction = normalize(v_positionEC);
34-
czm_ray ray = czm_ray(vec3(0.0), direction);
35-
czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);
41+
vec3 ellipsoidCenter = czm_modelView[3].xyz;
42+
43+
float t1 = -1.0;
44+
float t2 = -1.0;
45+
46+
float b = -2.0 * dot(direction, ellipsoidCenter);
47+
float c = dot(ellipsoidCenter, ellipsoidCenter) - maxRadius * maxRadius;
3648

49+
float discriminant = b * b - 4.0 * c;
50+
if (discriminant >= 0.0) {
51+
t1 = (-b - sqrt(discriminant)) * 0.5;
52+
t2 = (-b + sqrt(discriminant)) * 0.5;
53+
}
54+
55+
if (t1 < 0.0 && t2 < 0.0) {
56+
discard;
57+
}
58+
59+
float t = min(t1, t2);
60+
if (t < 0.0) {
61+
t = 0.0;
62+
}
63+
64+
// March ray forward to intersection with larger sphere and find
65+
// actual intersection point with ellipsoid.
66+
czm_ellipsoid ellipsoid = czm_ellipsoidNew(ellipsoidCenter, u_radii);
67+
czm_ray ray = czm_ray(t * direction, direction);
68+
czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);
69+
3770
if (czm_isEmpty(intersection))
3871
{
3972
discard;

0 commit comments

Comments
 (0)