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:
parent
9d7b896c91
commit
56270e9941
15 changed files with 133 additions and 292 deletions
19
cli/main.c
19
cli/main.c
|
@ -1,6 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue