diff --git a/cli/main.c b/cli/main.c index b415e9b..e136e8e 100644 --- a/cli/main.c +++ b/cli/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "../lib_paysages/auto.h" #include "../lib_paysages/main.h" @@ -126,21 +127,29 @@ int main(int argc, char** argv) paysagesLoad(conf_file_path); } - renderer = sceneryCreateStandardRenderer(); - rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate); - for (outputcount = 0; outputcount < conf_nb_pictures; outputcount++) { - /*autoSetDaytimeFraction(conf_daytime_start);*/ /* TODO */ + 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(); + rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate); sprintf(outputpath, "output/pic%05d.png", outputcount); startRender(renderer, outputpath, conf_render_params); + rendererDelete(renderer); + conf_daytime_start += conf_daytime_step; } printf("Cleaning up ...\n"); - rendererDelete(renderer); paysagesQuit(); printf("\rDone. \n"); diff --git a/gui_qt/explorerchunksky.cpp b/gui_qt/explorerchunksky.cpp index 84721e3..46b2292 100644 --- a/gui_qt/explorerchunksky.cpp +++ b/gui_qt/explorerchunksky.cpp @@ -141,5 +141,5 @@ Color ExplorerChunkSky::getTextureColor(double x, double y) { location.y = 0.0; } - return renderer()->atmosphere->getSkyColor(renderer(), location); + return renderer()->atmosphere->getSkyColor(renderer(), location).final; } diff --git a/gui_qt/formatmosphere.cpp b/gui_qt/formatmosphere.cpp index 3d44004..867861d 100644 --- a/gui_qt/formatmosphere.cpp +++ b/gui_qt/formatmosphere.cpp @@ -84,7 +84,7 @@ FormAtmosphere::FormAtmosphere(QWidget *parent): //addInputColor(tr("Sun color"), &_definition->sun_color); 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("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(); } diff --git a/gui_qt/formrender.cpp b/gui_qt/formrender.cpp index dbea1c2..99c34d6 100644 --- a/gui_qt/formrender.cpp +++ b/gui_qt/formrender.cpp @@ -92,9 +92,15 @@ private: 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; } }; diff --git a/lib_paysages/atmosphere/basic.c b/lib_paysages/atmosphere/basic.c deleted file mode 100644 index 7bad9ce..0000000 --- a/lib_paysages/atmosphere/basic.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "private.h" - -#include -#include -#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 */ -} diff --git a/lib_paysages/atmosphere/bruneton.c b/lib_paysages/atmosphere/bruneton.c index 2a64e9a..5fc93a5 100644 --- a/lib_paysages/atmosphere/bruneton.c +++ b/lib_paysages/atmosphere/bruneton.c @@ -1151,7 +1151,7 @@ void brunetonInit() 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; eye.y += yoffset; @@ -1167,18 +1167,26 @@ Color brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Ve double mu = v3Dot(x, v) / r; double t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg); + AtmosphereResult result; 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 */ - sunColor.r = sunColor.r * attenuation.x + inscatterColor.r; - sunColor.g = sunColor.g * attenuation.y + inscatterColor.g; - sunColor.b = sunColor.b * attenuation.z + inscatterColor.b; + result.base.r = base.r + sunColor.r; + result.base.g = base.g + sunColor.g; + 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 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 t = v3Norm(direction); + AtmosphereResult result; 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; - base.g = base.g * attenuation.y + inscatterColor.g; - base.b = base.b * attenuation.z + inscatterColor.b; + result.base = base; + 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.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) diff --git a/lib_paysages/atmosphere/preetham.c b/lib_paysages/atmosphere/preetham.c deleted file mode 100644 index 433e713..0000000 --- a/lib_paysages/atmosphere/preetham.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "public.h" -#include "private.h" - -#include -#include -#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; -} diff --git a/lib_paysages/atmosphere/preview.c b/lib_paysages/atmosphere/preview.c index e15268e..2701195 100644 --- a/lib_paysages/atmosphere/preview.c +++ b/lib_paysages/atmosphere/preview.c @@ -134,13 +134,13 @@ Color atmosphereGetPreview(Renderer* renderer, double x, double y, double headin hit = m4Transform(rotation, hit); color = renderer->applyLightingToSurface(renderer, hit, normal, &MOUNT_MATERIAL); - return renderer->atmosphere->applyAerialPerspective(renderer, hit, color); + return renderer->atmosphere->applyAerialPerspective(renderer, hit, color).final; } else { direction = m4Transform(rotation, direction); - return renderer->atmosphere->getSkyColor(renderer, direction); + return renderer->atmosphere->getSkyColor(renderer, direction).final; } } diff --git a/lib_paysages/atmosphere/private.h b/lib_paysages/atmosphere/private.h index 0550b2e..ced237b 100644 --- a/lib_paysages/atmosphere/private.h +++ b/lib_paysages/atmosphere/private.h @@ -12,14 +12,9 @@ #define SUN_RADIUS 6.955e5 #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(); -Color brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position); -Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base); +AtmosphereResult brunetonGetSkyColor(Renderer* renderer, Vector3 eye, Vector3 direction, Vector3 sun_position, Color base); +AtmosphereResult brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base); void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque); -Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position); - #endif diff --git a/lib_paysages/atmosphere/public.h b/lib_paysages/atmosphere/public.h index 23957f3..dd925bc 100644 --- a/lib_paysages/atmosphere/public.h +++ b/lib_paysages/atmosphere/public.h @@ -23,8 +23,7 @@ typedef enum typedef enum { - ATMOSPHERE_MODEL_PREETHAM = 0, - ATMOSPHERE_MODEL_BRUNETON = 1 + ATMOSPHERE_MODEL_BRUNETON = 0 } AtmosphereModel; typedef struct @@ -40,9 +39,18 @@ typedef struct double _daytime; } 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 Color (*FuncAtmosphereApplyAerialPerspective)(Renderer* renderer, Vector3 location, Color base); -typedef Color (*FuncAtmosphereGetSkyColor)(Renderer* renderer, Vector3 direction); +typedef AtmosphereResult (*FuncAtmosphereApplyAerialPerspective)(Renderer* renderer, Vector3 location, Color base); +typedef AtmosphereResult (*FuncAtmosphereGetSkyColor)(Renderer* renderer, Vector3 direction); typedef Vector3 (*FuncAtmosphereGetSunDirection)(Renderer* renderer); typedef struct @@ -61,7 +69,11 @@ extern StandardDefinition AtmosphereDefinitionClass; extern StandardRenderer AtmosphereRendererClass; void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset preset); + void atmosphereRenderSkydome(Renderer* renderer); + +void atmosphereUpdateResult(AtmosphereResult* result); + Renderer* atmosphereCreatePreviewRenderer(); Color atmosphereGetPreview(Renderer* renderer, double x, double y, double heading); diff --git a/lib_paysages/atmosphere/raster.c b/lib_paysages/atmosphere/raster.c index 32a741d..d36521c 100644 --- a/lib_paysages/atmosphere/raster.c +++ b/lib_paysages/atmosphere/raster.c @@ -17,7 +17,7 @@ static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* da direction = v3Sub(location, camera_location); /* 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))); return result; diff --git a/lib_paysages/atmosphere/render.c b/lib_paysages/atmosphere/render.c index 417df85..957a6ba 100644 --- a/lib_paysages/atmosphere/render.c +++ b/lib_paysages/atmosphere/render.c @@ -8,18 +8,24 @@ #include "../system.h" /******************** Fake ********************/ -static Color _fakeApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) +static AtmosphereResult _fakeApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) { + AtmosphereResult result; UNUSED(renderer); 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(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) @@ -51,68 +57,53 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect } /******************** 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); - - UNUSED(base); + double distance = result->distance; if (distance > 100.0) { distance = 100.0; } + distance /= 100.0; - scattered.r += distance * 0.02 * definition->humidity; - scattered.g += distance * 0.02 * definition->humidity; - scattered.b += distance * 0.02 * definition->humidity; + result->inscattering.r += distance * 0.2 * definition->humidity; + result->inscattering.g += distance * 0.2 * 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) - { - 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; + atmosphereUpdateResult(result); } -static Color _realApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) +static AtmosphereResult _realApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) { AtmosphereDefinition* definition = renderer->atmosphere->definition; - Color changed; + AtmosphereResult result; /* Get base perspective */ switch (definition->model) { case ATMOSPHERE_MODEL_BRUNETON: - changed = brunetonApplyAerialPerspective(renderer, location, base); - break; - case ATMOSPHERE_MODEL_PREETHAM: - changed = basicApplyAerialPerspective(renderer, location, base); + result = brunetonApplyAerialPerspective(renderer, location, base); break; default: ; } /* 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; Vector3 sun_direction, sun_position, camera_location; - Color sky_color, sun_color; + Color base; definition = renderer->atmosphere->definition; camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO); @@ -121,20 +112,8 @@ static Color _realGetSkyColor(Renderer* renderer, Vector3 direction) direction = v3Normalize(direction); 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 */ + base = COLOR_BLACK; if (v3Dot(sun_direction, direction) >= 0) { 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) */ - sun_color = definition->sun_color; + Color sun_color = definition->sun_color; sun_color.r *= 100.0; sun_color.g *= 100.0; sun_color.b *= 100.0; - if (dist > 0.05) + if (dist <= 0.05) { - return sun_color; - } - else - { - sun_color.a = 1.0 - dist / 0.05; - colorMask(&sky_color, &sun_color); + sun_color.r *= 1.0 - dist / 0.05; + sun_color.g *= 1.0 - dist / 0.05; + sun_color.b *= 1.0 - dist / 0.05; } + base = sun_color; } } - /* TODO Apply weather effects */ - sky_color = _applyWeatherEffects(definition, COLOR_BLACK, sky_color, SPHERE_SIZE); + /* TODO Get stars */ - 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) @@ -177,6 +168,14 @@ static Vector3 _realGetSunDirection(Renderer* renderer) 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 ********************/ static AtmosphereRenderer* _createRenderer() { @@ -212,7 +211,7 @@ static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition) renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus; break; default: - renderer->atmosphere->getLightingStatus = basicGetLightingStatus; + renderer->atmosphere->getLightingStatus = _fakeGetLightingStatus; } } diff --git a/lib_paysages/clouds/tools.c b/lib_paysages/clouds/tools.c index 5eadc6b..dd34015 100644 --- a/lib_paysages/clouds/tools.c +++ b/lib_paysages/clouds/tools.c @@ -289,7 +289,7 @@ Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* col.a = inside_length / definition->transparencydepth; } - col = renderer->atmosphere->applyAerialPerspective(renderer, start, col); + col = renderer->atmosphere->applyAerialPerspective(renderer, start, col).final; colorMask(&base, &col); diff --git a/lib_paysages/renderer.c b/lib_paysages/renderer.c index 2079c9b..39ea329 100644 --- a/lib_paysages/renderer.c +++ b/lib_paysages/renderer.c @@ -94,7 +94,7 @@ static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vecto 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); return color; } diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index 7e09826..d7ccfd8 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -182,7 +182,7 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector result = renderer->terrain->castRay(renderer, location, direction); if (!result.hit) { - sky_color = renderer->atmosphere->getSkyColor(renderer, direction); + sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final; result.hit = 1; result.hit_location = v3Add(location, v3Scale(direction, 1000.0));