diff --git a/src/basics/Color.cpp b/src/basics/Color.cpp index 8b16107..47a5cda 100644 --- a/src/basics/Color.cpp +++ b/src/basics/Color.cpp @@ -167,6 +167,16 @@ void Color::limitPower(double max_power) { } } +void Color::scale(double factor) { + r *= factor; + g *= factor; + b *= factor; +} + +Color Color::scaled(double factor) const { + return Color(r * factor, g * factor, b * factor, a); +} + Color Color::add(const Color &other) const { return Color(r + other.r, g + other.g, b + other.b, a); } diff --git a/src/basics/Color.h b/src/basics/Color.h index f305d60..32e8a9b 100644 --- a/src/basics/Color.h +++ b/src/basics/Color.h @@ -32,6 +32,15 @@ class BASICSSHARED_EXPORT Color { double getPower() const; void limitPower(double max_power); + /** + * Scale the RGB components by a factor. + */ + void scale(double factor); + /** + * Return a copy, with RGB components scaled by a factor. + */ + Color scaled(double factor) const; + Color add(const Color &other) const; Color lerp(const Color &other, double f) const; diff --git a/src/definition/GodRaysDefinition.cpp b/src/definition/GodRaysDefinition.cpp index 01fb2c6..a107b7c 100644 --- a/src/definition/GodRaysDefinition.cpp +++ b/src/definition/GodRaysDefinition.cpp @@ -5,5 +5,5 @@ 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); + boost = new FloatNode(this, "boost", 3.0); } diff --git a/src/definition/TextureLayerDefinition.cpp b/src/definition/TextureLayerDefinition.cpp index 3af6b8a..1ca65f0 100644 --- a/src/definition/TextureLayerDefinition.cpp +++ b/src/definition/TextureLayerDefinition.cpp @@ -80,7 +80,7 @@ void TextureLayerDefinition::applyPreset(TextureLayerPreset preset, RandomGenera material->shininess = 4.0; break; case TEXTURES_LAYER_PRESET_ROCK: - terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 1.0, 1.0); + terrain_zone->addHeightRangeQuick(1.0, 0.55, 0.7, 0.9, 1.0); displacement_noise->setConfig(1.0, 0.3, 0.5, 0.85); detail_noise->setConfig(0.02, 0.04); material->setColor(0.6, 0.55, 0.57, 1.0); diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index d4ba2b5..693ffca 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -1069,7 +1069,7 @@ AtmosphereModelBruneton::~AtmosphereModelBruneton() { } AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, - const Vector3 &sun_position, const Color &base) { + const Vector3 &sun_position, const Color &base) const { Vector3 x = {0.0, Rg + eye.y * WORLD_SCALING, 0.0}; Vector3 v = direction.normalize(); Vector3 s = sun_position.sub(x).normalize(); @@ -1096,7 +1096,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 return result; } -AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) { +AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) const { Vector3 eye = parent->getCameraLocation(location); eye.y = max(eye.y, 0.0); location.y = max(location.y, 0.0); diff --git a/src/render/software/AtmosphereModelBruneton.h b/src/render/software/AtmosphereModelBruneton.h index 8ef56f8..d458d69 100644 --- a/src/render/software/AtmosphereModelBruneton.h +++ b/src/render/software/AtmosphereModelBruneton.h @@ -13,8 +13,8 @@ class SOFTWARESHARED_EXPORT AtmosphereModelBruneton : public LightSource { AtmosphereModelBruneton(SoftwareRenderer *parent); virtual ~AtmosphereModelBruneton(); - AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base); - AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base); + AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base) const; + AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base) const; virtual bool getLightsAt(vector &result, const Vector3 &location) const override; /* Functions to get access to internal textures (for opengl shaders) */ diff --git a/src/render/software/CloudBasicLayerRenderer.cpp b/src/render/software/CloudBasicLayerRenderer.cpp index fc4b23a..8c66be3 100644 --- a/src/render/software/CloudBasicLayerRenderer.cpp +++ b/src/render/software/CloudBasicLayerRenderer.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "CloudLayerDefinition.h" #include "SoftwareRenderer.h" #include "NoiseGenerator.h" @@ -63,12 +64,9 @@ int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3 model->getAltitudeRange(&ymin, &ymax); model->getDetailRange(&min_step, &max_step); - render_precision = max_step - quality * (max_step - min_step); - if (render_precision > max_total_length / 10.0) { - render_precision = max_total_length / 10.0; - } else if (render_precision < max_total_length / 2000.0) { - render_precision = max_total_length / 2000.0; - } + + double distance = parent->getCameraLocation(start).sub(start).getNorm(); + render_precision = min_step + (max_step - min_step) * min(distance / (quality + 0.1), 100.0) * 0.01; segment_count = 0; current_total_length = 0.0; @@ -121,6 +119,8 @@ int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3 step = direction.scale((noise_distance > -render_precision) ? render_precision : -noise_distance); } } + + render_precision *= 1.0 + 0.001 / (quality + 0.1); } while (inside || (walker.y >= ymin - 0.001 && walker.y <= ymax + 0.001 && current_total_length < max_total_length && current_inside_length < max_inside_length)); @@ -134,7 +134,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e double max_length, total_length, inside_length; Vector3 start, end, direction; Color result, col; - CloudSegment segments[20]; + CloudSegment segments[30]; start = eye; end = location; @@ -149,25 +149,18 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e double ymin, ymax; model->getAltitudeRange(&ymin, &ymax); - double transparency_depth = (ymax - ymin) * 0.5; + double transparency_depth = (ymax - ymin); - segment_count = findSegments(model, start, direction, 20, transparency_depth, max_length, &inside_length, + SurfaceMaterial material(COLOR_WHITE.scaled(5.0)); + material.hardness = 1.0; + material.reflection = 0.0; + material.shininess = 0.0; + material.validate(); + + segment_count = findSegments(model, start, direction, 30, transparency_depth, max_length, &inside_length, &total_length, segments); for (i = segment_count - 1; i >= 0; i--) { - SurfaceMaterial material(COLOR_WHITE); - material.hardness = 0.25; - material.reflection = 0.0; - material.shininess = 0.0; - material.validate(); - - col = parent->applyLightingToSurface(segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(), - material); - - // Boost highly lighted area - double boost = 1.0 + (col.getPower() * col.getPower()); - col.r *= boost; - col.g *= boost; - col.b *= boost; + col = parent->applyLightingToSurface(segments[i].start, VECTOR_UP, material); col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth); result.mask(col); @@ -197,7 +190,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent const Vector3 &location) { Vector3 start, end, direction; double inside_depth, total_depth, factor; - CloudSegment segments[20]; + CloudSegment segments[30]; start = location; direction = light->direction.scale(-1.0); @@ -208,8 +201,8 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent double ymin, ymax; model->getAltitudeRange(&ymin, &ymax); - double light_traversal = (ymax - ymin) * 1.2; - findSegments(model, start, direction, 20, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth, + double light_traversal = (ymax - ymin) * 0.8 * light->color.getPower(); + findSegments(model, start, direction, 30, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth, segments); if (light_traversal < 0.0001) { @@ -223,7 +216,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent } } - double miminum_light = 0.3; + double miminum_light = 0.01 * light->color.getPower(); factor = 1.0 - (1.0 - miminum_light) * factor; light->color.r *= factor; diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index bb6f0a0..10615ad 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -97,6 +97,7 @@ void SoftwareRenderer::prepare() { void SoftwareRenderer::setQuality(double quality) { terrain_renderer->setQuality(quality); + textures_renderer->setQuality(quality); clouds_renderer->setQuality(quality); godrays->setQuality(quality); diff --git a/src/render/software/clouds/CloudModelStratoCumulus.cpp b/src/render/software/clouds/CloudModelStratoCumulus.cpp index 6664294..0c0cc0a 100644 --- a/src/render/software/clouds/CloudModelStratoCumulus.cpp +++ b/src/render/software/clouds/CloudModelStratoCumulus.cpp @@ -33,14 +33,14 @@ void CloudModelStratoCumulus::update() { } void CloudModelStratoCumulus::getAltitudeRange(double *min_altitude, double *max_altitude) const { - *min_altitude = 10.0 + 10.0 * layer->altitude; + *min_altitude = 20.0 + 10.0 * layer->altitude; *max_altitude = *min_altitude + 11.0 * layer->scaling; } double CloudModelStratoCumulus::getDensity(const Vector3 &location) const { double val; double min_altitude, max_altitude; - double noise_scaling = 25.0 * layer->scaling; + double noise_scaling = 30.0 * layer->scaling; getAltitudeRange(&min_altitude, &max_altitude);