paysages : Polished weather effects.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@542 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
56270e9941
commit
46148424c0
6 changed files with 74 additions and 28 deletions
1
TODO
1
TODO
|
@ -1,4 +1,5 @@
|
||||||
Technology Preview 2 :
|
Technology Preview 2 :
|
||||||
|
- Better time selection widget for atmosphere.
|
||||||
- Replace terrain canvas editor by full sculpting editor.
|
- Replace terrain canvas editor by full sculpting editor.
|
||||||
=> Add a generation dialog, with fixed resolution.
|
=> Add a generation dialog, with fixed resolution.
|
||||||
=> Store local terrain modifications in fully dynamic canvas.
|
=> Store local terrain modifications in fully dynamic canvas.
|
||||||
|
|
|
@ -84,7 +84,7 @@ FormAtmosphere::FormAtmosphere(QWidget *parent):
|
||||||
//addInputColor(tr("Sun color"), &_definition->sun_color);
|
//addInputColor(tr("Sun color"), &_definition->sun_color);
|
||||||
addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 5.0, 0.05, 0.5);
|
addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 5.0, 0.05, 0.5);
|
||||||
//addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1);
|
//addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1);
|
||||||
/*addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1);*/
|
addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1);
|
||||||
|
|
||||||
revertConfig();
|
revertConfig();
|
||||||
}
|
}
|
||||||
|
|
|
@ -919,10 +919,10 @@ static Color _getInscatterColor(Vector3* _x, double* _t, Vector3 v, Vector3 s, d
|
||||||
}
|
}
|
||||||
|
|
||||||
/* direct sun light for ray x+tv, when sun in direction s (=L0) */
|
/* direct sun light for ray x+tv, when sun in direction s (=L0) */
|
||||||
static Color _sunColor(Vector3 v, Vector3 s, double r, double mu)
|
static Color _sunColor(Vector3 v, Vector3 s, double r, double mu, double radius)
|
||||||
{
|
{
|
||||||
Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; /* T(x,xo) */
|
Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; /* T(x,xo) */
|
||||||
double isun = step(cos(M_PI / 180.0), v3Dot(v, s)) * ISun; /* Lsun */
|
double isun = step(cos(radius * M_PI / 180.0), v3Dot(v, s)) * ISun; /* Lsun */
|
||||||
transmittance.r *= isun;
|
transmittance.r *= isun;
|
||||||
transmittance.g *= isun;
|
transmittance.g *= isun;
|
||||||
transmittance.b *= isun;
|
transmittance.b *= isun;
|
||||||
|
@ -1169,15 +1169,14 @@ AtmosphereResult brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 di
|
||||||
|
|
||||||
AtmosphereResult result;
|
AtmosphereResult result;
|
||||||
Vector3 attenuation;
|
Vector3 attenuation;
|
||||||
Color sunColor = _sunColor(v, s, r, mu); /* L0 */
|
Color sunColor = _sunColor(v, s, r, mu, renderer->atmosphere->definition->sun_radius); /* L0 */
|
||||||
|
|
||||||
result.base.r = base.r + sunColor.r;
|
atmosphereInitResult(&result);
|
||||||
|
/*result.base.r = base.r + sunColor.r;
|
||||||
result.base.g = base.g + sunColor.g;
|
result.base.g = base.g + sunColor.g;
|
||||||
result.base.b = base.b + sunColor.b;
|
result.base.b = base.b + sunColor.b;*/
|
||||||
|
result.base = sunColor;
|
||||||
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
||||||
result.attenuation.r = 1.0;
|
|
||||||
result.attenuation.g = 1.0;
|
|
||||||
result.attenuation.b = 1.0;
|
|
||||||
/* TODO Use atmosphere attenuation */
|
/* TODO Use atmosphere attenuation */
|
||||||
result.distance = SPHERE_SIZE;
|
result.distance = SPHERE_SIZE;
|
||||||
|
|
||||||
|
@ -1220,12 +1219,14 @@ AtmosphereResult brunetonApplyAerialPerspective(Renderer* renderer, Vector3 loca
|
||||||
AtmosphereResult result;
|
AtmosphereResult result;
|
||||||
Vector3 attenuation;
|
Vector3 attenuation;
|
||||||
|
|
||||||
|
atmosphereInitResult(&result);
|
||||||
|
|
||||||
result.base = base;
|
result.base = base;
|
||||||
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
||||||
result.attenuation.r = attenuation.x;
|
result.attenuation.r = attenuation.x;
|
||||||
result.attenuation.g = attenuation.y;
|
result.attenuation.g = attenuation.y;
|
||||||
result.attenuation.b = attenuation.z;
|
result.attenuation.b = attenuation.z;
|
||||||
result.distance = t;
|
result.distance = t / WORLD_SCALING;
|
||||||
|
|
||||||
atmosphereUpdateResult(&result);
|
atmosphereUpdateResult(&result);
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,19 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre
|
||||||
definition->hour = 8;
|
definition->hour = 8;
|
||||||
definition->minute = 30;
|
definition->minute = 30;
|
||||||
definition->dome_lighting = 0.25;
|
definition->dome_lighting = 0.25;
|
||||||
definition->humidity = 0.3;
|
definition->humidity = 0.4;
|
||||||
break;
|
break;
|
||||||
case ATMOSPHERE_PRESET_FOGGY:
|
case ATMOSPHERE_PRESET_FOGGY:
|
||||||
definition->hour = 15;
|
definition->hour = 15;
|
||||||
definition->minute = 0;
|
definition->minute = 0;
|
||||||
definition->dome_lighting = 0.1;
|
definition->dome_lighting = 0.1;
|
||||||
definition->humidity = 0.5;
|
definition->humidity = 0.7;
|
||||||
break;
|
break;
|
||||||
case ATMOSPHERE_PRESET_STORMY:
|
case ATMOSPHERE_PRESET_STORMY:
|
||||||
definition->hour = 15;
|
definition->hour = 15;
|
||||||
definition->minute = 0;
|
definition->minute = 0;
|
||||||
definition->dome_lighting = 0.05;
|
definition->dome_lighting = 0.05;
|
||||||
definition->humidity = 0.8;
|
definition->humidity = 0.9;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
|
|
@ -45,6 +45,7 @@ typedef struct
|
||||||
double distance;
|
double distance;
|
||||||
Color inscattering;
|
Color inscattering;
|
||||||
Color attenuation;
|
Color attenuation;
|
||||||
|
Color mask;
|
||||||
Color final;
|
Color final;
|
||||||
} AtmosphereResult;
|
} AtmosphereResult;
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre
|
||||||
|
|
||||||
void atmosphereRenderSkydome(Renderer* renderer);
|
void atmosphereRenderSkydome(Renderer* renderer);
|
||||||
|
|
||||||
|
void atmosphereInitResult(AtmosphereResult* result);
|
||||||
void atmosphereUpdateResult(AtmosphereResult* result);
|
void atmosphereUpdateResult(AtmosphereResult* result);
|
||||||
|
|
||||||
Renderer* atmosphereCreatePreviewRenderer();
|
Renderer* atmosphereCreatePreviewRenderer();
|
||||||
|
|
|
@ -57,23 +57,53 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************** Real ********************/
|
/******************** Real ********************/
|
||||||
|
static inline double _getDayFactor(double daytime)
|
||||||
|
{
|
||||||
|
daytime = 1.0 - fabs(0.5 - daytime) / 0.5;
|
||||||
|
return daytime < 0.45 ? 0.0 : sqrt((daytime - 0.45) / 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void _applyWeatherEffects(AtmosphereDefinition* definition, AtmosphereResult* result)
|
static inline void _applyWeatherEffects(AtmosphereDefinition* definition, AtmosphereResult* result)
|
||||||
{
|
{
|
||||||
double distance = result->distance;
|
double distance = result->distance;
|
||||||
|
double max_distance = 100.0 - 90.0 * definition->humidity;
|
||||||
|
double distancefactor, dayfactor;
|
||||||
|
|
||||||
if (distance > 100.0)
|
if (distance > max_distance)
|
||||||
{
|
{
|
||||||
distance = 100.0;
|
distance = max_distance;
|
||||||
}
|
}
|
||||||
distance /= 100.0;
|
distancefactor = (distance > max_distance ? max_distance : distance) / max_distance;
|
||||||
|
/* TODO Get day lighting from model */
|
||||||
|
dayfactor = _getDayFactor(definition->_daytime);
|
||||||
|
|
||||||
result->inscattering.r += distance * 0.2 * definition->humidity;
|
/* Fog masking */
|
||||||
result->inscattering.g += distance * 0.2 * definition->humidity;
|
if (definition->humidity > 0.3)
|
||||||
result->inscattering.b += distance * 0.2 * definition->humidity;
|
{
|
||||||
|
result->mask.r = result->mask.g = result->mask.b = (10.0 - 8.0 * definition->humidity) * dayfactor;
|
||||||
|
result->mask.a = distancefactor * (definition->humidity - 0.3) / 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
result->attenuation.r *= 1.0 - distance * definition->humidity;
|
/* Scattering tweaking */
|
||||||
result->attenuation.g *= 1.0 - distance * definition->humidity;
|
if (definition->humidity < 0.15)
|
||||||
result->attenuation.b *= 1.0 - distance * definition->humidity;
|
{
|
||||||
|
/* Limit scattering on ultra clear day */
|
||||||
|
double force = (0.15 - definition->humidity) / 0.15;
|
||||||
|
colorLimitPower(&result->inscattering, 100.0 - 90.0 * pow(force, 0.1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Scattering boost */
|
||||||
|
double force = 1.2 * (definition->humidity < 0.5 ? sqrt((definition->humidity - 0.15) / 0.35) : 1.0 - (definition->humidity - 0.5) / 0.5);
|
||||||
|
result->inscattering.r *= 1.0 + force * distancefactor * (definition->humidity - 0.15) / 0.85;
|
||||||
|
result->inscattering.g *= 1.0 + force * distancefactor * (definition->humidity - 0.15) / 0.85;
|
||||||
|
result->inscattering.b *= 1.0 + force * distancefactor * (definition->humidity - 0.15) / 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attenuation */
|
||||||
|
result->attenuation.r *= 1.0 - 0.4 * distancefactor * definition->humidity;
|
||||||
|
result->attenuation.g *= 1.0 - 0.4 * distancefactor * definition->humidity;
|
||||||
|
result->attenuation.b *= 1.0 - 0.4 * distancefactor * definition->humidity;
|
||||||
|
|
||||||
atmosphereUpdateResult(result);
|
atmosphereUpdateResult(result);
|
||||||
}
|
}
|
||||||
|
@ -94,7 +124,7 @@ static AtmosphereResult _realApplyAerialPerspective(Renderer* renderer, Vector3
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply weather effects */
|
/* Apply weather effects */
|
||||||
/*_applyWeatherEffects(definition, &result);*/
|
_applyWeatherEffects(definition, &result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -114,14 +144,14 @@ static AtmosphereResult _realGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
|
|
||||||
/* Get sun shape */
|
/* Get sun shape */
|
||||||
base = COLOR_BLACK;
|
base = COLOR_BLACK;
|
||||||
if (v3Dot(sun_direction, direction) >= 0)
|
/*if (v3Dot(sun_direction, direction) >= 0)
|
||||||
{
|
{
|
||||||
double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED * 5.0; /* FIXME Why should we multiply by 5 ? */
|
double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED * 5.0; // FIXME Why should we multiply by 5 ?
|
||||||
Vector3 hit1, hit2;
|
Vector3 hit1, hit2;
|
||||||
int hits = euclidRayIntersectSphere(camera_location, direction, sun_position, sun_radius, &hit1, &hit2);
|
int hits = euclidRayIntersectSphere(camera_location, direction, sun_position, sun_radius, &hit1, &hit2);
|
||||||
if (hits > 1)
|
if (hits > 1)
|
||||||
{
|
{
|
||||||
double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; /* distance between intersection points (relative to radius) */
|
double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; // distance between intersection points (relative to radius)
|
||||||
|
|
||||||
Color sun_color = definition->sun_color;
|
Color sun_color = definition->sun_color;
|
||||||
sun_color.r *= 100.0;
|
sun_color.r *= 100.0;
|
||||||
|
@ -136,7 +166,7 @@ static AtmosphereResult _realGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
}
|
}
|
||||||
base = sun_color;
|
base = sun_color;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/* TODO Get stars */
|
/* TODO Get stars */
|
||||||
|
|
||||||
|
@ -153,7 +183,7 @@ static AtmosphereResult _realGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply weather effects */
|
/* Apply weather effects */
|
||||||
/*_applyWeatherEffects(definition, &result);*/
|
_applyWeatherEffects(definition, &result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -168,12 +198,24 @@ static Vector3 _realGetSunDirection(Renderer* renderer)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void atmosphereInitResult(AtmosphereResult* result)
|
||||||
|
{
|
||||||
|
result->base = COLOR_BLACK;
|
||||||
|
result->inscattering = COLOR_BLACK;
|
||||||
|
result->attenuation = COLOR_WHITE;
|
||||||
|
result->mask = COLOR_TRANSPARENT;
|
||||||
|
result->distance = 0.0;
|
||||||
|
result->final = COLOR_BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
void atmosphereUpdateResult(AtmosphereResult* result)
|
void atmosphereUpdateResult(AtmosphereResult* result)
|
||||||
{
|
{
|
||||||
result->final.r = result->base.r * result->attenuation.r + result->inscattering.r;
|
result->final.r = result->base.r * result->attenuation.r + result->inscattering.r;
|
||||||
result->final.g = result->base.g * result->attenuation.g + result->inscattering.g;
|
result->final.g = result->base.g * result->attenuation.g + result->inscattering.g;
|
||||||
result->final.b = result->base.b * result->attenuation.b + result->inscattering.b;
|
result->final.b = result->base.b * result->attenuation.b + result->inscattering.b;
|
||||||
result->final.a = 1.0;
|
result->final.a = 1.0;
|
||||||
|
|
||||||
|
colorMask(&result->final, &result->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************** Renderer ********************/
|
/******************** Renderer ********************/
|
||||||
|
|
Loading…
Reference in a new issue