diff --git a/src/interface/commandline/tests.cpp b/src/interface/commandline/tests.cpp index 867531f..8b28c93 100644 --- a/src/interface/commandline/tests.cpp +++ b/src/interface/commandline/tests.cpp @@ -210,6 +210,23 @@ static void testNearFrustum() startTestRender(&renderer, "near_frustum"); } +static void testCloudsNearGround() +{ + Scenery scenery; + scenery.autoPreset(8); + scenery.getAtmosphere()->setDayTime(6, 20); + + SoftwareCanvasRenderer renderer(&scenery); + renderer.setSize(400, 300); + renderer.setQuality(0.3); + + startTestRender(&renderer, "clouds_near_ground", 1); + + scenery.getCamera()->strafeUp(6.0); + scenery.getCamera()->copy(renderer.render_camera); + startTestRender(&renderer, "clouds_near_ground", 2); +} + void runTestSuite() { testGroundShadowQuality(); @@ -217,4 +234,5 @@ void runTestSuite() testCloudQuality(); testGodRays(); testNearFrustum(); + testCloudsNearGround(); } diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index 77118b1..752fb7b 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -1191,6 +1191,12 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(SUN_DISTANCE); Vector3 direction = location.sub(eye).scale(WORLD_SCALING); + double t = direction.getNorm(); + if (t < 0.000001) + { + direction = parent->getCameraDirection(location).scale(0.001 * WORLD_SCALING); + t = direction.getNorm(); + } Vector3 x = {0.0, Rg + WORKAROUND_OFFSET + eye.y * WORLD_SCALING, 0.0}; Vector3 v = direction.normalize(); @@ -1203,7 +1209,6 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio double r = x.getNorm(); double mu = x.dotProduct(v) / r; - double t = direction.getNorm(); AtmosphereResult result; Vector3 attenuation; diff --git a/src/render/software/CloudBasicLayerRenderer.cpp b/src/render/software/CloudBasicLayerRenderer.cpp index b966265..b3badf9 100644 --- a/src/render/software/CloudBasicLayerRenderer.cpp +++ b/src/render/software/CloudBasicLayerRenderer.cpp @@ -11,6 +11,8 @@ #include "SurfaceMaterial.h" #include "Logs.h" +#include + struct CloudSegment { Vector3 start; @@ -196,9 +198,16 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e result.a += (1.0 - result.a) * ((inside_length - transparency_depth * 0.8) / (transparency_depth * 0.2)); } - double a = result.a; - result = parent->getAtmosphereRenderer()->applyAerialPerspective(start, result).final; - result.a = a; + // Apply aerial perspective + if (result.a > 0.00001) + { + assert(segment_count > 0); + + double a = result.a; + // TODO Don't apply it only at first segment + result = parent->getAtmosphereRenderer()->applyAerialPerspective(segments[0].start, result).final; + result.a = a; + } return result; }