diff --git a/modules/globebrowsing/shaders/ellipsoid.hglsl b/modules/globebrowsing/shaders/ellipsoid.hglsl index 02f505c3d9..779c951de8 100644 --- a/modules/globebrowsing/shaders/ellipsoid.hglsl +++ b/modules/globebrowsing/shaders/ellipsoid.hglsl @@ -30,6 +30,12 @@ struct PositionNormalPair { vec3 normal; }; +struct Intersection { + bool intersects; + float nearParameter;// Along ray + float farParameter; // Along ray +}; + vec3 geodeticSurfaceNormal(float latitude, float longitude) { float cosLat = cos(latitude); @@ -68,4 +74,33 @@ vec3 latLonToCartesian(float latitude, float longitude, float radius) { sin(latitude)); } +// +// Assumes ellipsoid is at (0, 0, 0) +// +Intersection rayIntersectEllipsoid( + vec3 rayOrigin, + vec3 rayOriginSquared, + vec3 rayDirection, + vec3 oneOverEllipsoidRadiiSquared) +{ + float a = dot(rayDirection * rayDirection, oneOverEllipsoidRadiiSquared); + float b = 2.0 * dot(rayOrigin * rayDirection, oneOverEllipsoidRadiiSquared); + float c = dot(rayOriginSquared, oneOverEllipsoidRadiiSquared) - 1.0; + float discriminant = b * b - 4.0 * a * c; + + if (discriminant < 0.0) { + return Intersection(false, 0.0, 0.0); + } + else if (discriminant == 0.0) { + float time = -0.5 * b / a; + return Intersection(true, time, time); + } + + float t = -0.5 * (b + (b > 0.0 ? 1.0 : -1.0) * sqrt(discriminant)); + float root1 = t / a; + float root2 = c / t; + + return Intersection(true, min(root1, root2), max(root1, root2)); +} + #endif // ELLIPSOID_HGLSL \ No newline at end of file