WIP on restoring clouds rendering

This commit is contained in:
Michaël Lemaire 2013-12-17 23:45:09 +01:00
parent 192aa7604e
commit 3271b7ed5e
11 changed files with 106 additions and 85 deletions

View file

@ -164,13 +164,13 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
result = COLOR_TRANSPARENT; result = COLOR_TRANSPARENT;
detail = parent->getPrecision(start) / layer->scaling; 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); 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--) for (i = segment_count - 1; i >= 0; i--)
{ {
SurfaceMaterial material; 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.hardness = 0.25;
material.reflection = 0.0; material.reflection = 0.0;
material.shininess = 0.0; material.shininess = 0.0;
@ -206,7 +206,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent*
return false; 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); _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) 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; factor = 1.0 - (1.0 - miminum_light) * factor;
light->color.r *= factor; light->color.r *= factor;

View file

@ -6,6 +6,7 @@
#include "CloudLayerDefinition.h" #include "CloudLayerDefinition.h"
#include "BaseCloudLayerRenderer.h" #include "BaseCloudLayerRenderer.h"
#include "CloudBasicLayerRenderer.h" #include "CloudBasicLayerRenderer.h"
#include "CameraDefinition.h"
#include "clouds/BaseCloudsModel.h" #include "clouds/BaseCloudsModel.h"
#include "clouds/CloudModelStratoCumulus.h" #include "clouds/CloudModelStratoCumulus.h"
@ -134,25 +135,24 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons
return cumul; 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(); CloudsDefinition* definition = parent->getScenery()->getClouds();
int n = definition->count(); int n = definition->count();
if (n < 1) if (n < 1)
{ {
return false; return true;
} }
/* TODO Iter layers in sorted order */ /* TODO Iter layers in sorted order */
bool altered = false;
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
BaseCloudLayerRenderer* layer_renderer = getLayerRenderer(i); BaseCloudLayerRenderer* layer_renderer = getLayerRenderer(i);
BaseCloudsModel* layer_model = getLayerModel(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;
} }

View file

@ -3,13 +3,15 @@
#include "software_global.h" #include "software_global.h"
#include "LightFilter.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
/*! /*!
* \brief Software renderer of a group of cloud layers. * \brief Software renderer of a group of cloud layers.
*/ */
class SOFTWARESHARED_EXPORT CloudsRenderer class SOFTWARESHARED_EXPORT CloudsRenderer: public LightFilter
{ {
public: public:
CloudsRenderer(SoftwareRenderer* parent); CloudsRenderer(SoftwareRenderer* parent);
@ -20,7 +22,7 @@ public:
* *
* Don't call this if another thread is currently using this renderer. * 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. * \brief Get the layer renderer for a given layer.
@ -46,7 +48,7 @@ public:
* *
* Return true if the light was altered. * 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: private:
SoftwareRenderer* parent; SoftwareRenderer* parent;

View file

@ -18,7 +18,7 @@ public:
* This will alter the component and return if the component is still * This will alter the component and return if the component is still
* useful. * useful.
*/ */
bool applyLightFilter(LightComponent &light, const Vector3 &at); virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) = 0;
}; };
} }

View file

@ -42,6 +42,10 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
fluid_medium = new FluidMediumManager(this); fluid_medium = new FluidMediumManager(this);
lighting = new LightingManager(); lighting = new LightingManager();
lighting->registerFilter(terrain_renderer);
lighting->registerFilter(water_renderer);
lighting->registerFilter(clouds_renderer);
this->scenery = new Scenery; this->scenery = new Scenery;
if (scenery) if (scenery)
{ {
@ -54,15 +58,15 @@ SoftwareRenderer::~SoftwareRenderer()
delete render_camera; delete render_camera;
delete render_area; delete render_area;
delete fluid_medium;
delete lighting;
delete atmosphere_renderer; delete atmosphere_renderer;
delete clouds_renderer; delete clouds_renderer;
delete terrain_renderer; delete terrain_renderer;
delete textures_renderer; delete textures_renderer;
delete water_renderer; delete water_renderer;
delete fluid_medium;
delete lighting;
delete scenery; delete scenery;
} }
@ -76,6 +80,7 @@ void SoftwareRenderer::prepare()
scenery->getCamera()->copy(render_camera); scenery->getCamera()->copy(render_camera);
// Prepare sub renderers // Prepare sub renderers
// TODO Don't recreate the renderer each time
delete atmosphere_renderer; delete atmosphere_renderer;
if (getScenery()->getAtmosphere()->model == AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON) if (getScenery()->getAtmosphere()->model == AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON)
{ {
@ -86,18 +91,10 @@ void SoftwareRenderer::prepare()
atmosphere_renderer = new BaseAtmosphereRenderer(this); atmosphere_renderer = new BaseAtmosphereRenderer(this);
} }
delete clouds_renderer;
clouds_renderer = new CloudsRenderer(this);
clouds_renderer->update(); clouds_renderer->update();
terrain_renderer->update();
delete terrain_renderer; water_renderer->update();
terrain_renderer = new TerrainRenderer(this); textures_renderer->update();
delete textures_renderer;
textures_renderer = new TexturesRenderer(this);
delete water_renderer;
water_renderer = new WaterRenderer(this);
// Prepare global tools // Prepare global tools
fluid_medium->clearMedia(); fluid_medium->clearMedia();

View file

@ -15,6 +15,10 @@ TerrainRenderer::~TerrainRenderer()
{ {
} }
void TerrainRenderer::update()
{
}
double TerrainRenderer::getHeight(double x, double z, int with_painting) double TerrainRenderer::getHeight(double x, double z, int with_painting)
{ {
return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, 1, 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; return result;
} }
int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location) bool TerrainRenderer::applyLightFilter(LightComponent &light, const Vector3 &at)
{ {
TerrainDefinition* definition = parent->getScenery()->getTerrain(); TerrainDefinition* definition = parent->getScenery()->getTerrain();
Vector3 inc_vector, direction_to_light, cursor; Vector3 inc_vector, direction_to_light, cursor;
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; 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) if (direction_to_light.y < -0.05)
{ {
light->color = COLOR_BLACK; light.color = COLOR_BLACK;
return 1; return false;
} }
else if (direction_to_light.y < 0.0000) else if (direction_to_light.y < 0.0000)
{ {
light->color.r *= (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.g *= (0.05 + direction_to_light.y) / 0.05;
light->color.b *= (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_factor = (double)parent->render_quality;
inc_base = definition->height / definition->scaling; inc_base = definition->height / definition->scaling;
inc_value = inc_base / inc_factor; 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); inc_vector = direction_to_light.scale(inc_value);
length += inc_vector.getNorm(); length += inc_vector.getNorm();
cursor = cursor.add(inc_vector); cursor = cursor.add(inc_vector);
height = parent->getTerrainRenderer()->getResult(location.x, location.z, 1, 1).location.y; height = parent->getTerrainRenderer()->getResult(cursor.x, cursor.z, 1, 1).location.y;
diff = location.y - height; diff = cursor.y - height;
if (diff < 0.0) if (diff < 0.0)
{ {
if (length * smoothing > 0.000001) if (length * smoothing > 0.000001)
@ -242,20 +246,20 @@ int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location)
inc_value = diff; 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) if (light_factor <= 0.0)
{ {
light->color = COLOR_BLACK; light.color = COLOR_BLACK;
return 1; return false;
} }
else else
{ {
light->color.r *= light_factor; light.color.r *= light_factor;
light->color.g *= light_factor; light.color.g *= light_factor;
light->color.b *= light_factor; light.color.b *= light_factor;
return 1; return true;
} }
} }

View file

@ -3,13 +3,15 @@
#include "software_global.h" #include "software_global.h"
#include "LightFilter.h"
#include "RayCastingManager.h" #include "RayCastingManager.h"
#include "Color.h" #include "Color.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
class SOFTWARESHARED_EXPORT TerrainRenderer class SOFTWARESHARED_EXPORT TerrainRenderer: public LightFilter
{ {
public: public:
typedef struct typedef struct
@ -22,12 +24,14 @@ public:
TerrainRenderer(SoftwareRenderer* parent); TerrainRenderer(SoftwareRenderer* parent);
virtual ~TerrainRenderer(); virtual ~TerrainRenderer();
virtual void update();
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction); virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
virtual double getHeight(double x, double z, int with_painting); virtual double getHeight(double x, double z, int with_painting);
virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures); virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures);
virtual Color getFinalColor(const Vector3 &location, double precision); virtual Color getFinalColor(const Vector3 &location, double precision);
virtual double getWaterHeight(); virtual double getWaterHeight();
virtual int alterLight(LightComponent *light, const Vector3 &location); virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
private: private:
SoftwareRenderer* parent; SoftwareRenderer* parent;

View file

@ -16,6 +16,10 @@ TexturesRenderer::~TexturesRenderer()
{ {
} }
void TexturesRenderer::update()
{
}
/* /*
* Get the base presence factor of a layer, not accounting for other layers. * Get the base presence factor of a layer, not accounting for other layers.
*/ */

View file

@ -34,6 +34,8 @@ public:
TexturesRenderer(SoftwareRenderer *parent); TexturesRenderer(SoftwareRenderer *parent);
virtual ~TexturesRenderer(); virtual ~TexturesRenderer();
virtual void update();
virtual double getMaximalDisplacement(TexturesDefinition *textures); virtual double getMaximalDisplacement(TexturesDefinition *textures);
virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain); virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain);
virtual double getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal); virtual double getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal);

View file

@ -17,6 +17,10 @@ WaterRenderer::~WaterRenderer()
{ {
} }
void WaterRenderer::update()
{
}
static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z) static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z)
{ {
return base_height + definition->_waves_noise->get2DTotal(x, z); return base_height + definition->_waves_noise->get2DTotal(x, z);
@ -135,43 +139,6 @@ static inline Color _getFoamMask(SoftwareRenderer* renderer, WaterDefinition* de
return result; 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() HeightInfo WaterRenderer::getHeightInfo()
{ {
WaterDefinition* definition = parent->getScenery()->getWater(); WaterDefinition* definition = parent->getScenery()->getWater();
@ -270,3 +237,40 @@ WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z)
return result; 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;
}
}

View file

@ -3,6 +3,8 @@
#include "software_global.h" #include "software_global.h"
#include "LightFilter.h"
#include "TerrainDefinition.h" #include "TerrainDefinition.h"
#include "Vector3.h" #include "Vector3.h"
#include "Color.h" #include "Color.h"
@ -10,7 +12,7 @@
namespace paysages { namespace paysages {
namespace software { namespace software {
class SOFTWARESHARED_EXPORT WaterRenderer class SOFTWARESHARED_EXPORT WaterRenderer:public LightFilter
{ {
public: public:
typedef struct typedef struct
@ -27,10 +29,12 @@ public:
WaterRenderer(SoftwareRenderer* parent); WaterRenderer(SoftwareRenderer* parent);
virtual ~WaterRenderer(); virtual ~WaterRenderer();
virtual void update();
virtual HeightInfo getHeightInfo(); virtual HeightInfo getHeightInfo();
virtual double getHeight(double x, double z); virtual double getHeight(double x, double z);
virtual WaterResult getResult(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: private:
SoftwareRenderer* parent; SoftwareRenderer* parent;