From 80a6616cd39df37a28414b956264b0a5ba9e3ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Tue, 15 Mar 2016 01:33:07 +0100 Subject: [PATCH] WIP on clouds testing --- src/interface/commandline/tests.cpp | 26 +++++++++++++++++++ src/render/software/CloudsRenderer.cpp | 12 +++++++++ src/render/software/CloudsRenderer.h | 10 ++++++- .../software/clouds/BaseCloudsModel.cpp | 12 ++++++--- src/render/software/clouds/BaseCloudsModel.h | 8 ++++++ 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/interface/commandline/tests.cpp b/src/interface/commandline/tests.cpp index 19e0cf8..c36b7f9 100644 --- a/src/interface/commandline/tests.cpp +++ b/src/interface/commandline/tests.cpp @@ -559,6 +559,31 @@ static void testCloudModels() { } } +static void testCloudsComponents() { + Scenery scenery; + scenery.autoPreset(2); + scenery.getTerrain()->propHeightNoise()->setConfig(0.0); + scenery.getCamera()->setLocation(Vector3(0.0, 1.0, 0.0)); + scenery.getCamera()->setTarget(Vector3(0.0, 2.0, -1.0)); + scenery.getCamera()->setFov(Maths::PI_2); + + scenery.getClouds()->clear(); + scenery.getClouds()->addLayer("test"); + auto layer = scenery.getClouds()->getCloudLayer(0); + layer->type = CloudLayerDefinition::STRATOCUMULUS; + layer->coverage = 0.7; + layer->validate(); + + SoftwareCanvasRenderer renderer(&scenery); + renderer.setSize(800, 600); + renderer.getGodRaysSampler()->setEnabled(false); + renderer.setQuality(0.5); + + startTestRender(&renderer, "clouds_component", 0); + // TODO Remove detail + // TODO Remove shadows +} + static void testCanvasAliasing() { class FakeRasterizer : public OverlayRasterizer { public: @@ -590,6 +615,7 @@ void runTestSuite() { // testCelestialBodies(); // testNearFrustum(); // testCloudsLighting(); + testCloudsComponents(); testCloudModels(); // testCloudsNearGround(); // testVegetationModels(); diff --git a/src/render/software/CloudsRenderer.cpp b/src/render/software/CloudsRenderer.cpp index f7c1e7e..ea2d23f 100644 --- a/src/render/software/CloudsRenderer.cpp +++ b/src/render/software/CloudsRenderer.cpp @@ -98,6 +98,18 @@ BaseCloudsModel *CloudsRenderer::getLayerModel(unsigned int layer) { } } +void CloudsRenderer::setLayerRenderer(unsigned int layer, BaseCloudLayerRenderer *renderer, bool delete_old) { + if (layer < layer_renderers.size()) { + if (delete_old) { + delete layer_renderers[layer]; + } + layer_renderers[layer] = renderer; + } else { + Logs::warning("Software.Clouds") << "Asked to set an unknown layer model" << layer << endl; + delete renderer; + } +} + void CloudsRenderer::setLayerModel(unsigned int layer, BaseCloudsModel *model, bool delete_old) { if (layer < layer_models.size()) { if (delete_old) { diff --git a/src/render/software/CloudsRenderer.h b/src/render/software/CloudsRenderer.h index 47e2677..e2c90c9 100644 --- a/src/render/software/CloudsRenderer.h +++ b/src/render/software/CloudsRenderer.h @@ -50,7 +50,15 @@ class SOFTWARESHARED_EXPORT CloudsRenderer : public LightFilter { virtual BaseCloudsModel *getLayerModel(unsigned int layer); /** - * Override de default density model for a given layer. + * Override the default renderer for a given layer. + * + * This must be called after each update(). + * Ownership of the renderer is taken. + */ + virtual void setLayerRenderer(unsigned int layer, BaseCloudLayerRenderer *renderer, bool delete_old = true); + + /** + * Override the default density model for a given layer. * * This must be called after each update(). * Ownership of the model is taken. diff --git a/src/render/software/clouds/BaseCloudsModel.cpp b/src/render/software/clouds/BaseCloudsModel.cpp index 71118e0..fa57201 100644 --- a/src/render/software/clouds/BaseCloudsModel.cpp +++ b/src/render/software/clouds/BaseCloudsModel.cpp @@ -30,14 +30,14 @@ BaseCloudsModel::CloudDensityInfo BaseCloudsModel::getDensity(const Vector3 &, d return {0.0, 1.0}; } -static inline Vector3 _getPseudoNormal(const BaseCloudsModel *model, const Vector3 &base, const Vector3 &direction, double base_density, double precision) { +static inline Vector3 _getPseudoNormal(const BaseCloudsModel *model, const Vector3 &base, const Vector3 &direction, + double base_density, double precision) { double density = model->getDensity(base.add(direction.scale(precision * 10.0)), precision).density; double diff = base_density - density; return direction.scale(diff > 0.0 ? diff : 0.0); } -Vector3 BaseCloudsModel::getNormal(const Vector3 &location) const -{ +Vector3 BaseCloudsModel::getNormal(const Vector3 &location) const { double precision = 0.3; Vector3 normal = VECTOR_ZERO; double base_density = getDensity(location, precision).density; @@ -47,5 +47,9 @@ Vector3 BaseCloudsModel::getNormal(const Vector3 &location) const normal = normal.add(_getPseudoNormal(this, location, VECTOR_WEST, base_density, precision)); normal = normal.add(_getPseudoNormal(this, location, VECTOR_NORTH, base_density, precision)); normal = normal.add(_getPseudoNormal(this, location, VECTOR_SOUTH, base_density, precision)); - return normal.normalize().scale(Maths::smoothstep(0.0, 1.0, normal.getNorm())); + return normal.normalize().scale(Maths::smoothstep(0.0, 0.1, normal.getNorm())); +} + +double BaseCloudsModel::getDetailValue(const Vector3 &, double, double) const { + return 0.0; } diff --git a/src/render/software/clouds/BaseCloudsModel.h b/src/render/software/clouds/BaseCloudsModel.h index d38495c..911ff0f 100644 --- a/src/render/software/clouds/BaseCloudsModel.h +++ b/src/render/software/clouds/BaseCloudsModel.h @@ -44,6 +44,14 @@ class SOFTWARESHARED_EXPORT BaseCloudsModel { */ Vector3 getNormal(const Vector3 &location) const; + /** + * Get the presence of clouds, at a detail level, given a density factor. + * + * The detail value is assumed to have a continuous derivative. + * To do so, it may return negative-or-zero values for non-presence. + */ + virtual double getDetailValue(const Vector3 &location, double density, double quality) const; + protected: CloudLayerDefinition *layer; };