paysages3d/src/interface/commandline/tests.cpp
Michaël Lemaire 2be80bf8e2 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.
2015-10-09 00:43:32 +02:00

239 lines
7.3 KiB
C++

#include "SoftwareCanvasRenderer.h"
#include "TerrainRenderer.h"
#include "Scenery.h"
#include "CameraDefinition.h"
#include "TerrainDefinition.h"
#include "AtmosphereDefinition.h"
#include "TexturesDefinition.h"
#include "GodRaysDefinition.h"
#include "TextureLayerDefinition.h"
#include "WaterDefinition.h"
#include "SurfaceMaterial.h"
#include "FloatNode.h"
#include "SkyRasterizer.h"
#include "CloudsDefinition.h"
#include "LightComponent.h"
#include "LightingManager.h"
#include "LightFilter.h"
#include "GodRaysSampler.h"
#include <sstream>
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath);
static void startTestRender(SoftwareCanvasRenderer *renderer, const std::string &name, int iteration=-1)
{
std::ostringstream stream;
stream << "pic_test_" << name;
if (iteration >= 0)
{
stream << "_";
stream.width(4);
stream.fill('0');
stream << iteration;
}
stream << ".png";
startRender(renderer, stream.str().data());
}
static void testGroundShadowQuality()
{
Scenery scenery;
srand(5);
scenery.getTerrain()->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD);
scenery.getTerrain()->propWaterHeight()->setValue(-0.5);
scenery.getWater()->propReflection()->setValue(0.0);
scenery.getWater()->material->base->r = 0.0;
scenery.getWater()->material->base->g = 0.3;
scenery.getWater()->material->base->b = 1.0;
scenery.getWater()->material->reflection = 0.0;
scenery.getWater()->foam_coverage = 0.0;
scenery.getWater()->transparency = 0.0;
scenery.getAtmosphere()->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_SUNSET);
scenery.getAtmosphere()->setDayTime(16, 45);
scenery.getTextures()->clear();
TextureLayerDefinition *texture = scenery.getTextures()->getTextureLayer(scenery.getTextures()->addLayer());
texture->displacement_height = 0.3;
texture->displacement_scaling = 2.0;
texture->displacement_offset = 0.0;
texture->material->setColor(0.6, 0.55, 0.57, 1.0);
texture->material->reflection = 0.006;
texture->material->shininess = 6.0;
texture->validate();
scenery.getCamera()->setLocation(Vector3(10.0, 10.0, -10.0));
scenery.getCamera()->setTarget(VECTOR_ZERO);
scenery.validate();
SoftwareCanvasRenderer renderer(&scenery);
renderer.setSize(400, 300);
renderer.setQuality(0.2);
for (int i = 0; i < 6; i++)
{
// TODO keep same rasterization across renders
renderer.getTerrainRenderer()->setQuality((double)i / 5.0);
startTestRender(&renderer, "ground_shadow_quality", i);
}
}
static void testRasterizationQuality()
{
Scenery scenery;
scenery.autoPreset(12);
SoftwareCanvasRenderer renderer(&scenery);
renderer.setSize(800, 600);
renderer.enablePostprocess(false);
for (int i = 0; i < 6; i++)
{
renderer.setQuality((double)i / 5.0);
startTestRender(&renderer, "rasterization_quality", i);
}
}
static void testCloudQuality()
{
Scenery scenery;
scenery.autoPreset(3);
scenery.getCamera()->setLocation(Vector3(5.0, 5.0, 5.0));
scenery.getCamera()->setTarget(Vector3(8.0, 7.25, 8.0));
scenery.getTerrain()->height = 0.0;
scenery.getTerrain()->validate();
SoftwareCanvasRenderer renderer(&scenery);
renderer.setSize(600, 800);
SkyRasterizer *rasterizer = new SkyRasterizer(&renderer, renderer.getProgressHelper(), 0);
renderer.setSoloRasterizer(rasterizer);
for (int i = 0; i < 6; i++)
{
renderer.setQuality((double)i / 5.0);
rasterizer->setQuality(0.2);
startTestRender(&renderer, "cloud_quality", i);
}
}
static void testGodRays()
{
class TestLightFilter: public LightFilter
{
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override
{
if (Vector3(0.0, 100.0, 0.0).sub(at).normalize().y > 0.97)
{
light.color = COLOR_BLACK;
return false;
}
else
{
return true;
}
}
};
class TestRenderer: public SoftwareCanvasRenderer
{
public:
TestRenderer(Scenery *scenery): SoftwareCanvasRenderer(scenery) {}
private:
virtual void prepare() override
{
SoftwareRenderer::prepare();
getLightingManager()->clearSources();
getLightingManager()->addStaticLight(LightComponent(COLOR_WHITE, VECTOR_DOWN));
getGodRaysSampler()->setAltitudes(0.0, 30.0);
getGodRaysSampler()->reset();
}
};
Scenery scenery;
scenery.autoPreset(63);
scenery.getAtmosphere()->setDayTime(12);
scenery.getCamera()->setLocation(Vector3(0.0, 1.0, -50.0));
scenery.getCamera()->setTarget(Vector3(0.0, 15.0, 0.0));
scenery.getTerrain()->height = 0.0;
scenery.getTerrain()->validate();
scenery.getClouds()->clear();
TestRenderer renderer(&scenery);
renderer.setSize(500, 300);
SkyRasterizer *rasterizer = new SkyRasterizer(&renderer, renderer.getProgressHelper(), 0);
renderer.setSoloRasterizer(rasterizer);
TestLightFilter filter;
renderer.getLightingManager()->clearFilters();
renderer.getLightingManager()->registerFilter(&filter);
// quality
for (int i = 0; i < 6; i++)
{
renderer.setQuality((double)i / 5.0);
rasterizer->setQuality(0.2);
startTestRender(&renderer, "god_rays_quality", i);
}
renderer.setQuality(0.5);
// penetration
for (int i = 0; i < 3; i++)
{
scenery.getAtmosphere()->childGodRays()->propPenetration()->setValue(0.01 + 0.02 * (double)i);
startTestRender(&renderer, "god_rays_penetration", i);
}
// resistance
scenery.getAtmosphere()->childGodRays()->propPenetration()->setValue(0.01);
for (int i = 0; i < 3; i++)
{
scenery.getAtmosphere()->childGodRays()->propResistance()->setValue(0.1 + 0.1 * (double)i);
startTestRender(&renderer, "god_rays_resistance", i);
}
// boost
scenery.getAtmosphere()->childGodRays()->propResistance()->setValue(0.3);
for (int i = 0; i < 3; i++)
{
scenery.getAtmosphere()->childGodRays()->propBoost()->setValue(2.0 + 4.0 * (double)i);
startTestRender(&renderer, "god_rays_boost", i);
}
}
static void testNearFrustum()
{
Scenery scenery;
scenery.autoPreset(3);
scenery.getCamera()->setLocation(Vector3(0.0, 0.0, 0.0));
scenery.getCamera()->setTarget(Vector3(1.0, 0.0, 1.0));
scenery.keepCameraAboveGround(scenery.getCamera());
SoftwareCanvasRenderer renderer(&scenery);
renderer.setSize(400, 300);
renderer.setQuality(0.1);
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();
testRasterizationQuality();
testCloudQuality();
testGodRays();
testNearFrustum();
testCloudsNearGround();
}