Fixed aerial perspective being applied at wrong location in clouds
It was applied at the enter point of the walking algorithm, which was the camera when it was inside a cloud layer. Now it is applied at the first found segment, which is still not optimal but better. The bruneton model was also fixed to not produce black results for aerial perspective exactly at the camera location.
This commit is contained in:
parent
a5c36f90f0
commit
2be80bf8e2
3 changed files with 36 additions and 4 deletions
|
@ -210,6 +210,23 @@ static void testNearFrustum()
|
||||||
startTestRender(&renderer, "near_frustum");
|
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()
|
void runTestSuite()
|
||||||
{
|
{
|
||||||
testGroundShadowQuality();
|
testGroundShadowQuality();
|
||||||
|
@ -217,4 +234,5 @@ void runTestSuite()
|
||||||
testCloudQuality();
|
testCloudQuality();
|
||||||
testGodRays();
|
testGodRays();
|
||||||
testNearFrustum();
|
testNearFrustum();
|
||||||
|
testCloudsNearGround();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1191,6 +1191,12 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
|
||||||
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(SUN_DISTANCE);
|
Vector3 sun_position = parent->getAtmosphereRenderer()->getSunDirection().scale(SUN_DISTANCE);
|
||||||
|
|
||||||
Vector3 direction = location.sub(eye).scale(WORLD_SCALING);
|
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 x = {0.0, Rg + WORKAROUND_OFFSET + eye.y * WORLD_SCALING, 0.0};
|
||||||
Vector3 v = direction.normalize();
|
Vector3 v = direction.normalize();
|
||||||
|
@ -1203,7 +1209,6 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
|
||||||
|
|
||||||
double r = x.getNorm();
|
double r = x.getNorm();
|
||||||
double mu = x.dotProduct(v) / r;
|
double mu = x.dotProduct(v) / r;
|
||||||
double t = direction.getNorm();
|
|
||||||
|
|
||||||
AtmosphereResult result;
|
AtmosphereResult result;
|
||||||
Vector3 attenuation;
|
Vector3 attenuation;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
struct CloudSegment
|
struct CloudSegment
|
||||||
{
|
{
|
||||||
Vector3 start;
|
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));
|
result.a += (1.0 - result.a) * ((inside_length - transparency_depth * 0.8) / (transparency_depth * 0.2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply aerial perspective
|
||||||
|
if (result.a > 0.00001)
|
||||||
|
{
|
||||||
|
assert(segment_count > 0);
|
||||||
|
|
||||||
double a = result.a;
|
double a = result.a;
|
||||||
result = parent->getAtmosphereRenderer()->applyAerialPerspective(start, result).final;
|
// TODO Don't apply it only at first segment
|
||||||
|
result = parent->getAtmosphereRenderer()->applyAerialPerspective(segments[0].start, result).final;
|
||||||
result.a = a;
|
result.a = a;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue