From 6589589ad42bb1398d6a0452886cb8b7466a5628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 15:36:15 +0100 Subject: [PATCH 1/6] Added basic night sky with a plain moon --- .../software/AtmosphereModelBruneton.cpp | 4 +- src/render/software/AtmosphereRenderer.cpp | 9 ++-- src/render/software/NightSky.cpp | 53 +++++++++++++++++++ src/render/software/NightSky.h | 36 +++++++++++++ src/render/software/SoftwareRenderer.cpp | 7 +++ src/render/software/SoftwareRenderer.h | 3 ++ src/render/software/software.pro | 6 ++- src/render/software/software_global.h | 2 + 8 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 src/render/software/NightSky.cpp create mode 100644 src/render/software/NightSky.h diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index ccaed98..1a21ad5 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -1154,7 +1154,7 @@ AtmosphereModelBruneton::AtmosphereModelBruneton(SoftwareRenderer *parent): { } -AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &) +AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base) { double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height; eye.y += yoffset; @@ -1177,7 +1177,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 /*result.base.r = base.r + sunColor.r; result.base.g = base.g + sunColor.g; result.base.b = base.b + sunColor.b;*/ - result.base = sunColor; + result.base = base.add(sunColor); result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */ /* TODO Use atmosphere attenuation */ result.distance = SPHERE_SIZE; diff --git a/src/render/software/AtmosphereRenderer.cpp b/src/render/software/AtmosphereRenderer.cpp index 5b79eba..7ce14ad 100644 --- a/src/render/software/AtmosphereRenderer.cpp +++ b/src/render/software/AtmosphereRenderer.cpp @@ -8,6 +8,7 @@ #include "LightComponent.h" #include "LightStatus.h" #include "Scenery.h" +#include "NightSky.h" /* Factor to convert software units to kilometers */ #define WORLD_SCALING 0.05 @@ -207,8 +208,12 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi direction = direction.normalize(); sun_position = sun_direction.scale(SUN_DISTANCE_SCALED); - /* Get sun shape */ base = COLOR_BLACK; + + /* Get night sky */ + base = base.add(parent->getNightSky()->getColor(camera_location.y, direction)); + + /* Get sun shape */ /*if (v3Dot(sun_direction, direction) >= 0) { double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED * 5.0; // FIXME Why should we multiply by 5 ? @@ -233,8 +238,6 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi } }*/ - /* TODO Get stars */ - /* Get scattering */ AtmosphereResult result; Vector3 location = camera_location.add(direction.scale(6421.0)); diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp new file mode 100644 index 0000000..a8bfa72 --- /dev/null +++ b/src/render/software/NightSky.cpp @@ -0,0 +1,53 @@ +#include "NightSky.h" + +#include "Color.h" +#include "Vector3.h" +#include "Geometry.h" + +NightSky::NightSky(SoftwareRenderer* renderer): + renderer(renderer) +{ +} + +NightSky::~NightSky() +{ +} + +void NightSky::update() +{ +} + +const Color NightSky::getColor(double altitude, const Vector3 &direction) +{ + Color result(0.01, 0.012, 0.03); + + Vector3 location(0.0, altitude, 0.0); + + // Get stars + + // Get moon + Vector3 moon_direction(0.3, 0.4, -0.3); + moon_direction.normalize(); + if (moon_direction.dotProduct(direction) >= 0) + { + Vector3 moon_position = moon_direction.scale(100.0); + double moon_radius = 1.0; + Vector3 hit1, hit2; + int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2); + if (hits > 1) + { + double dist = hit2.sub(hit1).getNorm() / moon_radius; // distance between intersection points (relative to radius) + + Color moon_color(0.3, 0.3, 0.3); + if (dist <= 0.05) + { + moon_color.a *= 1.0 - dist / 0.05; + } + result.mask(moon_color); + } + } + + + return result; + +} diff --git a/src/render/software/NightSky.h b/src/render/software/NightSky.h new file mode 100644 index 0000000..428f033 --- /dev/null +++ b/src/render/software/NightSky.h @@ -0,0 +1,36 @@ +#ifndef NIGHTSKY_H +#define NIGHTSKY_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/*! + * \brief Night sky renderer. + */ +class SOFTWARESHARED_EXPORT NightSky +{ +public: + NightSky(SoftwareRenderer* renderer); + virtual ~NightSky(); + + /*! + * \brief Update the night sky renderer, when the scenery or parent renderer changed. + */ + void update(); + + /*! + * \brief Get the color of the night sky at a given direction. + * \param altitude Altitude above water level, in coordinate units (not kilometers). + */ + virtual const Color getColor(double altitude, const Vector3 &direction); + +private: + SoftwareRenderer* renderer; +}; + +} +} + +#endif // NIGHTSKY_H diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index c0d8882..a876c83 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -14,6 +14,7 @@ #include "SkyRasterizer.h" #include "TerrainRasterizer.h" #include "WaterRasterizer.h" +#include "NightSky.h" #include "LightStatus.h" #include "LightingManager.h" #include "System.h" @@ -39,6 +40,8 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery) textures_renderer = new TexturesRenderer(this); water_renderer = new WaterRenderer(this); + nightsky_renderer = new NightSky(this); + fluid_medium = new FluidMediumManager(this); lighting = new LightingManager(); @@ -61,6 +64,8 @@ SoftwareRenderer::~SoftwareRenderer() delete fluid_medium; delete lighting; + delete nightsky_renderer; + delete atmosphere_renderer; delete clouds_renderer; delete terrain_renderer; @@ -96,6 +101,8 @@ void SoftwareRenderer::prepare() water_renderer->update(); textures_renderer->update(); + nightsky_renderer->update(); + // Prepare global tools fluid_medium->clearMedia(); //fluid_medium->registerMedium(water_renderer); diff --git a/src/render/software/SoftwareRenderer.h b/src/render/software/SoftwareRenderer.h index 4894949..9f269f3 100644 --- a/src/render/software/SoftwareRenderer.h +++ b/src/render/software/SoftwareRenderer.h @@ -90,6 +90,8 @@ public: inline TexturesRenderer* getTexturesRenderer() const {return textures_renderer;} inline WaterRenderer* getWaterRenderer() const {return water_renderer;} + inline NightSky* getNightSky() const {return nightsky_renderer;} + inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;} inline LightingManager* getLightingManager() const {return lighting;} @@ -108,6 +110,7 @@ private: TerrainRenderer* terrain_renderer; TexturesRenderer* textures_renderer; WaterRenderer* water_renderer; + NightSky* nightsky_renderer; }; } diff --git a/src/render/software/software.pro b/src/render/software/software.pro index 070ad32..f00ec48 100644 --- a/src/render/software/software.pro +++ b/src/render/software/software.pro @@ -35,7 +35,8 @@ SOURCES += SoftwareRenderer.cpp \ TexturesRenderer.cpp \ WaterRenderer.cpp \ RenderArea.cpp \ - RayCastingManager.cpp + RayCastingManager.cpp \ + NightSky.cpp HEADERS += SoftwareRenderer.h\ software_global.h \ @@ -60,7 +61,8 @@ HEADERS += SoftwareRenderer.h\ TexturesRenderer.h \ WaterRenderer.h \ RenderArea.h \ - RayCastingManager.h + RayCastingManager.h \ + NightSky.h unix:!symbian { maemo5 { diff --git a/src/render/software/software_global.h b/src/render/software/software_global.h index f14bf27..a7f2c68 100644 --- a/src/render/software/software_global.h +++ b/src/render/software/software_global.h @@ -40,6 +40,8 @@ namespace software { class LightStatus; class LightFilter; class LightComponent; + + class NightSky; } } From d2f49a124fae47ee75ceb8a1511674d2522f78b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 16:35:29 +0100 Subject: [PATCH 2/6] Added moon basic lighting --- .../software/AtmosphereModelBruneton.cpp | 9 +++++++- src/render/software/NightSky.cpp | 21 ++++++++++++++----- src/render/software/TerrainRenderer.cpp | 6 ++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index 1a21ad5..330e155 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -1254,7 +1254,14 @@ void AtmosphereModelBruneton::fillLightingStatus(LightStatus *status, const Vect Vector3 s = sun_position.sub(x).normalize(); muS = up.dotProduct(s); - sun.color = _transmittanceWithShadow(r0, muS); + if (altitude * WORLD_SCALING > RL) + { + sun.color = parent->getScenery()->getAtmosphere()->sun_color; + } + else + { + sun.color = _transmittanceWithShadow(r0, muS); + } sun.direction = s.scale(-1.0); sun.reflection = ISun; sun.altered = 1; diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index a8bfa72..8376ab5 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -3,6 +3,14 @@ #include "Color.h" #include "Vector3.h" #include "Geometry.h" +#include "SoftwareRenderer.h" +#include "SurfaceMaterial.h" + +#define WORLD_SCALING 0.05 +#define MOON_DISTANCE 384403.0 +#define MOON_DISTANCE_SCALED (MOON_DISTANCE / WORLD_SCALING) +#define MOON_RADIUS 1737.4 +#define MOON_RADIUS_SCALED (MOON_RADIUS / WORLD_SCALING) NightSky::NightSky(SoftwareRenderer* renderer): renderer(renderer) @@ -26,19 +34,22 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) // Get stars // Get moon - Vector3 moon_direction(0.3, 0.4, -0.3); - moon_direction.normalize(); + Vector3 moon_direction = Vector3(0.9, 0.5, -0.6).normalize(); if (moon_direction.dotProduct(direction) >= 0) { - Vector3 moon_position = moon_direction.scale(100.0); - double moon_radius = 1.0; + Vector3 moon_position = moon_direction.scale(MOON_DISTANCE_SCALED); + double moon_radius = MOON_RADIUS_SCALED * 5.0; Vector3 hit1, hit2; int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2); if (hits > 1) { double dist = hit2.sub(hit1).getNorm() / moon_radius; // distance between intersection points (relative to radius) - Color moon_color(0.3, 0.3, 0.3); + Vector3 nearest = (hit1.sub(location).getNorm() > hit2.sub(location).getNorm()) ? hit2 : hit1; + SurfaceMaterial moon_material(Color(3.0, 3.0, 3.0, 1.0)); + moon_material.validate(); + + Color moon_color = renderer->applyLightingToSurface(nearest, nearest.sub(moon_position).normalize(), moon_material); if (dist <= 0.05) { moon_color.a *= 1.0 - dist / 0.05; diff --git a/src/render/software/TerrainRenderer.cpp b/src/render/software/TerrainRenderer.cpp index cd55247..66ad070 100644 --- a/src/render/software/TerrainRenderer.cpp +++ b/src/render/software/TerrainRenderer.cpp @@ -192,6 +192,12 @@ bool TerrainRenderer::applyLightFilter(LightComponent &light, const Vector3 &at) Vector3 inc_vector, direction_to_light, cursor; double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; + if (at.y > definition->getHeightInfo().max_height) + { + // Location is above terrain, don't bother + return true; + } + direction_to_light = light.direction.scale(-1.0); if (direction_to_light.y < -0.05) { From c651b436ab816335a5fee76ca890dce64d795666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 16:55:37 +0100 Subject: [PATCH 3/6] Added moon configuration --- src/definition/AtmosphereDefinition.cpp | 12 ++++++++++++ src/definition/AtmosphereDefinition.h | 4 ++++ src/interface/desktop/formatmosphere.cpp | 3 +++ src/render/software/NightSky.cpp | 10 +++++++--- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp index c6dc88f..50c22d9 100644 --- a/src/definition/AtmosphereDefinition.cpp +++ b/src/definition/AtmosphereDefinition.cpp @@ -20,6 +20,9 @@ void AtmosphereDefinition::save(PackStream* stream) const stream->write(&sun_radius); stream->write(&dome_lighting); stream->write(&humidity); + stream->write(&moon_radius); + stream->write(&moon_theta); + stream->write(&moon_phi); } void AtmosphereDefinition::load(PackStream* stream) @@ -31,6 +34,9 @@ void AtmosphereDefinition::load(PackStream* stream) stream->read(&sun_radius); stream->read(&dome_lighting); stream->read(&humidity); + stream->read(&moon_radius); + stream->read(&moon_theta); + stream->read(&moon_phi); validate(); } @@ -46,6 +52,9 @@ void AtmosphereDefinition::copy(BaseDefinition* _destination) const destination->sun_radius = sun_radius; destination->dome_lighting = dome_lighting; destination->humidity = humidity; + destination->moon_radius = moon_radius; + destination->moon_theta = moon_theta; + destination->moon_phi = moon_phi; destination->validate(); } @@ -79,6 +88,9 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) sun_color.b = 0.9; sun_color.a = 1.0; sun_radius = 1.0; + moon_radius = 1.0; + moon_theta = 0.3; + moon_phi = 0.5; humidity = 0.1; model = ATMOSPHERE_MODEL_BRUNETON; diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h index ae3a635..19d1a0b 100644 --- a/src/definition/AtmosphereDefinition.h +++ b/src/definition/AtmosphereDefinition.h @@ -48,6 +48,10 @@ public: double sun_radius; double dome_lighting; + double moon_radius; + double moon_theta; + double moon_phi; + double _daytime; }; diff --git a/src/interface/desktop/formatmosphere.cpp b/src/interface/desktop/formatmosphere.cpp index 6a1519f..37abd33 100644 --- a/src/interface/desktop/formatmosphere.cpp +++ b/src/interface/desktop/formatmosphere.cpp @@ -42,6 +42,9 @@ FormAtmosphere::FormAtmosphere(QWidget *parent): addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 5.0, 0.05, 0.5); //addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1); addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1); + addInputDouble(tr("Moon radius"), &_definition->moon_radius, 0.5, 3.0, 0.03, 0.3); + addInputDouble(tr("Moon location (horizontal)"), &_definition->moon_phi, 0.0, M_PI * 2.0, 0.05, 0.5); + addInputDouble(tr("Moon location (vertical)"), &_definition->moon_theta, -0.1, M_PI * 0.5, 0.02, 0.2); revertConfig(); } diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index 8376ab5..dc6cd3e 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -4,6 +4,8 @@ #include "Vector3.h" #include "Geometry.h" #include "SoftwareRenderer.h" +#include "Scenery.h" +#include "AtmosphereDefinition.h" #include "SurfaceMaterial.h" #define WORLD_SCALING 0.05 @@ -27,6 +29,7 @@ void NightSky::update() const Color NightSky::getColor(double altitude, const Vector3 &direction) { + AtmosphereDefinition* atmosphere = renderer->getScenery()->getAtmosphere(); Color result(0.01, 0.012, 0.03); Vector3 location(0.0, altitude, 0.0); @@ -34,11 +37,12 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) // Get stars // Get moon - Vector3 moon_direction = Vector3(0.9, 0.5, -0.6).normalize(); + VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi}; + Vector3 moon_position(moon_location_s); + Vector3 moon_direction = moon_position.normalize(); if (moon_direction.dotProduct(direction) >= 0) { - Vector3 moon_position = moon_direction.scale(MOON_DISTANCE_SCALED); - double moon_radius = MOON_RADIUS_SCALED * 5.0; + double moon_radius = MOON_RADIUS_SCALED * 5.0 * atmosphere->moon_radius; Vector3 hit1, hit2; int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2); if (hits > 1) From 3786b21e1574dd546c0fe15860c935603cb2fdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 17:30:22 +0100 Subject: [PATCH 4/6] Added stars to night sky --- src/definition/AtmosphereDefinition.cpp | 48 +++++++++++++++++++++++++ src/definition/AtmosphereDefinition.h | 12 +++++++ src/render/software/NightSky.cpp | 20 +++++++++++ 3 files changed, 80 insertions(+) diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp index 50c22d9..d1fd3c5 100644 --- a/src/definition/AtmosphereDefinition.cpp +++ b/src/definition/AtmosphereDefinition.cpp @@ -1,6 +1,7 @@ #include "AtmosphereDefinition.h" #include "PackStream.h" +#include "RandomGenerator.h" AtmosphereDefinition::AtmosphereDefinition(BaseDefinition* parent): BaseDefinition(parent) @@ -23,6 +24,15 @@ void AtmosphereDefinition::save(PackStream* stream) const stream->write(&moon_radius); stream->write(&moon_theta); stream->write(&moon_phi); + + int star_count = stars.size(); + stream->write(&star_count); + for (const auto &star : stars) + { + star.location.save(stream); + star.col.save(stream); + stream->write(&star.radius); + } } void AtmosphereDefinition::load(PackStream* stream) @@ -38,6 +48,19 @@ void AtmosphereDefinition::load(PackStream* stream) stream->read(&moon_theta); stream->read(&moon_phi); + int star_count; + stream->read(&star_count); + for (int i = 0; i < star_count; i++) + { + Star star; + + star.location.load(stream); + star.col.load(stream); + stream->read(&star.radius); + + stars.push_back(star); + } + validate(); } @@ -55,6 +78,7 @@ void AtmosphereDefinition::copy(BaseDefinition* _destination) const destination->moon_radius = moon_radius; destination->moon_theta = moon_theta; destination->moon_phi = moon_phi; + destination->stars = stars; destination->validate(); } @@ -130,5 +154,29 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) ; } + generateStars(5000); + validate(); } + +void AtmosphereDefinition::generateStars(int count) +{ + stars.clear(); + + for (int i = 0; i < count; ++i) + { + Star star; + + star.location = Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() - 0.5) * 100000.0); + if (star.location.getNorm() < 30000.0) + { + i--; + continue; + } + double brillance = RandomGenerator::random() * 0.05 + 0.1; + star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, 1.0); + star.radius = 30.0 + RandomGenerator::random() * 20.0; + + stars.push_back(star); + } +} diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h index 19d1a0b..39d4838 100644 --- a/src/definition/AtmosphereDefinition.h +++ b/src/definition/AtmosphereDefinition.h @@ -5,6 +5,7 @@ #include "BaseDefinition.h" +#include "Vector3.h" #include "Color.h" namespace paysages { @@ -12,6 +13,14 @@ namespace definition { class AtmosphereDefinition : public BaseDefinition { +public: + typedef struct + { + Vector3 location; + double radius; + Color col; + } Star; + public: typedef enum { @@ -38,6 +47,7 @@ public: virtual void validate() override; void applyPreset(AtmospherePreset preset); + void generateStars(int count); public: AtmosphereModel model; @@ -53,6 +63,8 @@ public: double moon_phi; double _daytime; + + std::vector stars; }; } diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index dc6cd3e..1ba1a7b 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -35,6 +35,26 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) Vector3 location(0.0, altitude, 0.0); // Get stars + for (const auto &star: atmosphere->stars) + { + if (star.location.dotProduct(direction) >= 0) + { + double radius = star.radius; + Vector3 hit1, hit2; + int hits = Geometry::rayIntersectSphere(location, direction, star.location, radius, &hit1, &hit2); + if (hits > 1) + { + double dist = hit2.sub(hit1).getNorm() / radius; // distance between intersection points (relative to radius) + + Color color = star.col; + if (dist <= 0.5) + { + color.a *= 1.0 - dist / 0.5; + } + result.mask(color); + } + } + } // Get moon VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi}; From 0e837f00c66f93b24ff7f0dd6f76e624a8c841b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 18:28:25 +0100 Subject: [PATCH 5/6] Added lighting done by moon --- src/render/software/AtmosphereRenderer.cpp | 3 ++- src/render/software/NightSky.cpp | 17 +++++++++++++++++ src/render/software/NightSky.h | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/render/software/AtmosphereRenderer.cpp b/src/render/software/AtmosphereRenderer.cpp index 7ce14ad..49e8d5f 100644 --- a/src/render/software/AtmosphereRenderer.cpp +++ b/src/render/software/AtmosphereRenderer.cpp @@ -171,7 +171,8 @@ SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer() void SoftwareBrunetonAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3 normal, int opaque) { - return model->fillLightingStatus(status, normal, opaque); + model->fillLightingStatus(status, normal, opaque); + parent->getNightSky()->fillLightingStatus(status, normal, opaque); } AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base) diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index 1ba1a7b..4a8e2b2 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -7,6 +7,8 @@ #include "Scenery.h" #include "AtmosphereDefinition.h" #include "SurfaceMaterial.h" +#include "LightComponent.h" +#include "LightStatus.h" #define WORLD_SCALING 0.05 #define MOON_DISTANCE 384403.0 @@ -86,3 +88,18 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) return result; } + +void NightSky::fillLightingStatus(LightStatus *status, const Vector3 &, int) +{ + LightComponent moon; + + AtmosphereDefinition* atmosphere = renderer->getScenery()->getAtmosphere(); + VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi}; + + moon.color = Color(0.03, 0.03, 0.03); // TODO take moon phase into account + moon.direction = Vector3(moon_location_s).normalize().scale(-1.0); + moon.reflection = 0.2; + moon.altered = 1; + + status->pushComponent(moon); +} diff --git a/src/render/software/NightSky.h b/src/render/software/NightSky.h index 428f033..c1bc3c5 100644 --- a/src/render/software/NightSky.h +++ b/src/render/software/NightSky.h @@ -26,6 +26,8 @@ public: */ virtual const Color getColor(double altitude, const Vector3 &direction); + virtual void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque); + private: SoftwareRenderer* renderer; }; From 938242a7de2a4cf4b209f9c532c53ad75f0d2fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 26 Dec 2013 19:03:19 +0100 Subject: [PATCH 6/6] Optimization for moon lighting --- src/render/opengl/OpenGLRenderer.cpp | 2 +- src/render/opengl/shaders/skybox.frag | 4 +++- src/render/opengl/shaders/tonemapping.frag | 20 +++++++++++--------- src/render/software/LightStatus.cpp | 12 ++++++++++++ src/render/software/LightStatus.h | 1 + src/render/software/NightSky.cpp | 11 +++++++++-- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/render/opengl/OpenGLRenderer.cpp b/src/render/opengl/OpenGLRenderer.cpp index e86ef48..7df1940 100644 --- a/src/render/opengl/OpenGLRenderer.cpp +++ b/src/render/opengl/OpenGLRenderer.cpp @@ -21,7 +21,7 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery): shared_state = new OpenGLSharedState(); shared_state->set("viewDistance", 300.0); - shared_state->set("exposure", 1.6); + shared_state->set("exposure", 1.2); skybox = new OpenGLSkybox(this); water = new OpenGLWater(this); diff --git a/src/render/opengl/shaders/skybox.frag b/src/render/opengl/shaders/skybox.frag index 8acc7da..604677b 100644 --- a/src/render/opengl/shaders/skybox.frag +++ b/src/render/opengl/shaders/skybox.frag @@ -15,5 +15,7 @@ void main(void) vec3 attenuation; vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation); - gl_FragColor = applyToneMapping(sunTransmittance + vec4(inscattering, 0.0)); + gl_FragColor = vec4(0.01, 0.012, 0.03, 1.0); // night sky + gl_FragColor += sunTransmittance + vec4(inscattering, 0.0); + gl_FragColor = applyToneMapping(gl_FragColor); } diff --git a/src/render/opengl/shaders/tonemapping.frag b/src/render/opengl/shaders/tonemapping.frag index 2ea09af..5614cab 100644 --- a/src/render/opengl/shaders/tonemapping.frag +++ b/src/render/opengl/shaders/tonemapping.frag @@ -12,21 +12,23 @@ float _uncharted2Tonemap(float x) return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; } -vec4 applyToneMapping(vec4 color) -{ - return vec4(((color * exposure) / (1.0 + color * exposure)).rgb, 1.0); -} - /*vec4 applyToneMapping(vec4 color) { + float e = mix(exposure, exposure * 3.0, clamp(-sunDirection.y * 10.0, 0.0, 1.0)); + return vec4(((color * e) / (1.0 + color * e)).rgb, 1.0); +}*/ + +vec4 applyToneMapping(vec4 color) +{ + float e = mix(exposure, exposure * 3.0, clamp(-sunDirection.y * 10.0, 0.0, 1.0)); float W = 11.2; float white_scale = 1.0 / _uncharted2Tonemap(W); vec4 result; - result.r = pow(_uncharted2Tonemap(color.r * exposure) * white_scale, 1.0 / 2.2); - result.g = pow(_uncharted2Tonemap(color.g * exposure) * white_scale, 1.0 / 2.2); - result.b = pow(_uncharted2Tonemap(color.b * exposure) * white_scale, 1.0 / 2.2); + result.r = pow(_uncharted2Tonemap(color.r * e) * white_scale, 1.0 / 2.2); + result.g = pow(_uncharted2Tonemap(color.g * e) * white_scale, 1.0 / 2.2); + result.b = pow(_uncharted2Tonemap(color.b * e) * white_scale, 1.0 / 2.2); result.a = 1.0; return result; -}*/ +} diff --git a/src/render/software/LightStatus.cpp b/src/render/software/LightStatus.cpp index a424267..ae26119 100644 --- a/src/render/software/LightStatus.cpp +++ b/src/render/software/LightStatus.cpp @@ -6,6 +6,7 @@ LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye) { + this->max_power = 0.0; this->manager = manager; this->location = location; this->eye = eye; @@ -13,8 +14,19 @@ LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, cons void LightStatus::pushComponent(LightComponent component) { + double power = component.color.getPower(); + if (component.altered && (power < max_power * 0.05 || power < 0.001)) + { + // Exclude filtered lights that are owerpowered by a previous one + return; + } + if (manager->alterLight(component, location)) { + if (power > max_power) + { + max_power = power; + } components.push_back(component); } } diff --git a/src/render/software/LightStatus.h b/src/render/software/LightStatus.h index 048bd31..947ee8a 100644 --- a/src/render/software/LightStatus.h +++ b/src/render/software/LightStatus.h @@ -25,6 +25,7 @@ public: Color apply(const Vector3 &normal, const SurfaceMaterial &material); private: + double max_power; LightingManager* manager; Vector3 location; Vector3 eye; diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index 4a8e2b2..b8c1cdb 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -72,7 +72,7 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) double dist = hit2.sub(hit1).getNorm() / moon_radius; // distance between intersection points (relative to radius) Vector3 nearest = (hit1.sub(location).getNorm() > hit2.sub(location).getNorm()) ? hit2 : hit1; - SurfaceMaterial moon_material(Color(3.0, 3.0, 3.0, 1.0)); + SurfaceMaterial moon_material(Color(3.0, 3.0, 3.0)); moon_material.validate(); Color moon_color = renderer->applyLightingToSurface(nearest, nearest.sub(moon_position).normalize(), moon_material); @@ -91,7 +91,7 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) void NightSky::fillLightingStatus(LightStatus *status, const Vector3 &, int) { - LightComponent moon; + LightComponent moon, sky; AtmosphereDefinition* atmosphere = renderer->getScenery()->getAtmosphere(); VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi}; @@ -102,4 +102,11 @@ void NightSky::fillLightingStatus(LightStatus *status, const Vector3 &, int) moon.altered = 1; status->pushComponent(moon); + + sky.color = Color(0.01, 0.012, 0.03); + sky.direction = VECTOR_DOWN; + sky.reflection = 0.0; + sky.altered = 0; + + status->pushComponent(sky); }