Some tweaks to improve clouds aspect
This commit is contained in:
parent
3b27d3be3e
commit
c0a4e93c52
9 changed files with 48 additions and 35 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<LightComponent> &result, const Vector3 &location) const override;
|
||||
|
||||
/* Functions to get access to internal textures (for opengl shaders) */
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#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,
|
||||
&total_length, segments);
|
||||
for (i = segment_count - 1; i >= 0; i--) {
|
||||
SurfaceMaterial material(COLOR_WHITE);
|
||||
material.hardness = 0.25;
|
||||
SurfaceMaterial material(COLOR_WHITE.scaled(5.0));
|
||||
material.hardness = 1.0;
|
||||
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;
|
||||
segment_count = findSegments(model, start, direction, 30, transparency_depth, max_length, &inside_length,
|
||||
&total_length, segments);
|
||||
for (i = segment_count - 1; i >= 0; i--) {
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue