diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp index cd7935f..e96c8cd 100644 --- a/src/definition/AtmosphereDefinition.cpp +++ b/src/definition/AtmosphereDefinition.cpp @@ -3,10 +3,12 @@ #include "PackStream.h" #include "RandomGenerator.h" #include "FloatNode.h" +#include "GodRaysDefinition.h" AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent): DefinitionNode(parent, "atmosphere", "atmosphere") { + godrays = new GodRaysDefinition(this); daytime = new FloatNode(this, "daytime"); humidity = new FloatNode(this, "humidity"); sun_radius = new FloatNode(this, "sun_radius"); diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h index 0d61340..20f43ee 100644 --- a/src/definition/AtmosphereDefinition.h +++ b/src/definition/AtmosphereDefinition.h @@ -45,6 +45,7 @@ public: virtual void copy(DefinitionNode* destination) const override; + inline GodRaysDefinition *childGodRays() const {return godrays;} inline FloatNode *propDayTime() const {return daytime;} inline FloatNode *propHumidity() const {return humidity;} inline FloatNode *propSunRadius() const {return sun_radius;} @@ -78,6 +79,7 @@ public: std::vector stars; private: + GodRaysDefinition *godrays; FloatNode *humidity; FloatNode *daytime; FloatNode *sun_radius; diff --git a/src/definition/GodRaysDefinition.cpp b/src/definition/GodRaysDefinition.cpp new file mode 100644 index 0000000..94ec938 --- /dev/null +++ b/src/definition/GodRaysDefinition.cpp @@ -0,0 +1,12 @@ +#include "GodRaysDefinition.h" + +#include "FloatNode.h" + +GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent): + DefinitionNode(parent, "godrays", "godrays") +{ + penetration = new FloatNode(this, "penetration", 0.01); + resistance = new FloatNode(this, "resistance", 0.3); + boost = new FloatNode(this, "boost", 8.0); +} + diff --git a/src/definition/GodRaysDefinition.h b/src/definition/GodRaysDefinition.h new file mode 100644 index 0000000..52775ec --- /dev/null +++ b/src/definition/GodRaysDefinition.h @@ -0,0 +1,29 @@ +#ifndef GODRAYSDEFINITION_H +#define GODRAYSDEFINITION_H + +#include "definition_global.h" + +#include "DefinitionNode.h" + +namespace paysages { +namespace definition { + +class DEFINITIONSHARED_EXPORT GodRaysDefinition: public DefinitionNode +{ +public: + GodRaysDefinition(DefinitionNode *parent); + + inline FloatNode *propPenetration() const {return penetration;} + inline FloatNode *propResistance() const {return resistance;} + inline FloatNode *propBoost() const {return boost;} + +private: + FloatNode *penetration; + FloatNode *resistance; + FloatNode *boost; +}; + +} +} + +#endif // GODRAYSDEFINITION_H diff --git a/src/definition/definition.pro b/src/definition/definition.pro index 7105ccf..c831134 100644 --- a/src/definition/definition.pro +++ b/src/definition/definition.pro @@ -37,7 +37,8 @@ SOURCES += \ DiffManager.cpp \ DefinitionWatcher.cpp \ IntNode.cpp \ - IntDiff.cpp + IntDiff.cpp \ + GodRaysDefinition.cpp HEADERS +=\ definition_global.h \ @@ -64,7 +65,8 @@ HEADERS +=\ DiffManager.h \ DefinitionWatcher.h \ IntNode.h \ - IntDiff.h + IntDiff.h \ + GodRaysDefinition.h unix:!symbian { maemo5 { diff --git a/src/definition/definition_global.h b/src/definition/definition_global.h index 9f2d446..e2e6903 100644 --- a/src/definition/definition_global.h +++ b/src/definition/definition_global.h @@ -30,6 +30,7 @@ namespace definition { class CloudsDefinition; class CloudLayerDefinition; class AtmosphereDefinition; + class GodRaysDefinition; class TexturesDefinition; class TextureLayerDefinition; class TerrainDefinition; diff --git a/src/interface/commandline/tests.cpp b/src/interface/commandline/tests.cpp index c71702f..6260484 100644 --- a/src/interface/commandline/tests.cpp +++ b/src/interface/commandline/tests.cpp @@ -5,6 +5,7 @@ #include "TerrainDefinition.h" #include "AtmosphereDefinition.h" #include "TexturesDefinition.h" +#include "GodRaysDefinition.h" #include "TextureLayerDefinition.h" #include "WaterDefinition.h" #include "SurfaceMaterial.h" @@ -157,11 +158,37 @@ static void testGodRays() TestLightFilter filter; renderer.getLightingManager()->clearFilters(); renderer.getLightingManager()->registerFilter(&filter); + + // quality for (int i = 0; i < 6; i++) { renderer.setQuality((double)i / 5.0); rasterizer->setQuality(0.2); - startTestRender(&renderer, "god_rays", i); + startTestRender(&renderer, "god_rays_quality", i); + } + renderer.setQuality(0.5); + + // penetration + for (int i = 0; i < 3; i++) + { + scenery.getAtmosphere()->childGodRays()->propPenetration()->setValue(0.01 + 0.02 * (double)i); + startTestRender(&renderer, "god_rays_penetration", i); + } + + // resistance + scenery.getAtmosphere()->childGodRays()->propPenetration()->setValue(0.01); + for (int i = 0; i < 3; i++) + { + scenery.getAtmosphere()->childGodRays()->propResistance()->setValue(0.1 + 0.1 * (double)i); + startTestRender(&renderer, "god_rays_resistance", i); + } + + // boost + scenery.getAtmosphere()->childGodRays()->propResistance()->setValue(0.3); + for (int i = 0; i < 3; i++) + { + scenery.getAtmosphere()->childGodRays()->propBoost()->setValue(2.0 + 4.0 * (double)i); + startTestRender(&renderer, "god_rays_boost", i); } } diff --git a/src/render/software/GodRaysResult.cpp b/src/render/software/GodRaysResult.cpp index 27ea188..5a629ae 100644 --- a/src/render/software/GodRaysResult.cpp +++ b/src/render/software/GodRaysResult.cpp @@ -5,7 +5,7 @@ GodRaysResult::GodRaysResult(double inside_length, double full_length): { } -Color GodRaysResult::apply(const Color &raw, const Color &atmosphered) +Color GodRaysResult::apply(const Color &raw, const Color &atmosphered, const GodRaysParams ¶ms) { if (inside_length == 0.0) { @@ -14,14 +14,16 @@ Color GodRaysResult::apply(const Color &raw, const Color &atmosphered) else if (inside_length < full_length) { double diff = full_length - inside_length; - double factor = 1.0 - 0.01 * diff; - if (factor < 0.3) + double factor = 1.0 - params.penetration * diff; + double minimum = params.resistance; + double complement = 1.0 - minimum; + if (factor < minimum) { - factor = 0.3; + factor = minimum; } else { - factor = pow((factor - 0.3) / 0.7, 8.0) * 0.7 + 0.3; + factor = pow((factor - minimum) / complement, params.boost) * complement + minimum; } return Color(raw.r + (atmosphered.r - raw.r) * factor, diff --git a/src/render/software/GodRaysResult.h b/src/render/software/GodRaysResult.h index bc6f952..15102f4 100644 --- a/src/render/software/GodRaysResult.h +++ b/src/render/software/GodRaysResult.h @@ -13,6 +13,13 @@ namespace software { */ class SOFTWARESHARED_EXPORT GodRaysResult { +public: + typedef struct { + double penetration; + double resistance; + double boost; + } GodRaysParams; + public: GodRaysResult() = default; GodRaysResult(double inside_length, double full_length); @@ -20,7 +27,7 @@ public: /** * Apply the result on a base color. */ - Color apply(const Color &raw, const Color &atmosphered); + Color apply(const Color &raw, const Color &atmosphered, const GodRaysParams ¶ms); private: double inside_length; diff --git a/src/render/software/GodRaysSampler.cpp b/src/render/software/GodRaysSampler.cpp index 75ee606..39c6e67 100644 --- a/src/render/software/GodRaysSampler.cpp +++ b/src/render/software/GodRaysSampler.cpp @@ -1,10 +1,13 @@ #include "GodRaysSampler.h" +#include "GodRaysDefinition.h" +#include "AtmosphereDefinition.h" #include "SoftwareRenderer.h" #include "Vector3.h" #include "SpaceSegment.h" #include "GodRaysResult.h" #include "LightingManager.h" +#include "FloatNode.h" #include "LightStatus.h" #include "Scenery.h" #include "TerrainDefinition.h" @@ -16,6 +19,7 @@ GodRaysSampler::GodRaysSampler() { enabled = true; bounds = new SpaceSegment(); + definition = new GodRaysDefinition(NULL); camera_location = new Vector3(0, 0, 0); lighting = NULL; low_altitude = -1.0; @@ -28,6 +32,7 @@ GodRaysSampler::GodRaysSampler() GodRaysSampler::~GodRaysSampler() { + delete definition; delete bounds; delete camera_location; delete[] data; @@ -38,6 +43,7 @@ void GodRaysSampler::prepare(SoftwareRenderer *renderer) setCameraLocation(renderer->getCameraLocation(VECTOR_ZERO)); setLighting(renderer->getLightingManager()); setAltitudes(renderer->getScenery()->getTerrain()->getHeightInfo().min_height, renderer->getCloudsRenderer()->getHighestAltitude()); + renderer->getScenery()->getAtmosphere()->childGodRays()->copy(definition); reset(); } @@ -178,7 +184,13 @@ Color GodRaysSampler::apply(const Color &raw, const Color &atmosphered, const Ve if (enabled) { GodRaysResult result = getResult(SpaceSegment(*camera_location, location)); - return result.apply(raw, atmosphered); + + GodRaysResult::GodRaysParams params; + params.penetration = definition->propPenetration()->getValue(); + params.resistance = definition->propResistance()->getValue(); + params.boost = definition->propBoost()->getValue(); + + return result.apply(raw, atmosphered, params); } else { diff --git a/src/render/software/GodRaysSampler.h b/src/render/software/GodRaysSampler.h index a3e4954..27efc67 100644 --- a/src/render/software/GodRaysSampler.h +++ b/src/render/software/GodRaysSampler.h @@ -99,6 +99,8 @@ private: bool enabled; SpaceSegment *bounds; + GodRaysDefinition *definition; + double sampling_step; double max_length; double walk_step; diff --git a/src/render/software/NightSky.cpp b/src/render/software/NightSky.cpp index 6cb4bd9..d70923e 100644 --- a/src/render/software/NightSky.cpp +++ b/src/render/software/NightSky.cpp @@ -95,7 +95,7 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) } -bool NightSky::getLightsAt(std::vector &result, const Vector3 &location) const +bool NightSky::getLightsAt(std::vector &result, const Vector3 &) const { LightComponent moon, sky;