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;
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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
};
}

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;

View file

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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;