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.g = 0.95;
sun_color.b = 0.9; sun_color.b = 0.9;
sun_color.a = 1.0; sun_color.a = 1.0;
sun_radius->setValue(0.7); sun_radius->setValue(0.5);
moon_radius = 1.0; moon_radius = 1.0;
moon_theta = 0.3; moon_theta = 0.3;
moon_phi = 0.5; moon_phi = 0.5;

View file

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

View file

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