Prevent floating point over- and underflows; specifically when interpolating the camera position (closes #575)

This commit is contained in:
Alexander Bock
2018-04-10 15:04:41 -04:00
parent 62eca12e25
commit 34987e9f85
8 changed files with 49 additions and 19 deletions
@@ -292,7 +292,13 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
}
// Sun Position in Object Space
program.setUniform(_uniformCache2.sunDirectionObj, glm::normalize(glm::dvec3(sunPosObj)));
const double l = glm::length(glm::dvec3(sunPosObj));
program.setUniform(
_uniformCache2.sunDirectionObj,
l > 0.0 ?
glm::normalize(glm::dvec3(sunPosObj)) :
glm::dvec3(0.0)
);
// Shadow calculations..
if (!_shadowConfArray.empty()) {
@@ -85,13 +85,21 @@ bool HorizonCuller::isCullable(const glm::dvec3& cameraPosition,
double objectBoundingSphereRadius,
double minimumGlobeRadius)
{
double distanceToHorizon =
sqrt(pow(length(cameraPosition - globePosition), 2) -
pow(minimumGlobeRadius, 2));
const double objectP = pow(length(objectPosition - globePosition), 2);
const double horizonP = pow(minimumGlobeRadius - objectBoundingSphereRadius, 2);
if (objectP < horizonP) {
return false;
}
double minimumAllowedDistanceToObjectFromHorizon = sqrt(
pow(length(objectPosition - globePosition), 2) -
pow(minimumGlobeRadius - objectBoundingSphereRadius, 2));
const double cameraP = pow(length(cameraPosition - globePosition), 2);
const double minR = pow(minimumGlobeRadius, 2);
if (cameraP < minR) {
return false;
}
double minimumAllowedDistanceToObjectFromHorizon = sqrt(objectP - horizonP);
double distanceToHorizon = sqrt(cameraP - minR);
// Minimum allowed for the object to be occluded
double minimumAllowedDistanceToObjectSquared =
@@ -271,8 +271,11 @@ void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObjec
chunk.owner().generalProperties().atmosphereEnabled ||
chunk.owner().generalProperties().performShading)
{
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::dvec3 directionToSunWorldSpace =
length(data.modelTransform.translation) > 0.0 ?
glm::normalize(-data.modelTransform.translation) :
glm::dvec3(0.0);
glm::vec3 directionToSunCameraSpace =
glm::vec3(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
programObject.setUniform(