Fixed some artifacts in atmosphere rendering

when sun was near horizon
This commit is contained in:
Michaël Lemaire 2015-12-21 17:48:30 +01:00
parent 366ac4a6c9
commit 3934077552
8 changed files with 38 additions and 28 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

View file

@ -106,7 +106,7 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator
sun_color.g = 0.95;
sun_color.b = 0.9;
sun_color.a = 1.0;
sun_radius->setValue(0.7);
sun_radius->setValue(0.5);
moon_radius = 1.0;
moon_theta = 0.3;
moon_phi = 0.5;

View file

@ -6,12 +6,12 @@ const float AVERAGE_GROUND_REFLECTANCE = 0.1;
const float HR = 8.0;
const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2);
const float HM = 1.2;
const vec3 betaMSca = vec3(4e-3);
const vec3 betaMEx = vec3(4e-3 / 0.9);
const float mieG = 0.8;
const float WORKAROUND_OFFSET = 0.2;
const vec3 betaMSca = vec3(20e-3, 20e-3, 20e-3);
const vec3 betaMEx = vec3(20e-3 / 0.9, 20e-3 / 0.9, 20e-3 / 0.9);
const float mieG = 0.76;
const float WORKAROUND_OFFSET = 0.1;
const float SPHERE_SIZE = 20000.0;
const float WORLD_SCALING = 0.05;
const float WORLD_SCALING = 0.03;
const float SUN_DISTANCE = 149597870.0;
const float SUN_DISTANCE_SCALED = (SUN_DISTANCE / WORLD_SCALING);
const float M_PI = 3.141592657;
@ -162,11 +162,11 @@ vec3 _getInscatterColor(inout vec3 x, inout float t, vec3 v, vec3 s, out float r
float muS0 = dot(x0, s) / r0;
// avoids imprecision problems in transmittance computations based on textures
attenuation = analyticTransmittance(r, mu, t);
if (r0 > Rg + 0.001) {
if (r0 > Rg + 0.01) {
// computes S[L]-T(x,x0)S[L]|x0
inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0);
// avoids imprecision problems near horizon by interpolating between two points above and below horizon
const float EPS = 0.02;
const float EPS = 0.004;
float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
if (abs(mu - muHoriz) < EPS) {
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
@ -263,6 +263,10 @@ vec4 applyAerialPerspective(vec4 base)
vec3 v = normalize(unprojected - cameraLocation);
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
if (v.y > s.y - 0.01) {
v.y = s.y - 0.01;
v = normalize(v);
}
if (v.y == 0.0)
{
v.y = -0.000001;

View file

@ -26,19 +26,19 @@
#include "FloatNode.h"
/* Factor to convert software units to kilometers */
// TODO This is copied in AtmosphereRenderer
#define SPHERE_SIZE 20000.0
#define WORLD_SCALING 0.05
#define WORLD_SCALING 0.03
#define SUN_DISTANCE 149597870.0
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
#define WORKAROUND_OFFSET 0.2
#define WORKAROUND_OFFSET 0.1
// TODO This is copied in AtmosphereRenderer
#define SPHERE_SIZE 20000.0
/*********************** Constants ***********************/
static const double Rg = 6360.0;
static const double Rt = 6420.0;
static const double RL = 6421.0;
static const double exposure = 0.4;
static const double ISun = 100.0;
static const double AVERAGE_GROUND_REFLECTANCE = 0.1;
@ -47,14 +47,14 @@ static const double AVERAGE_GROUND_REFLECTANCE = 0.1;
#define RES_MU_S 32
#define RES_R 32
#define RES_NU 8
#define SKY_W 64
#define SKY_H 16
#define TRANSMITTANCE_W 256
#define TRANSMITTANCE_H 64
#define SKY_W 256
#define SKY_H 64
#define TRANSMITTANCE_W 512
#define TRANSMITTANCE_H 128
#define TRANSMITTANCE_INTEGRAL_SAMPLES 500
#define INSCATTER_INTEGRAL_SAMPLES 50
#define IRRADIANCE_INTEGRAL_SAMPLES 32
#define INSCATTER_SPHERICAL_INTEGRAL_SAMPLES 16
#define INSCATTER_INTEGRAL_SAMPLES 100
#define IRRADIANCE_INTEGRAL_SAMPLES 64
#define INSCATTER_SPHERICAL_INTEGRAL_SAMPLES 32
#else
#define RES_MU 64
#define RES_MU_S 16
@ -79,16 +79,17 @@ static const double HR = 8.0;
static const Color betaR = {5.8e-3, 1.35e-2, 3.31e-2, 1.0};
/* Mie */
// TODO Use the good ones, determined by weather definition
/* DEFAULT */
static const double HM = 1.2;
/*static const double HM = 1.2;
static const Vector3 betaMSca = {4e-3, 4e-3, 4e-3};
static const Vector3 betaMEx = {4e-3 / 0.9, 4e-3 / 0.9, 4e-3 / 0.9};
static const double mieG = 0.8;
static const double mieG = 0.8;*/
/* CLEAR SKY */
/*static const double HM = 1.2;
static const double HM = 1.2;
static const Vector3 betaMSca = {20e-3, 20e-3, 20e-3};
static const Vector3 betaMEx = {20e-3 / 0.9, 20e-3 / 0.9, 20e-3 / 0.9};
static const double mieG = 0.76;*/
static const double mieG = 0.76;
/* PARTLY CLOUDY */
/*static const double HM = 3.0;
static const Vector3 betaMSca = {3e-3, 3e-3, 3e-3};
@ -809,14 +810,14 @@ static Color _getInscatterColor(Vector3 *_x, double *_t, Vector3 v, Vector3 s, d
double muS0 = x0.dotProduct(s) / r0;
/* avoids imprecision problems in transmittance computations based on textures */
*attenuation = _analyticTransmittance(r, mu, t);
if (r0 > Rg + 0.001) {
if (r0 > Rg + 0.01) {
/* computes S[L]-T(x,x0)S[L]|x0 */
Color attmod = {attenuation->x, attenuation->y, attenuation->z, attenuation->x};
Color samp = _texture4D(_inscatterTexture, r0, mu0, muS0, nu);
inscatter = _applyInscatter(inscatter, attmod, samp);
/* avoids imprecision problems near horizon by interpolating between two points above and below horizon
*/
const double EPS = 0.02;
const double EPS = 0.004;
double muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
if (fabs(mu - muHoriz) < EPS) {
double a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
@ -899,7 +900,7 @@ static void _saveCache2D(Texture2D *tex, const char *tag, int order) {
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, 0, 0, order);
if (cache.isWritable()) {
PackStream stream;
stream.bindToFile(cache.getPath());
stream.bindToFile(cache.getPath(), true);
tex->save(&stream);
}
}
@ -937,7 +938,7 @@ static void _saveCache4D(Texture4D *tex, const char *tag, int order) {
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, zsize, wsize, order);
if (cache.isWritable()) {
PackStream stream;
stream.bindToFile(cache.getPath());
stream.bindToFile(cache.getPath(), true);
tex->save(&stream);
}
}
@ -1110,6 +1111,11 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
Vector3 v = direction.normalize();
Vector3 s = sun_position.sub(x).normalize();
if (v.y > s.y) {
v.y = s.y;
v.normalize();
}
if (v.y == 0.0) {
v.y = -0.000001;
}