paysages : Added AtmosphereResult + deleted basic and preetham models.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@541 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-03-14 17:29:12 +00:00 committed by ThunderK
parent 9d7b896c91
commit 56270e9941
15 changed files with 133 additions and 292 deletions

View file

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h>
#include "../lib_paysages/auto.h" #include "../lib_paysages/auto.h"
#include "../lib_paysages/main.h" #include "../lib_paysages/main.h"
@ -126,21 +127,29 @@ int main(int argc, char** argv)
paysagesLoad(conf_file_path); paysagesLoad(conf_file_path);
} }
for (outputcount = 0; outputcount < conf_nb_pictures; outputcount++)
{
AtmosphereDefinition* atmo;
atmo = AtmosphereDefinitionClass.create();
sceneryGetAtmosphere(atmo);
atmo->hour = (int)floor(conf_daytime_start * 24.0);
atmo->minute = (int)floor(fmod(conf_daytime_start, 1.0 / 24.0) * 24.0 * 60.0);
AtmosphereDefinitionClass.validate(atmo);
scenerySetAtmosphere(atmo);
AtmosphereDefinitionClass.destroy(atmo);
renderer = sceneryCreateStandardRenderer(); renderer = sceneryCreateStandardRenderer();
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate); rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
for (outputcount = 0; outputcount < conf_nb_pictures; outputcount++)
{
/*autoSetDaytimeFraction(conf_daytime_start);*/ /* TODO */
sprintf(outputpath, "output/pic%05d.png", outputcount); sprintf(outputpath, "output/pic%05d.png", outputcount);
startRender(renderer, outputpath, conf_render_params); startRender(renderer, outputpath, conf_render_params);
rendererDelete(renderer);
conf_daytime_start += conf_daytime_step; conf_daytime_start += conf_daytime_step;
} }
printf("Cleaning up ...\n"); printf("Cleaning up ...\n");
rendererDelete(renderer);
paysagesQuit(); paysagesQuit();
printf("\rDone. \n"); printf("\rDone. \n");

View file

@ -141,5 +141,5 @@ Color ExplorerChunkSky::getTextureColor(double x, double y)
{ {
location.y = 0.0; location.y = 0.0;
} }
return renderer()->atmosphere->getSkyColor(renderer(), location); return renderer()->atmosphere->getSkyColor(renderer(), location).final;
} }

View file

@ -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();
} }

View file

@ -92,9 +92,15 @@ private:
return v3Add(location, v3Scale(VECTOR_UP, 50.0)); return v3Add(location, v3Scale(VECTOR_UP, 50.0));
} }
static Color _applyAerialPerspective(Renderer*, Vector3, Color base) static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
{ {
return base; AtmosphereResult result;
result.base = base;
result.distance = 0.0;
result.inscattering = COLOR_BLACK;
result.attenuation = COLOR_BLACK;
result.final = base;
return result;
} }
}; };

View file

@ -1,58 +0,0 @@
#include "private.h"
#include <assert.h>
#include <math.h>
#include "../renderer.h"
Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
{
Vector3 direction = v3Sub(location, renderer->getCameraLocation(renderer, location));
double distance = v3Norm(direction);
AtmosphereDefinition* definition = renderer->atmosphere->definition;
double near = 10.0 - definition->humidity * 10.0;
double far = 500.0 - definition->humidity * 480.0;
double max = 0.75 + definition->humidity * 0.22;
assert(near < far);
if (distance < near)
{
return base;
}
else
{
if (distance > far)
{
distance = far;
}
double factor = (distance - near) / (far - near);
/* TODO Get sky color without celestial objects (sun, stars...) */
double angle = (1.0 - factor) * (1.0 - factor) * (1.0 - factor) * (1.0 - factor) * M_PI_4;
direction = v3Normalize(direction);
direction.y = sin(angle);
Color sky = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction));
sky.a = max * factor;
colorMask(&base, &sky);
return base;
}
}
void basicGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
{
/* Direct light from the sun */
LightDefinition light;
light.direction = v3Scale(renderer->atmosphere->getSunDirection(renderer), -1.0);
light.color = renderer->atmosphere->definition->sun_color;
/*light.color.r *= 100.0;
light.color.g *= 100.0;
light.color.b *= 100.0;*/
light.reflection = 1.0;
light.altered = 1;
lightingPushLight(status, &light);
/* TODO Sample other directions */
}

View file

@ -1151,7 +1151,7 @@ void brunetonInit()
texture4DDelete(_deltaJTexture); texture4DDelete(_deltaJTexture);
} }
Color brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position) AtmosphereResult brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position, Color base)
{ {
double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height; double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height;
eye.y += yoffset; eye.y += yoffset;
@ -1167,18 +1167,26 @@ Color brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Ve
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);
AtmosphereResult result;
Vector3 attenuation; Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color sunColor = _sunColor(v, s, r, mu); /* L0 */ Color sunColor = _sunColor(v, s, r, mu); /* L0 */
sunColor.r = sunColor.r * attenuation.x + inscatterColor.r; result.base.r = base.r + sunColor.r;
sunColor.g = sunColor.g * attenuation.y + inscatterColor.g; result.base.g = base.g + sunColor.g;
sunColor.b = sunColor.b * attenuation.z + inscatterColor.b; result.base.b = base.b + sunColor.b;
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 */
result.distance = SPHERE_SIZE;
return sunColor; /* Eq (16) */ atmosphereUpdateResult(&result);
return result;
} }
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) AtmosphereResult brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
{ {
Vector3 eye = renderer->getCameraLocation(renderer, location); Vector3 eye = renderer->getCameraLocation(renderer, location);
Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE);
@ -1209,14 +1217,19 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
double mu = v3Dot(x, v) / r; double mu = v3Dot(x, v) / r;
double t = v3Norm(direction); double t = v3Norm(direction);
AtmosphereResult result;
Vector3 attenuation; Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
base.r = base.r * attenuation.x + inscatterColor.r; result.base = base;
base.g = base.g * attenuation.y + inscatterColor.g; result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
base.b = base.b * attenuation.z + inscatterColor.b; result.attenuation.r = attenuation.x;
result.attenuation.g = attenuation.y;
result.attenuation.b = attenuation.z;
result.distance = t;
return base; /* Eq (16) */ atmosphereUpdateResult(&result);
return result;
} }
void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)

View file

@ -1,135 +0,0 @@
#include "public.h"
#include "private.h"
#include <math.h>
#include <assert.h>
#include "../renderer.h"
static inline double _angleBetween(double thetav, double phiv, double theta, double phi)
{
double cospsi = sin(thetav) * sin(theta) * cos(phi-phiv) + cos(thetav) * cos(theta);
if (cospsi > 1.0) return 0.0;
if (cospsi < -1.0) return M_PI;
return acos(cospsi);
}
static inline Color _xyYToRGB(double x, double y, double Y)
{
double fX, fY, fZ;
Color result;
fY = Y;
fX = x / y * Y;
fZ = ((1.0 - x - y) / y) * Y;
double r, g, b;
r = 3.2404 * fX - 1.5371 * fY - 0.4985 * fZ;
g = -0.9692 * fX + 1.8759 * fY + 0.0415 * fZ;
b = 0.0556 * fX - 0.2040 * fY + 1.0573 * fZ;
double expo = -(1.0 / 10000.0);
r = 1.0 - exp(expo * r);
g = 1.0 - exp(expo * g);
b = 1.0 - exp(expo * b);
if (r < 0.0) r = 0.0;
if (g < 0.0) g = 0.0;
if (b < 0.0) b = 0.0;
result.r = r;
result.g = g;
result.b = b;
result.a = 1.0;
return result;
}
static inline void _directionToThetaPhi(Vector3 direction, double* theta, double* phi)
{
direction = v3Normalize(direction);
*phi = atan2(-direction.z, direction.x);
*theta = M_PI_2 - asin(direction.y);
}
Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
{
double theta, phi;
double thetaSun, phiSun;
_directionToThetaPhi(direction, &theta, &phi);
_directionToThetaPhi(sun_position, &thetaSun, &phiSun);
if (theta > M_PI / 2.0)
{
theta = M_PI / 2.0;
}
double gamma = _angleBetween(theta, phi, thetaSun, phiSun);
double cosTheta;
if (theta > M_PI / 2.0)
{
cosTheta = 0.0000001;
}
else
{
cosTheta = cos(theta);
}
double T = definition->humidity * 3.0 + 1.8;
double T2 = T * T;
double suntheta = thetaSun;
double suntheta2 = thetaSun * thetaSun;
double suntheta3 = thetaSun * suntheta2;
double Ax = -0.01925 * T - 0.25922;
double Bx = -0.06651 * T + 0.00081;
double Cx = -0.00041 * T + 0.21247;
double Dx = -0.06409 * T - 0.89887;
double Ex = -0.00325 * T + 0.04517;
double Ay = -0.01669 * T - 0.26078;
double By = -0.09495 * T + 0.00921;
double Cy = -0.00792 * T + 0.21023;
double Dy = -0.04405 * T - 1.65369;
double Ey = -0.01092 * T + 0.05291;
double AY = 0.17872 * T - 1.46303;
double BY = -0.35540 * T + 0.42749;
double CY = -0.02266 * T + 5.32505;
double DY = 0.12064 * T - 2.57705;
double EY = -0.06696 * T + 0.37027;
double cosGamma = cos(gamma);
cosGamma = cosGamma < 0.0 ? 0.0 : cosGamma;
double cosSTheta = fabs(cos(thetaSun));
double xz = ( 0.00165 * suntheta3 - 0.00375 * suntheta2 + 0.00209 * suntheta + 0.00000) * T2 +
(-0.02903 * suntheta3 + 0.06377 * suntheta2 - 0.03202 * suntheta + 0.00394) * T +
( 0.11693 * suntheta3 - 0.21196 * suntheta2 + 0.06052 * suntheta + 0.25886);
double yz = ( 0.00275 * suntheta3 - 0.00610 * suntheta2 + 0.00317 * suntheta + 0.00000) * T2 +
(-0.04214 * suntheta3 + 0.08970 * suntheta2 - 0.04153 * suntheta + 0.00516) * T +
( 0.15346 * suntheta3 - 0.26756 * suntheta2 + 0.06670 * suntheta + 0.26688);
double X = (4.0 / 9.0 - T / 120.0) * (M_PI - 2.0 * suntheta);
double Yz = ((4.0453 * T - 4.9710) * tan(X) - 0.2155 * T + 2.4192) * 1000.0;
double val1, val2;
val1 = (1.0 + Ax * exp(Bx / cosTheta)) * (1.0 + Cx * exp(Dx * gamma) + Ex * sqrt(cosGamma));
val2 = (1.0 + Ax * exp(Bx)) * (1.0 + Cx * exp(Dx * suntheta) + Ex * sqrt(cosSTheta));
double x = xz * val1 / val2;
val1 = (1.0 + Ay * exp(By / cosTheta)) * (1.0 + Cy * exp(Dy * gamma) + Ey * sqrt(cosGamma));
val2 = (1.0 + Ay * exp(By)) * (1.0 + Cy * exp(Dy * suntheta) + Ey * sqrt(cosSTheta));
double y = yz * val1 / val2;
val1 = (1.0 + AY * exp(BY / cosTheta)) * (1.0 + CY * exp(DY * gamma) + EY * sqrt(cosGamma));
val2 = (1.0 + AY * exp(BY)) * (1.0 + CY * exp(DY * suntheta) + EY * sqrt(cosSTheta));
double Y = Yz * val1 / val2;
Color result = _xyYToRGB(x, y, Y);
Color humidity_color = {0.8, 0.8, 0.8, definition->humidity * 0.8 * colorGetValue(&result)};
colorMask(&result, &humidity_color);
return result;
}

View file

@ -134,13 +134,13 @@ Color atmosphereGetPreview(Renderer* renderer, double x, double y, double headin
hit = m4Transform(rotation, hit); hit = m4Transform(rotation, hit);
color = renderer->applyLightingToSurface(renderer, hit, normal, &MOUNT_MATERIAL); color = renderer->applyLightingToSurface(renderer, hit, normal, &MOUNT_MATERIAL);
return renderer->atmosphere->applyAerialPerspective(renderer, hit, color); return renderer->atmosphere->applyAerialPerspective(renderer, hit, color).final;
} }
else else
{ {
direction = m4Transform(rotation, direction); direction = m4Transform(rotation, direction);
return renderer->atmosphere->getSkyColor(renderer, direction); return renderer->atmosphere->getSkyColor(renderer, direction).final;
} }
} }

View file

@ -12,14 +12,9 @@
#define SUN_RADIUS 6.955e5 #define SUN_RADIUS 6.955e5
#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) #define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING)
Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base);
void basicGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque);
void brunetonInit(); void brunetonInit();
Color brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position); AtmosphereResult brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position, Color base);
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base); AtmosphereResult brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base);
void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque); void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque);
Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
#endif #endif

View file

@ -23,8 +23,7 @@ typedef enum
typedef enum typedef enum
{ {
ATMOSPHERE_MODEL_PREETHAM = 0, ATMOSPHERE_MODEL_BRUNETON = 0
ATMOSPHERE_MODEL_BRUNETON = 1
} AtmosphereModel; } AtmosphereModel;
typedef struct typedef struct
@ -40,9 +39,18 @@ typedef struct
double _daytime; double _daytime;
} AtmosphereDefinition; } AtmosphereDefinition;
typedef struct
{
Color base;
double distance;
Color inscattering;
Color attenuation;
Color final;
} AtmosphereResult;
typedef void (*FuncAtmosphereGetLightingStatus)(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque); typedef void (*FuncAtmosphereGetLightingStatus)(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque);
typedef Color (*FuncAtmosphereApplyAerialPerspective)(Renderer* renderer, Vector3 location, Color base); typedef AtmosphereResult (*FuncAtmosphereApplyAerialPerspective)(Renderer* renderer, Vector3 location, Color base);
typedef Color (*FuncAtmosphereGetSkyColor)(Renderer* renderer, Vector3 direction); typedef AtmosphereResult (*FuncAtmosphereGetSkyColor)(Renderer* renderer, Vector3 direction);
typedef Vector3 (*FuncAtmosphereGetSunDirection)(Renderer* renderer); typedef Vector3 (*FuncAtmosphereGetSunDirection)(Renderer* renderer);
typedef struct typedef struct
@ -61,7 +69,11 @@ extern StandardDefinition AtmosphereDefinitionClass;
extern StandardRenderer AtmosphereRendererClass; extern StandardRenderer AtmosphereRendererClass;
void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset preset); void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset preset);
void atmosphereRenderSkydome(Renderer* renderer); void atmosphereRenderSkydome(Renderer* renderer);
void atmosphereUpdateResult(AtmosphereResult* result);
Renderer* atmosphereCreatePreviewRenderer(); Renderer* atmosphereCreatePreviewRenderer();
Color atmosphereGetPreview(Renderer* renderer, double x, double y, double heading); Color atmosphereGetPreview(Renderer* renderer, double x, double y, double heading);

View file

@ -17,7 +17,7 @@ static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* da
direction = v3Sub(location, camera_location); direction = v3Sub(location, camera_location);
/* TODO Don't compute result->color if it's fully covered by clouds */ /* TODO Don't compute result->color if it's fully covered by clouds */
result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)); result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)).final;
result = renderer->clouds->getColor(renderer, result, camera_location, v3Add(camera_location, v3Scale(direction, 10.0))); result = renderer->clouds->getColor(renderer, result, camera_location, v3Add(camera_location, v3Scale(direction, 10.0)));
return result; return result;

View file

@ -8,18 +8,24 @@
#include "../system.h" #include "../system.h"
/******************** Fake ********************/ /******************** Fake ********************/
static Color _fakeApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) static AtmosphereResult _fakeApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
{ {
AtmosphereResult result;
UNUSED(renderer); UNUSED(renderer);
UNUSED(location); UNUSED(location);
return base; result.base = result.final = base;
result.inscattering = result.attenuation = COLOR_BLACK;
return result;
} }
static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction) static AtmosphereResult _fakeGetSkyColor(Renderer* renderer, Vector3 direction)
{ {
AtmosphereResult result;
UNUSED(renderer); UNUSED(renderer);
UNUSED(direction); UNUSED(direction);
return COLOR_WHITE; result.base = result.final = COLOR_WHITE;
result.inscattering = result.attenuation = COLOR_BLACK;
return result;
} }
static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
@ -51,68 +57,53 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
} }
/******************** Real ********************/ /******************** Real ********************/
static inline Color _applyWeatherEffects(AtmosphereDefinition* definition, Color base, Color scattered, double distance) static inline void _applyWeatherEffects(AtmosphereDefinition* definition, AtmosphereResult* result)
{ {
double max_power = colorGetPower(&scattered); double distance = result->distance;
UNUSED(base);
if (distance > 100.0) if (distance > 100.0)
{ {
distance = 100.0; distance = 100.0;
} }
distance /= 100.0;
scattered.r += distance * 0.02 * definition->humidity; result->inscattering.r += distance * 0.2 * definition->humidity;
scattered.g += distance * 0.02 * definition->humidity; result->inscattering.g += distance * 0.2 * definition->humidity;
scattered.b += distance * 0.02 * definition->humidity; result->inscattering.b += distance * 0.2 * definition->humidity;
colorLimitPower(&scattered, max_power - max_power * 0.4 * definition->humidity); result->attenuation.r *= 1.0 - distance * definition->humidity;
result->attenuation.g *= 1.0 - distance * definition->humidity;
result->attenuation.b *= 1.0 - distance * definition->humidity;
if (definition->humidity > 0.3) atmosphereUpdateResult(result);
{
double humidity = (definition->humidity - 0.3) / 0.7;
scattered.r += distance * 0.1 * humidity * humidity;
scattered.g += distance * 0.1 * humidity * humidity;
scattered.b += distance * 0.1 * humidity * humidity;
colorLimitPower(&scattered, 10.0 - humidity * 4.0);
/*scattered.r *= 1.0 - humidity * 0.8;
scattered.g *= 1.0 - humidity * 0.8;
scattered.b *= 1.0 - humidity * 0.8;*/
} }
return scattered; static AtmosphereResult _realApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
}
static Color _realApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
{ {
AtmosphereDefinition* definition = renderer->atmosphere->definition; AtmosphereDefinition* definition = renderer->atmosphere->definition;
Color changed; AtmosphereResult result;
/* Get base perspective */ /* Get base perspective */
switch (definition->model) switch (definition->model)
{ {
case ATMOSPHERE_MODEL_BRUNETON: case ATMOSPHERE_MODEL_BRUNETON:
changed = brunetonApplyAerialPerspective(renderer, location, base); result = brunetonApplyAerialPerspective(renderer, location, base);
break;
case ATMOSPHERE_MODEL_PREETHAM:
changed = basicApplyAerialPerspective(renderer, location, base);
break; break;
default: default:
; ;
} }
/* Apply weather effects */ /* Apply weather effects */
changed = _applyWeatherEffects(definition, base, changed, v3Norm(v3Sub(location, renderer->getCameraLocation(renderer, location)))); /*_applyWeatherEffects(definition, &result);*/
return changed; return result;
} }
static Color _realGetSkyColor(Renderer* renderer, Vector3 direction) static AtmosphereResult _realGetSkyColor(Renderer* renderer, Vector3 direction)
{ {
AtmosphereDefinition* definition; AtmosphereDefinition* definition;
Vector3 sun_direction, sun_position, camera_location; Vector3 sun_direction, sun_position, camera_location;
Color sky_color, sun_color; Color base;
definition = renderer->atmosphere->definition; definition = renderer->atmosphere->definition;
camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO); camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO);
@ -121,20 +112,8 @@ static Color _realGetSkyColor(Renderer* renderer, Vector3 direction)
direction = v3Normalize(direction); direction = v3Normalize(direction);
sun_position = v3Scale(sun_direction, SUN_DISTANCE_SCALED); sun_position = v3Scale(sun_direction, SUN_DISTANCE_SCALED);
/* Get base scattering*/
switch (definition->model)
{
case ATMOSPHERE_MODEL_BRUNETON:
sky_color = brunetonGetSkyColor(renderer, camera_location, direction, sun_position);
break;
case ATMOSPHERE_MODEL_PREETHAM:
sky_color = preethamGetSkyColor(definition, camera_location, direction, sun_position);
break;
default:
sky_color = COLOR_BLUE;
}
/* Get sun shape */ /* Get sun shape */
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 ? */
@ -144,27 +123,39 @@ static Color _realGetSkyColor(Renderer* renderer, Vector3 direction)
{ {
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) */
sun_color = definition->sun_color; Color sun_color = definition->sun_color;
sun_color.r *= 100.0; sun_color.r *= 100.0;
sun_color.g *= 100.0; sun_color.g *= 100.0;
sun_color.b *= 100.0; sun_color.b *= 100.0;
if (dist > 0.05) if (dist <= 0.05)
{ {
return sun_color; sun_color.r *= 1.0 - dist / 0.05;
} sun_color.g *= 1.0 - dist / 0.05;
else sun_color.b *= 1.0 - dist / 0.05;
{
sun_color.a = 1.0 - dist / 0.05;
colorMask(&sky_color, &sun_color);
} }
base = sun_color;
} }
} }
/* TODO Apply weather effects */ /* TODO Get stars */
sky_color = _applyWeatherEffects(definition, COLOR_BLACK, sky_color, SPHERE_SIZE);
return sky_color; /* Get scattering */
AtmosphereResult result;
Vector3 location = v3Add(camera_location, v3Scale(direction, 6421.0));
switch (definition->model)
{
case ATMOSPHERE_MODEL_BRUNETON:
result = brunetonGetSkyColor(renderer, camera_location, direction, sun_position, base);
break;
default:
result = _fakeApplyAerialPerspective(renderer, location, result.base);
}
/* Apply weather effects */
/*_applyWeatherEffects(definition, &result);*/
return result;
} }
static Vector3 _realGetSunDirection(Renderer* renderer) static Vector3 _realGetSunDirection(Renderer* renderer)
@ -177,6 +168,14 @@ static Vector3 _realGetSunDirection(Renderer* renderer)
return result; return result;
} }
void atmosphereUpdateResult(AtmosphereResult* result)
{
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.b = result->base.b * result->attenuation.b + result->inscattering.b;
result->final.a = 1.0;
}
/******************** Renderer ********************/ /******************** Renderer ********************/
static AtmosphereRenderer* _createRenderer() static AtmosphereRenderer* _createRenderer()
{ {
@ -212,7 +211,7 @@ static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition)
renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus; renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus;
break; break;
default: default:
renderer->atmosphere->getLightingStatus = basicGetLightingStatus; renderer->atmosphere->getLightingStatus = _fakeGetLightingStatus;
} }
} }

View file

@ -289,7 +289,7 @@ Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer*
col.a = inside_length / definition->transparencydepth; col.a = inside_length / definition->transparencydepth;
} }
col = renderer->atmosphere->applyAerialPerspective(renderer, start, col); col = renderer->atmosphere->applyAerialPerspective(renderer, start, col).final;
colorMask(&base, &col); colorMask(&base, &col);

View file

@ -94,7 +94,7 @@ static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vecto
static Color _applyMediumTraversal(Renderer* renderer, Vector3 location, Color color) static Color _applyMediumTraversal(Renderer* renderer, Vector3 location, Color color)
{ {
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color); color = renderer->atmosphere->applyAerialPerspective(renderer, location, color).final;
color = renderer->clouds->getColor(renderer, color, renderer->getCameraLocation(renderer, location), location); color = renderer->clouds->getColor(renderer, color, renderer->getCameraLocation(renderer, location), location);
return color; return color;
} }

View file

@ -182,7 +182,7 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
result = renderer->terrain->castRay(renderer, location, direction); result = renderer->terrain->castRay(renderer, location, direction);
if (!result.hit) if (!result.hit)
{ {
sky_color = renderer->atmosphere->getSkyColor(renderer, direction); sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final;
result.hit = 1; result.hit = 1;
result.hit_location = v3Add(location, v3Scale(direction, 1000.0)); result.hit_location = v3Add(location, v3Scale(direction, 1000.0));