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 {
|
Color Color::add(const Color &other) const {
|
||||||
return Color(r + other.r, g + other.g, b + other.b, a);
|
return Color(r + other.r, g + other.g, b + other.b, a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,15 @@ class BASICSSHARED_EXPORT Color {
|
||||||
double getPower() const;
|
double getPower() const;
|
||||||
void limitPower(double max_power);
|
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 add(const Color &other) const;
|
||||||
Color lerp(const Color &other, double f) const;
|
Color lerp(const Color &other, double f) const;
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent) : DefinitionNode(parent, "godrays", "godrays") {
|
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent) : DefinitionNode(parent, "godrays", "godrays") {
|
||||||
penetration = new FloatNode(this, "penetration", 0.01);
|
penetration = new FloatNode(this, "penetration", 0.01);
|
||||||
resistance = new FloatNode(this, "resistance", 0.3);
|
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;
|
material->shininess = 4.0;
|
||||||
break;
|
break;
|
||||||
case TEXTURES_LAYER_PRESET_ROCK:
|
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);
|
displacement_noise->setConfig(1.0, 0.3, 0.5, 0.85);
|
||||||
detail_noise->setConfig(0.02, 0.04);
|
detail_noise->setConfig(0.02, 0.04);
|
||||||
material->setColor(0.6, 0.55, 0.57, 1.0);
|
material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||||
|
|
|
@ -1069,7 +1069,7 @@ AtmosphereModelBruneton::~AtmosphereModelBruneton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction,
|
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 x = {0.0, Rg + eye.y * WORLD_SCALING, 0.0};
|
||||||
Vector3 v = direction.normalize();
|
Vector3 v = direction.normalize();
|
||||||
Vector3 s = sun_position.sub(x).normalize();
|
Vector3 s = sun_position.sub(x).normalize();
|
||||||
|
@ -1096,7 +1096,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) {
|
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) const {
|
||||||
Vector3 eye = parent->getCameraLocation(location);
|
Vector3 eye = parent->getCameraLocation(location);
|
||||||
eye.y = max(eye.y, 0.0);
|
eye.y = max(eye.y, 0.0);
|
||||||
location.y = max(location.y, 0.0);
|
location.y = max(location.y, 0.0);
|
||||||
|
|
|
@ -13,8 +13,8 @@ class SOFTWARESHARED_EXPORT AtmosphereModelBruneton : public LightSource {
|
||||||
AtmosphereModelBruneton(SoftwareRenderer *parent);
|
AtmosphereModelBruneton(SoftwareRenderer *parent);
|
||||||
virtual ~AtmosphereModelBruneton();
|
virtual ~AtmosphereModelBruneton();
|
||||||
|
|
||||||
AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, 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);
|
AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base) const;
|
||||||
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||||
|
|
||||||
/* Functions to get access to internal textures (for opengl shaders) */
|
/* Functions to get access to internal textures (for opengl shaders) */
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
#include "CloudLayerDefinition.h"
|
#include "CloudLayerDefinition.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
|
@ -63,12 +64,9 @@ int CloudBasicLayerRenderer::findSegments(BaseCloudsModel *model, const Vector3
|
||||||
model->getAltitudeRange(&ymin, &ymax);
|
model->getAltitudeRange(&ymin, &ymax);
|
||||||
|
|
||||||
model->getDetailRange(&min_step, &max_step);
|
model->getDetailRange(&min_step, &max_step);
|
||||||
render_precision = max_step - quality * (max_step - min_step);
|
|
||||||
if (render_precision > max_total_length / 10.0) {
|
double distance = parent->getCameraLocation(start).sub(start).getNorm();
|
||||||
render_precision = max_total_length / 10.0;
|
render_precision = min_step + (max_step - min_step) * min(distance / (quality + 0.1), 100.0) * 0.01;
|
||||||
} else if (render_precision < max_total_length / 2000.0) {
|
|
||||||
render_precision = max_total_length / 2000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
segment_count = 0;
|
segment_count = 0;
|
||||||
current_total_length = 0.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);
|
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 &&
|
} while (inside || (walker.y >= ymin - 0.001 && walker.y <= ymax + 0.001 &&
|
||||||
current_total_length < max_total_length && current_inside_length < max_inside_length));
|
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;
|
double max_length, total_length, inside_length;
|
||||||
Vector3 start, end, direction;
|
Vector3 start, end, direction;
|
||||||
Color result, col;
|
Color result, col;
|
||||||
CloudSegment segments[20];
|
CloudSegment segments[30];
|
||||||
|
|
||||||
start = eye;
|
start = eye;
|
||||||
end = location;
|
end = location;
|
||||||
|
@ -149,25 +149,18 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
|
||||||
|
|
||||||
double ymin, ymax;
|
double ymin, ymax;
|
||||||
model->getAltitudeRange(&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));
|
||||||
&total_length, segments);
|
material.hardness = 1.0;
|
||||||
for (i = segment_count - 1; i >= 0; i--) {
|
|
||||||
SurfaceMaterial material(COLOR_WHITE);
|
|
||||||
material.hardness = 0.25;
|
|
||||||
material.reflection = 0.0;
|
material.reflection = 0.0;
|
||||||
material.shininess = 0.0;
|
material.shininess = 0.0;
|
||||||
material.validate();
|
material.validate();
|
||||||
|
|
||||||
col = parent->applyLightingToSurface(segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(),
|
segment_count = findSegments(model, start, direction, 30, transparency_depth, max_length, &inside_length,
|
||||||
material);
|
&total_length, segments);
|
||||||
|
for (i = segment_count - 1; i >= 0; i--) {
|
||||||
// Boost highly lighted area
|
col = parent->applyLightingToSurface(segments[i].start, VECTOR_UP, material);
|
||||||
double boost = 1.0 + (col.getPower() * col.getPower());
|
|
||||||
col.r *= boost;
|
|
||||||
col.g *= boost;
|
|
||||||
col.b *= boost;
|
|
||||||
|
|
||||||
col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth);
|
col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth);
|
||||||
result.mask(col);
|
result.mask(col);
|
||||||
|
@ -197,7 +190,7 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent
|
||||||
const Vector3 &location) {
|
const Vector3 &location) {
|
||||||
Vector3 start, end, direction;
|
Vector3 start, end, direction;
|
||||||
double inside_depth, total_depth, factor;
|
double inside_depth, total_depth, factor;
|
||||||
CloudSegment segments[20];
|
CloudSegment segments[30];
|
||||||
|
|
||||||
start = location;
|
start = location;
|
||||||
direction = light->direction.scale(-1.0);
|
direction = light->direction.scale(-1.0);
|
||||||
|
@ -208,8 +201,8 @@ bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent
|
||||||
|
|
||||||
double ymin, ymax;
|
double ymin, ymax;
|
||||||
model->getAltitudeRange(&ymin, &ymax);
|
model->getAltitudeRange(&ymin, &ymax);
|
||||||
double light_traversal = (ymax - ymin) * 1.2;
|
double light_traversal = (ymax - ymin) * 0.8 * light->color.getPower();
|
||||||
findSegments(model, start, direction, 20, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth,
|
findSegments(model, start, direction, 30, light_traversal, end.sub(start).getNorm(), &inside_depth, &total_depth,
|
||||||
segments);
|
segments);
|
||||||
|
|
||||||
if (light_traversal < 0.0001) {
|
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;
|
factor = 1.0 - (1.0 - miminum_light) * factor;
|
||||||
|
|
||||||
light->color.r *= factor;
|
light->color.r *= factor;
|
||||||
|
|
|
@ -97,6 +97,7 @@ void SoftwareRenderer::prepare() {
|
||||||
|
|
||||||
void SoftwareRenderer::setQuality(double quality) {
|
void SoftwareRenderer::setQuality(double quality) {
|
||||||
terrain_renderer->setQuality(quality);
|
terrain_renderer->setQuality(quality);
|
||||||
|
textures_renderer->setQuality(quality);
|
||||||
clouds_renderer->setQuality(quality);
|
clouds_renderer->setQuality(quality);
|
||||||
godrays->setQuality(quality);
|
godrays->setQuality(quality);
|
||||||
|
|
||||||
|
|
|
@ -33,14 +33,14 @@ void CloudModelStratoCumulus::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloudModelStratoCumulus::getAltitudeRange(double *min_altitude, double *max_altitude) const {
|
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;
|
*max_altitude = *min_altitude + 11.0 * layer->scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CloudModelStratoCumulus::getDensity(const Vector3 &location) const {
|
double CloudModelStratoCumulus::getDensity(const Vector3 &location) const {
|
||||||
double val;
|
double val;
|
||||||
double min_altitude, max_altitude;
|
double min_altitude, max_altitude;
|
||||||
double noise_scaling = 25.0 * layer->scaling;
|
double noise_scaling = 30.0 * layer->scaling;
|
||||||
|
|
||||||
getAltitudeRange(&min_altitude, &max_altitude);
|
getAltitudeRange(&min_altitude, &max_altitude);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue