paysages : Progress on bruneton atmospheric model (WIP) + atmosphere presets.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@486 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-12-24 13:59:17 +00:00 committed by ThunderK
parent 4a6721e2ff
commit a50b0a25c2
8 changed files with 121 additions and 63 deletions

View file

@ -63,6 +63,12 @@ private:
FormAtmosphere::FormAtmosphere(QWidget *parent): FormAtmosphere::FormAtmosphere(QWidget *parent):
BaseForm(parent) BaseForm(parent)
{ {
addAutoPreset(tr("Clear day"));
addAutoPreset(tr("Clear sunset"));
addAutoPreset(tr("Hazy morning"));
addAutoPreset(tr("Foggy"));
addAutoPreset(tr("Stormy"));
_definition = (AtmosphereDefinition*)AtmosphereDefinitionClass.create(); _definition = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
previewWest = new PreviewSkyWest(this); previewWest = new PreviewSkyWest(this);
@ -99,3 +105,9 @@ void FormAtmosphere::configChangeEvent()
AtmosphereDefinitionClass.validate(_definition); AtmosphereDefinitionClass.validate(_definition);
BaseForm::configChangeEvent(); BaseForm::configChangeEvent();
} }
void FormAtmosphere::autoPresetSelected(int preset)
{
atmosphereAutoPreset(_definition, (AtmospherePreset)preset);
BaseForm::autoPresetSelected(preset);
}

View file

@ -18,6 +18,7 @@ public slots:
protected slots: protected slots:
virtual void configChangeEvent(); virtual void configChangeEvent();
virtual void autoPresetSelected(int preset);
private: private:
BasePreview* previewEast; BasePreview* previewEast;

View file

@ -56,7 +56,7 @@ int main(int argc, char** argv)
app.installTranslator(&qtTranslator); app.installTranslator(&qtTranslator);
} }
splash->showMessage(app.tr("Preloading environment...\n(may take some time on the first launch)"), Qt::AlignCenter, Qt::white); splash->showMessage(app.tr("Preloading..."), Qt::AlignCenter, Qt::white);
app.processEvents(); app.processEvents();
paysagesInit(); paysagesInit();

View file

@ -57,26 +57,26 @@ Texture2D* _transmittanceTexture = NULL;
Texture2D* _irradianceTexture = NULL; Texture2D* _irradianceTexture = NULL;
Texture3D* _inscatterTexture = NULL; Texture3D* _inscatterTexture = NULL;
// Rayleigh /* Rayleigh */
static const double HR = 8.0; 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 */
// 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 float HM = 1.2; /*static const double HM = 1.2;
static const vec3 betaMSca = vec3(20e-3); static const Vector3 betaMSca = {20e-3, 20e-3, 20e-3};
static const vec3 betaMEx = betaMSca / 0.9; static const Vector3 betaMEx = {20e-3 / 0.9, 20e-3 / 0.9, 20e-3 / 0.9};
static const float mieG = 0.76;*/ static const double mieG = 0.76;*/
// PARTLY CLOUDY /* PARTLY CLOUDY */
/*static const float HM = 3.0; /*static const double HM = 3.0;
static const vec3 betaMSca = vec3(3e-3); static const Vector3 betaMSca = {3e-3, 3e-3, 3e-3};
static const vec3 betaMEx = betaMSca / 0.9; static const Vector3 betaMEx = {3e-3 / 0.9, 3e-3 / 0.9, 3e-3 / 0.9};
static const float mieG = 0.65;*/ static const double mieG = 0.65;*/
/*********************** Shader helpers ***********************/ /*********************** Shader helpers ***********************/
@ -330,7 +330,7 @@ static Color _hdr(Color c1, Color c2, Color c3)
L.r *= exposure; L.r *= exposure;
L.g *= exposure; L.g *= exposure;
L.b *= exposure; L.b *= exposure;
L.a *= exposure; L.a = 1.0;
L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r); L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r);
L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g); L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g);
@ -356,9 +356,6 @@ static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, do
*mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); *mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
} }
*muS = fmod(x, (double)(RES_MU_S)) / ((double)(RES_MU_S)); *muS = fmod(x, (double)(RES_MU_S)) / ((double)(RES_MU_S));
/* paper formula :
* muS = -(0.6 + log(1.0 - muS * (1.0 - exp(-3.6)))) / 3.0; */
/* better formula */
*muS = tan((2.0 * (*muS) - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); *muS = tan((2.0 * (*muS) - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
*nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU)) * 2.0; *nu = -1.0 + floor(x / (double)(RES_MU_S)) / ((double)(RES_NU)) * 2.0;
} }
@ -936,44 +933,39 @@ static Color _groundColor(Color base, Vector3 x, double t, Vector3 v, Vector3 s,
Color result; Color result;
#if 0 #if 0
// ground reflectance at end of ray, x0 /* ground reflectance at end of ray, x0 */
Vector3 x0 = v3Add(x, v3Scale(v, t)); Vector3 x0 = v3Add(x, v3Scale(v, t));
float r0 = v3Norm(x0); float r0 = v3Norm(x0);
Vector3 n = v3Scale(x0, 1.0 / r0); Vector3 n = v3Scale(x0, 1.0 / r0);
vec2 coords = vec2(atan(n.y, n.x), acos(n.z)) * vec2(0.5, 1.0) / M_PI + vec2(0.5, 0.0);
Color reflectance;
if (r0 > Rg + 0.01)
{
reflectance = vec4(0.4, 0.4, 0.4, 0.0);
}
else
{
reflectance = texture2D(reflectanceSampler, coords) * vec4(0.2, 0.2, 0.2, 1.0);
}
// direct sun light (radiance) reaching x0 /* direct sun light (radiance) reaching x0 */
float muS = v3Dot(n, s); float muS = v3Dot(n, s);
Color sunLight = _transmittanceWithShadow(r0, muS); Color sunLight = _transmittanceWithShadow(r0, muS);
// precomputed sky light (irradiance) (=E[L*]) at x0 /* precomputed sky light (irradiance) (=E[L*]) at x0 */
Color groundSkyLight = irradiance(irradianceSampler, r0, muS); Color groundSkyLight = _irradiance(_irradianceTexture, r0, muS);
// light reflected at x0 (=(R[L0]+R[L*])/T(x,x0)) /* light reflected at x0 (=(R[L0]+R[L*])/T(x,x0)) */
Color groundColor = reflectance.rgb * (max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI; Color groundColor;
groundColor.r = base.r * (max(muS, 0.0) * sunLight.r + groundSkyLight.r) * ISun / M_PI;
groundColor.g = base.g * (max(muS, 0.0) * sunLight.g + groundSkyLight.g) * ISun / M_PI;
groundColor.b = base.b * (max(muS, 0.0) * sunLight.b + groundSkyLight.b) * ISun / M_PI;
// water specular color due to sunLight /* water specular color due to sunLight */
if (reflectance.w > 0.0) /*if (reflectance.w > 0.0)
{ {
vec3 h = normalize(s - v); vec3 h = normalize(s - v);
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0); float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun; groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun;
} }*/
#else
Color groundColor = base;
#endif #endif
result.r = attenuation.x * base.r; //=R[L0]+R[L*] result.r = attenuation.x * groundColor.r; //=R[L0]+R[L*]
result.g = attenuation.y * base.g; result.g = attenuation.y * groundColor.g;
result.b = attenuation.z * base.b; result.b = attenuation.z * groundColor.b;
result.a = 1.0; result.a = 1.0;
return result; return result;
@ -1226,7 +1218,7 @@ static inline void _fixVector(Vector3* v)
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position) Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
{ {
Vector3 x = {0.0, Rg + (eye.y + 20.0) * 0.1, 0.0}; Vector3 x = {0.0, Rg + (eye.y + 10.0) * 0.01, 0.0};
_fixVector(&x); _fixVector(&x);
Vector3 v = v3Normalize(direction); Vector3 v = v3Normalize(direction);
_fixVector(&v); _fixVector(&v);
@ -1237,8 +1229,7 @@ Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3
double mu = v3Dot(x, v) / r; double mu = v3Dot(x, v) / r;
double t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg); double t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);
Vector3 g = {0.0, 0.0, Rg + 10.0}; Vector3 g = {x.x, x.y, x.z - Rg + 10.0};
g = v3Sub(x, g);
double a = v.x * v.x + v.y * v.y - v.z * v.z; double a = v.x * v.x + v.y * v.y - v.z * v.z;
double b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z); double b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z);
double c = g.x * g.x + g.y * g.y - g.z * g.z; double c = g.x * g.x + g.y * g.y - g.z * g.z;
@ -1267,10 +1258,10 @@ Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
{ {
Vector3 eye = renderer->camera_location; Vector3 eye = renderer->camera_location;
Vector3 direction = v3Scale(v3Sub(location, eye), 0.1); Vector3 direction = v3Scale(v3Sub(location, eye), 0.01);
Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), 149597870.0); Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), 149597870.0);
Vector3 x = {0.0, Rg + (eye.y + 20.0) * 0.1, 0.0}; Vector3 x = {0.0, Rg + (eye.y + 10.0) * 0.01, 0.0};
_fixVector(&x); _fixVector(&x);
Vector3 v = v3Normalize(direction); Vector3 v = v3Normalize(direction);
_fixVector(&v); _fixVector(&v);
@ -1282,8 +1273,7 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
/*double t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);*/ /*double t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg);*/
double t = v3Norm(direction); double t = v3Norm(direction);
Vector3 g = {0.0, 0.0, Rg + 10.0}; Vector3 g = {x.x, x.y, x.z - Rg - 10.0};
g = v3Sub(x, g);
double a = v.x * v.x + v.y * v.y - v.z * v.z; double a = v.x * v.x + v.y * v.y - v.z * v.z;
double b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z); double b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z);
double c = g.x * g.x + g.y * g.y - g.z * g.z; double c = g.x * g.x + g.y * g.y - g.z * g.z;
@ -1305,6 +1295,6 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
Vector3 attenuation; Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */ Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color groundColor = _groundColor(base, x, t, v, s, r, mu, attenuation); //R[L0]+R[L*]*/ Color groundColor = _groundColor(base, x, t, v, s, r, mu, attenuation); //R[L0]+R[L*]*/
Color sunColor = _sunColor(x, t, v, s, r, mu); /* L0 */ Color sunColor = COLOR_BLACK;
return _hdr(sunColor, groundColor, inscatterColor); /* Eq (16) */ return _hdr(sunColor, groundColor, inscatterColor); /* Eq (16) */
} }

View file

@ -38,23 +38,9 @@ static AtmosphereDefinition* _createDefinition()
} }
result = malloc(sizeof(AtmosphereDefinition)); result = malloc(sizeof(AtmosphereDefinition));
result->model = ATMOSPHERE_MODEL_PREETHAM;
result->daytime = 0.0;
result->sun_color = COLOR_BLACK;
result->sun_color.r = 1.0;
result->sun_color.g = 0.95;
result->sun_color.b = 0.9;
result->sun_color.a = 1.0;
result->sun_radius = 0.02;
result->sun_halo_size = 0.3;
result->sun_halo_profile = curveCreate(); result->sun_halo_profile = curveCreate();
curveQuickAddPoint(result->sun_halo_profile, 0.0, 1.0);
curveQuickAddPoint(result->sun_halo_profile, 0.1, 0.2);
curveQuickAddPoint(result->sun_halo_profile, 1.0, 0.0);
result->dome_lighting = 0.6;
result->humidity = 0.1;
_validateDefinition(result); atmosphereAutoPreset(result, ATMOSPHERE_PRESET_CLEAR_DAY);
return result; return result;
} }

View file

@ -0,0 +1,57 @@
#include "private.h"
/*
* Atmosphere presets.
*/
void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset preset)
{
definition->sun_color.r = 1.0;
definition->sun_color.g = 0.95;
definition->sun_color.b = 0.9;
definition->sun_color.a = 1.0;
definition->sun_radius = 0.02;
definition->sun_halo_size = 0.3;
curveClear(definition->sun_halo_profile);
curveQuickAddPoint(definition->sun_halo_profile, 0.0, 1.0);
curveQuickAddPoint(definition->sun_halo_profile, 0.1, 0.2);
curveQuickAddPoint(definition->sun_halo_profile, 1.0, 0.0);
definition->humidity = 0.1;
switch (preset)
{
case ATMOSPHERE_PRESET_CLEAR_DAY:
definition->model = ATMOSPHERE_MODEL_BRUNETON;
definition->daytime = 0.4;
definition->dome_lighting = 0.6;
break;
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
definition->model = ATMOSPHERE_MODEL_BRUNETON;
definition->daytime = 0.74;
definition->dome_lighting = 0.8;
definition->sun_radius = 0.03;
break;
case ATMOSPHERE_PRESET_HAZY_MORNING:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->daytime = 0.3;
definition->dome_lighting = 0.5;
definition->humidity = 0.3;
break;
case ATMOSPHERE_PRESET_FOGGY:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->daytime = 0.4;
definition->dome_lighting = 0.7;
definition->humidity = 0.6;
break;
case ATMOSPHERE_PRESET_STORMY:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->daytime = 0.4;
definition->dome_lighting = 0.3;
definition->humidity = 0.9;
break;
default:
;
}
AtmosphereDefinitionClass.validate(definition);
}

View file

@ -1,3 +1,5 @@
#include "public.h"
#ifndef _PAYSAGES_ATMOSPHERE_PRIVATE_H_ #ifndef _PAYSAGES_ATMOSPHERE_PRIVATE_H_
#define _PAYSAGES_ATMOSPHERE_PRIVATE_H_ #define _PAYSAGES_ATMOSPHERE_PRIVATE_H_

View file

@ -11,6 +11,15 @@
extern "C" { extern "C" {
#endif #endif
typedef enum
{
ATMOSPHERE_PRESET_CLEAR_DAY = 0,
ATMOSPHERE_PRESET_CLEAR_SUNSET = 1,
ATMOSPHERE_PRESET_HAZY_MORNING = 2,
ATMOSPHERE_PRESET_FOGGY = 3,
ATMOSPHERE_PRESET_STORMY = 4
} AtmospherePreset;
typedef enum typedef enum
{ {
ATMOSPHERE_MODEL_PREETHAM = 0, ATMOSPHERE_MODEL_PREETHAM = 0,
@ -49,6 +58,7 @@ typedef struct
extern StandardDefinition AtmosphereDefinitionClass; extern StandardDefinition AtmosphereDefinitionClass;
extern StandardRenderer AtmosphereRendererClass; extern StandardRenderer AtmosphereRendererClass;
void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset preset);
void atmosphereRenderSkydome(Renderer* renderer); void atmosphereRenderSkydome(Renderer* renderer);
Renderer atmosphereCreatePreviewRenderer(); Renderer atmosphereCreatePreviewRenderer();
Color atmosphereGetPreview(Renderer* renderer, double x, double y, double heading); Color atmosphereGetPreview(Renderer* renderer, double x, double y, double heading);