From 3271b7ed5e2c0e684a20bf8cddf249375b081995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Tue, 17 Dec 2013 23:45:09 +0100 Subject: [PATCH] WIP on restoring clouds rendering --- .../software/CloudBasicLayerRenderer.cpp | 8 +- src/render/software/CloudsRenderer.cpp | 10 +-- src/render/software/CloudsRenderer.h | 8 +- src/render/software/LightFilter.h | 2 +- src/render/software/SoftwareRenderer.cpp | 25 +++--- src/render/software/TerrainRenderer.cpp | 38 +++++---- src/render/software/TerrainRenderer.h | 8 +- src/render/software/TexturesRenderer.cpp | 4 + src/render/software/TexturesRenderer.h | 2 + src/render/software/WaterRenderer.cpp | 78 ++++++++++--------- src/render/software/WaterRenderer.h | 8 +- 11 files changed, 106 insertions(+), 85 deletions(-) diff --git a/src/render/software/CloudBasicLayerRenderer.cpp b/src/render/software/CloudBasicLayerRenderer.cpp index 330cdd2..8a4e5d7 100644 --- a/src/render/software/CloudBasicLayerRenderer.cpp +++ b/src/render/software/CloudBasicLayerRenderer.cpp @@ -164,13 +164,13 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e result = COLOR_TRANSPARENT; detail = parent->getPrecision(start) / layer->scaling; - double transparency_depth = layer->scaling * 0.5; + double transparency_depth = layer->scaling * 0.7; segment_count = _findSegments(model, parent, start, direction, detail, 20, transparency_depth, max_length, &inside_length, &total_length, segments); for (i = segment_count - 1; i >= 0; i--) { SurfaceMaterial material; - material.base = colorToHSL(Color(0.7, 0.7, 0.7)); + material.base = colorToHSL(Color(3.0, 3.0, 3.0)); material.hardness = 0.25; material.reflection = 0.0; material.shininess = 0.0; @@ -206,7 +206,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent* return false; } - double light_traversal = model->getLayer()->scaling * 8.0; + double light_traversal = model->getLayer()->scaling * 1.3; _findSegments(model, parent, start, light->direction, 0.1, 20, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth, segments); if (light_traversal < 0.0001) @@ -222,7 +222,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent* } } - double miminum_light = 0.4; + double miminum_light = 0.2; factor = 1.0 - (1.0 - miminum_light) * factor; light->color.r *= factor; diff --git a/src/render/software/CloudsRenderer.cpp b/src/render/software/CloudsRenderer.cpp index e9635a2..16236ea 100644 --- a/src/render/software/CloudsRenderer.cpp +++ b/src/render/software/CloudsRenderer.cpp @@ -6,6 +6,7 @@ #include "CloudLayerDefinition.h" #include "BaseCloudLayerRenderer.h" #include "CloudBasicLayerRenderer.h" +#include "CameraDefinition.h" #include "clouds/BaseCloudsModel.h" #include "clouds/CloudModelStratoCumulus.h" @@ -134,25 +135,24 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons return cumul; } -bool CloudsRenderer::alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location) +bool CloudsRenderer::applyLightFilter(LightComponent &light, const Vector3 &at) { CloudsDefinition* definition = parent->getScenery()->getClouds(); int n = definition->count(); if (n < 1) { - return false; + return true; } /* TODO Iter layers in sorted order */ - bool altered = false; for (int i = 0; i < n; i++) { BaseCloudLayerRenderer* layer_renderer = getLayerRenderer(i); BaseCloudsModel* layer_model = getLayerModel(i); - altered = layer_renderer->alterLight(layer_model, light, eye, location) || altered; + layer_renderer->alterLight(layer_model, &light, parent->render_camera->getLocation(), at); } - return altered; + return true; } diff --git a/src/render/software/CloudsRenderer.h b/src/render/software/CloudsRenderer.h index 60daca8..8631887 100644 --- a/src/render/software/CloudsRenderer.h +++ b/src/render/software/CloudsRenderer.h @@ -3,13 +3,15 @@ #include "software_global.h" +#include "LightFilter.h" + namespace paysages { namespace software { /*! * \brief Software renderer of a group of cloud layers. */ -class SOFTWARESHARED_EXPORT CloudsRenderer +class SOFTWARESHARED_EXPORT CloudsRenderer: public LightFilter { public: CloudsRenderer(SoftwareRenderer* parent); @@ -20,7 +22,7 @@ public: * * Don't call this if another thread is currently using this renderer. */ - void update(); + virtual void update(); /*! * \brief Get the layer renderer for a given layer. @@ -46,7 +48,7 @@ public: * * Return true if the light was altered. */ - virtual bool alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location); + virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override; private: SoftwareRenderer* parent; diff --git a/src/render/software/LightFilter.h b/src/render/software/LightFilter.h index 3add5fa..eb9b90b 100644 --- a/src/render/software/LightFilter.h +++ b/src/render/software/LightFilter.h @@ -18,7 +18,7 @@ public: * This will alter the component and return if the component is still * useful. */ - bool applyLightFilter(LightComponent &light, const Vector3 &at); + virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) = 0; }; } diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index 5c690c8..5817772 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -42,6 +42,10 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery) fluid_medium = new FluidMediumManager(this); lighting = new LightingManager(); + lighting->registerFilter(terrain_renderer); + lighting->registerFilter(water_renderer); + lighting->registerFilter(clouds_renderer); + this->scenery = new Scenery; if (scenery) { @@ -54,15 +58,15 @@ SoftwareRenderer::~SoftwareRenderer() delete render_camera; delete render_area; + delete fluid_medium; + delete lighting; + delete atmosphere_renderer; delete clouds_renderer; delete terrain_renderer; delete textures_renderer; delete water_renderer; - delete fluid_medium; - delete lighting; - delete scenery; } @@ -76,6 +80,7 @@ void SoftwareRenderer::prepare() scenery->getCamera()->copy(render_camera); // Prepare sub renderers + // TODO Don't recreate the renderer each time delete atmosphere_renderer; if (getScenery()->getAtmosphere()->model == AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON) { @@ -86,18 +91,10 @@ void SoftwareRenderer::prepare() atmosphere_renderer = new BaseAtmosphereRenderer(this); } - delete clouds_renderer; - clouds_renderer = new CloudsRenderer(this); clouds_renderer->update(); - - delete terrain_renderer; - terrain_renderer = new TerrainRenderer(this); - - delete textures_renderer; - textures_renderer = new TexturesRenderer(this); - - delete water_renderer; - water_renderer = new WaterRenderer(this); + terrain_renderer->update(); + water_renderer->update(); + textures_renderer->update(); // Prepare global tools fluid_medium->clearMedia(); diff --git a/src/render/software/TerrainRenderer.cpp b/src/render/software/TerrainRenderer.cpp index 184773f..cd55247 100644 --- a/src/render/software/TerrainRenderer.cpp +++ b/src/render/software/TerrainRenderer.cpp @@ -15,6 +15,10 @@ TerrainRenderer::~TerrainRenderer() { } +void TerrainRenderer::update() +{ +} + double TerrainRenderer::getHeight(double x, double z, int with_painting) { return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, 1, with_painting); @@ -182,26 +186,26 @@ RayCastingResult TerrainRenderer::castRay(const Vector3 &start, const Vector3 &d return result; } -int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location) +bool TerrainRenderer::applyLightFilter(LightComponent &light, const Vector3 &at) { TerrainDefinition* definition = parent->getScenery()->getTerrain(); Vector3 inc_vector, direction_to_light, cursor; double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; - direction_to_light = light->direction.scale(-1.0); + direction_to_light = light.direction.scale(-1.0); if (direction_to_light.y < -0.05) { - light->color = COLOR_BLACK; - return 1; + light.color = COLOR_BLACK; + return false; } else if (direction_to_light.y < 0.0000) { - light->color.r *= (0.05 + direction_to_light.y) / 0.05; - light->color.g *= (0.05 + direction_to_light.y) / 0.05; - light->color.b *= (0.05 + direction_to_light.y) / 0.05; + light.color.r *= (0.05 + direction_to_light.y) / 0.05; + light.color.g *= (0.05 + direction_to_light.y) / 0.05; + light.color.b *= (0.05 + direction_to_light.y) / 0.05; } - cursor = location; + cursor = at; inc_factor = (double)parent->render_quality; inc_base = definition->height / definition->scaling; inc_value = inc_base / inc_factor; @@ -215,8 +219,8 @@ int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location) inc_vector = direction_to_light.scale(inc_value); length += inc_vector.getNorm(); cursor = cursor.add(inc_vector); - height = parent->getTerrainRenderer()->getResult(location.x, location.z, 1, 1).location.y; - diff = location.y - height; + height = parent->getTerrainRenderer()->getResult(cursor.x, cursor.z, 1, 1).location.y; + diff = cursor.y - height; if (diff < 0.0) { if (length * smoothing > 0.000001) @@ -242,20 +246,20 @@ int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location) inc_value = diff; } } - while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height); + while (light_factor > 0.0 && length < (10.0 * inc_factor) && cursor.y <= definition->_max_height); if (light_factor <= 0.0) { - light->color = COLOR_BLACK; - return 1; + light.color = COLOR_BLACK; + return false; } else { - light->color.r *= light_factor; - light->color.g *= light_factor; - light->color.b *= light_factor; + light.color.r *= light_factor; + light.color.g *= light_factor; + light.color.b *= light_factor; - return 1; + return true; } } diff --git a/src/render/software/TerrainRenderer.h b/src/render/software/TerrainRenderer.h index 3cdab8d..301ce88 100644 --- a/src/render/software/TerrainRenderer.h +++ b/src/render/software/TerrainRenderer.h @@ -3,13 +3,15 @@ #include "software_global.h" +#include "LightFilter.h" + #include "RayCastingManager.h" #include "Color.h" namespace paysages { namespace software { -class SOFTWARESHARED_EXPORT TerrainRenderer +class SOFTWARESHARED_EXPORT TerrainRenderer: public LightFilter { public: typedef struct @@ -22,12 +24,14 @@ public: TerrainRenderer(SoftwareRenderer* parent); virtual ~TerrainRenderer(); + virtual void update(); + virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction); virtual double getHeight(double x, double z, int with_painting); virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures); virtual Color getFinalColor(const Vector3 &location, double precision); virtual double getWaterHeight(); - virtual int alterLight(LightComponent *light, const Vector3 &location); + virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override; private: SoftwareRenderer* parent; diff --git a/src/render/software/TexturesRenderer.cpp b/src/render/software/TexturesRenderer.cpp index 454cd64..5e468eb 100644 --- a/src/render/software/TexturesRenderer.cpp +++ b/src/render/software/TexturesRenderer.cpp @@ -16,6 +16,10 @@ TexturesRenderer::~TexturesRenderer() { } +void TexturesRenderer::update() +{ +} + /* * Get the base presence factor of a layer, not accounting for other layers. */ diff --git a/src/render/software/TexturesRenderer.h b/src/render/software/TexturesRenderer.h index c7dea63..3281d07 100644 --- a/src/render/software/TexturesRenderer.h +++ b/src/render/software/TexturesRenderer.h @@ -34,6 +34,8 @@ public: TexturesRenderer(SoftwareRenderer *parent); virtual ~TexturesRenderer(); + virtual void update(); + virtual double getMaximalDisplacement(TexturesDefinition *textures); virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain); virtual double getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal); diff --git a/src/render/software/WaterRenderer.cpp b/src/render/software/WaterRenderer.cpp index abfa86e..bbda301 100644 --- a/src/render/software/WaterRenderer.cpp +++ b/src/render/software/WaterRenderer.cpp @@ -17,6 +17,10 @@ WaterRenderer::~WaterRenderer() { } +void WaterRenderer::update() +{ +} + static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z) { return base_height + definition->_waves_noise->get2DTotal(x, z); @@ -135,43 +139,6 @@ static inline Color _getFoamMask(SoftwareRenderer* renderer, WaterDefinition* de return result; } -int WaterRenderer::alterLight(LightComponent *light, const Vector3 &at) -{ - WaterDefinition* definition = parent->getScenery()->getWater(); - double factor; - double base_height; - - base_height = parent->getTerrainRenderer()->getWaterHeight(); - if (at.y < base_height) - { - if (light->direction.y <= -0.00001) - { - factor = (base_height - at.y) / (-light->direction.y * definition->lighting_depth); - if (factor > 1.0) - { - factor = 1.0; - } - factor = 1.0 - factor; - - light->color.r *= factor; - light->color.g *= factor; - light->color.b *= factor; - light->reflection *= factor; - - return 1; - } - else - { - light->color = COLOR_BLACK; - return 1; - } - } - else - { - return 0; - } -} - HeightInfo WaterRenderer::getHeightInfo() { WaterDefinition* definition = parent->getScenery()->getWater(); @@ -270,3 +237,40 @@ WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z) return result; } + +bool WaterRenderer::applyLightFilter(LightComponent &light, const Vector3 &at) +{ + WaterDefinition* definition = parent->getScenery()->getWater(); + double factor; + double base_height; + + base_height = parent->getTerrainRenderer()->getWaterHeight(); + if (at.y < base_height) + { + if (light.direction.y <= -0.00001) + { + factor = (base_height - at.y) / (-light.direction.y * definition->lighting_depth); + if (factor > 1.0) + { + factor = 1.0; + } + factor = 1.0 - factor; + + light.color.r *= factor; + light.color.g *= factor; + light.color.b *= factor; + light.reflection *= factor; + + return true; + } + else + { + light.color = COLOR_BLACK; + return false; + } + } + else + { + return true; + } +} diff --git a/src/render/software/WaterRenderer.h b/src/render/software/WaterRenderer.h index 055edbc..8d004c4 100644 --- a/src/render/software/WaterRenderer.h +++ b/src/render/software/WaterRenderer.h @@ -3,6 +3,8 @@ #include "software_global.h" +#include "LightFilter.h" + #include "TerrainDefinition.h" #include "Vector3.h" #include "Color.h" @@ -10,7 +12,7 @@ namespace paysages { namespace software { -class SOFTWARESHARED_EXPORT WaterRenderer +class SOFTWARESHARED_EXPORT WaterRenderer:public LightFilter { public: typedef struct @@ -27,10 +29,12 @@ public: WaterRenderer(SoftwareRenderer* parent); virtual ~WaterRenderer(); + virtual void update(); + virtual HeightInfo getHeightInfo(); virtual double getHeight(double x, double z); virtual WaterResult getResult(double x, double z); - virtual int alterLight(LightComponent *light, const Vector3 &at); + virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override; private: SoftwareRenderer* parent;