paysages : Preetham approximation for sky (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@356 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-06-22 22:13:55 +00:00 committed by ThunderK
parent 05f2c19ef6
commit 4a6d9bb001
10 changed files with 207 additions and 111 deletions

8
TODO
View file

@ -1,5 +1,13 @@
Technology Preview 2 : Technology Preview 2 :
- Finalize Preetham's model usage
=> Add enumarate to choose model in formsky
=> Hide fields based on chosen model
=> Update all fields when "auto from daytime" is selected
=> Apply the skydome lighting by directly sampling it (no more amplitude in lights)
=> Apply model to atmosphere (aerial perspective)
=> Find a proper model for night sky (maybe Shirley)
- InputInt doesn't honor small_step. - InputInt doesn't honor small_step.
- Disable form fields when no layer is selected.
- Remove color gradations (replace with automatic boolean and simple colors). - Remove color gradations (replace with automatic boolean and simple colors).
- Replace zone ranges with curves (with curve input and curve dialog). - Replace zone ranges with curves (with curve input and curve dialog).
- Interface for textures thickness, slope_range and thickness_transparency (and correct slider ranges). - Interface for textures thickness, slope_range and thickness_transparency (and correct slider ranges).

View file

@ -10,7 +10,7 @@ FormMaterial::FormMaterial(QWidget* parent, SurfaceMaterial* material) : BaseFor
addInputColor(tr("Base color"), &_material.base); addInputColor(tr("Base color"), &_material.base);
addInputDouble(tr("Light reflection"), &_material.reflection, 0.0, 1.0, 0.01, 0.1); addInputDouble(tr("Light reflection"), &_material.reflection, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Light reflection shininess"), &_material.shininess, 0.0, 20.0, 0.1, 1.0); addInputDouble(tr("Light reflection shininess"), &_material.shininess, 0.0, 30.0, 0.1, 1.0);
_preview_color = new PreviewMaterial(this, &_material); _preview_color = new PreviewMaterial(this, &_material);
addPreview(_preview_color, tr("Lighting preview")); addPreview(_preview_color, tr("Lighting preview"));

View file

@ -104,15 +104,17 @@ FormSky::FormSky(QWidget *parent):
previewEast = new PreviewSkyEast(this); previewEast = new PreviewSkyEast(this);
addPreview(previewEast, QString(tr("East preview"))); addPreview(previewEast, QString(tr("East preview")));
addInputDouble(tr("Day time"), &_definition.daytime, 0.0, 1.0, 0.01, 0.1); addInputDouble(tr("Day time"), &_definition.daytime, 0.0, 1.0, 0.002, 0.1);
addInputColorGradation(tr("Sun color"), _definition.sun_color); addInputColor(tr("Sun color"), &_definition.sun_color);
addInputDouble(tr("Sun radius"), &_definition.sun_radius, 0.0, 0.4, 0.004, 0.04); addInputDouble(tr("Sun radius"), &_definition.sun_radius, 0.0, 0.4, 0.004, 0.04);
addInputDouble(tr("Sun halo radius"), &_definition.sun_halo_size, 0.0, 0.4, 0.004, 0.04); addInputDouble(tr("Sun halo radius"), &_definition.sun_halo_size, 0.0, 0.4, 0.004, 0.04);
addInputCurve(tr("Sun halo profile"), _definition.sun_halo_profile, 0.0, 1.0, 0.0, 1.0); addInputCurve(tr("Sun halo profile"), _definition.sun_halo_profile, 0.0, 1.0, 0.0, 1.0);
addInputColorGradation(tr("Zenith color"), _definition.zenith_color); addInputBoolean(tr("Auto from daytime"), &_definition.model_custom.auto_from_daytime);
addInputColorGradation(tr("Haze color"), _definition.haze_color); addInputColor(tr("Zenith color"), &_definition.model_custom.zenith_color);
addInputDouble(tr("Haze height"), &_definition.haze_height, 0.0, 1.0, 0.01, 0.1); addInputColor(tr("Haze color"), &_definition.model_custom.haze_color);
addInputDouble(tr("Haze smoothing"), &_definition.haze_smoothing, 0.0, 1.0, 0.01, 0.1); addInputDouble(tr("Haze height"), &_definition.model_custom.haze_height, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Haze smoothing"), &_definition.model_custom.haze_smoothing, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Turbidity"), &_definition.model_preetham.turbidity, 1.8, 6.0, 0.05, 0.5);
revertConfig(); revertConfig();
} }

View file

@ -628,21 +628,31 @@ Maintenir Ctrl : Plus rapide</translation>
</message> </message>
<message> <message>
<location filename="../gui_qt/formsky.cpp" line="112"/> <location filename="../gui_qt/formsky.cpp" line="112"/>
<source>Auto from daytime</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="117"/>
<source>Turbidity</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui_qt/formsky.cpp" line="113"/>
<source>Zenith color</source> <source>Zenith color</source>
<translation>Couleur du ciel au zénith</translation> <translation>Couleur du ciel au zénith</translation>
</message> </message>
<message> <message>
<location filename="../gui_qt/formsky.cpp" line="113"/> <location filename="../gui_qt/formsky.cpp" line="114"/>
<source>Haze color</source> <source>Haze color</source>
<translation>Couleur de la brume</translation> <translation>Couleur de la brume</translation>
</message> </message>
<message> <message>
<location filename="../gui_qt/formsky.cpp" line="114"/> <location filename="../gui_qt/formsky.cpp" line="115"/>
<source>Haze height</source> <source>Haze height</source>
<translation>Hauteur apparente de la brume</translation> <translation>Hauteur apparente de la brume</translation>
</message> </message>
<message> <message>
<location filename="../gui_qt/formsky.cpp" line="115"/> <location filename="../gui_qt/formsky.cpp" line="116"/>
<source>Haze smoothing</source> <source>Haze smoothing</source>
<translation>Facteur de lissage de la brume</translation> <translation>Facteur de lissage de la brume</translation>
</message> </message>

View file

@ -77,7 +77,7 @@ void atmosphereValidateDefinition(AtmosphereDefinition* definition)
{ {
sky = skyCreateDefinition(); sky = skyCreateDefinition();
sceneryGetSky(&sky); sceneryGetSky(&sky);
definition->color = colorGradationGet(sky.haze_color, sky.daytime); definition->color = sky.model_custom.haze_color;
skyDeleteDefinition(&sky); skyDeleteDefinition(&sky);
} }
} }

View file

@ -82,17 +82,17 @@ void autoGenRealisticLandscape(int seed)
water = waterCreateDefinition(); water = waterCreateDefinition();
water.height = -5.0; water.height = -5.0;
water.transparency = 0.5; water.transparency = 0.5;
water.reflection = 0.3; water.reflection = 0.4;
water.transparency_depth = 6.0; water.transparency_depth = 6.0;
water.material.base.r = 0.1; water.material.base.r = 0.05;
water.material.base.g = 0.3; water.material.base.g = 0.15;
water.material.base.b = 0.4; water.material.base.b = 0.2;
water.material.base.a = 1.0; water.material.base.a = 1.0;
water.material.reflection = 1.0; water.material.reflection = 1.0;
water.material.shininess = 12.0; water.material.shininess = 16.0;
water.depth_color.r = 0.0; water.depth_color.r = 0.0;
water.depth_color.g = 0.2; water.depth_color.g = 0.1;
water.depth_color.b = 0.3; water.depth_color.b = 0.1;
water.depth_color.a = 1.0; water.depth_color.a = 1.0;
water.lighting_depth = 3.0; water.lighting_depth = 3.0;
water.waves_noise_height = 0.005; water.waves_noise_height = 0.005;
@ -106,32 +106,30 @@ void autoGenRealisticLandscape(int seed)
/* Sky */ /* Sky */
sky = skyCreateDefinition(); sky = skyCreateDefinition();
colorGradationQuickAddRgb(sky.sun_color, 0.3, 1.0, 0.91, 0.8); sky.model = SKY_MODEL_PREETHAM;
colorGradationQuickAddRgb(sky.sun_color, 0.5, 1.0, 0.95, 0.9);
colorGradationQuickAddRgb(sky.sun_color, 0.7, 1.0, 0.91, 0.8);
colorGradationQuickAddRgb(sky.zenith_color, 0.2, 0.03, 0.03, 0.05);
colorGradationQuickAddRgb(sky.zenith_color, 0.25, 0.25, 0.33, 0.37);
colorGradationQuickAddRgb(sky.zenith_color, 0.35, 0.52, 0.63, 0.8);
colorGradationQuickAddRgb(sky.zenith_color, 0.65, 0.52, 0.63, 0.8);
colorGradationQuickAddRgb(sky.zenith_color, 0.75, 0.25, 0.33, 0.37);
colorGradationQuickAddRgb(sky.zenith_color, 0.8, 0.03, 0.03, 0.05);
colorGradationQuickAddRgb(sky.haze_color, 0.2, 0.05, 0.05, 0.08);
colorGradationQuickAddRgb(sky.haze_color, 0.25, 0.55, 0.42, 0.42);
colorGradationQuickAddRgb(sky.haze_color, 0.3, 0.6, 0.6, 0.6);
colorGradationQuickAddRgb(sky.haze_color, 0.4, 0.92, 0.93, 1.0);
colorGradationQuickAddRgb(sky.haze_color, 0.6, 0.92, 0.93, 1.0);
colorGradationQuickAddRgb(sky.haze_color, 0.7, 0.6, 0.6, 0.8);
colorGradationQuickAddRgb(sky.haze_color, 0.75, 0.62, 0.50, 0.42);
colorGradationQuickAddRgb(sky.haze_color, 0.8, 0.05, 0.05, 0.08);
sky.daytime = 0.0; sky.daytime = 0.0;
sky.haze_height = 0.75; sky.sun_color.r = 1.0;
sky.haze_smoothing = 0.3; sky.sun_color.g = 0.95;
sky.sun_color.b = 0.9;
sky.sun_color.a = 1.0;
sky.sun_radius = 0.02; sky.sun_radius = 0.02;
sky.sun_halo_size = 0.3; sky.sun_halo_size = 0.3;
curveClear(sky.sun_halo_profile); curveClear(sky.sun_halo_profile);
curveQuickAddPoint(sky.sun_halo_profile, 0.0, 1.0); curveQuickAddPoint(sky.sun_halo_profile, 0.0, 1.0);
curveQuickAddPoint(sky.sun_halo_profile, 0.1, 0.2); curveQuickAddPoint(sky.sun_halo_profile, 0.1, 0.2);
curveQuickAddPoint(sky.sun_halo_profile, 1.0, 0.0); curveQuickAddPoint(sky.sun_halo_profile, 1.0, 0.0);
sky.model_custom.auto_from_daytime = 1;
sky.model_custom.zenith_color.r = 0.52;
sky.model_custom.zenith_color.g = 0.63;
sky.model_custom.zenith_color.b = 0.8;
sky.model_custom.zenith_color.a = 1.0;
sky.model_custom.haze_color.r = 0.92;
sky.model_custom.haze_color.g = 0.93;
sky.model_custom.haze_color.b = 1.0;
sky.model_custom.haze_color.a = 1.0;
sky.model_custom.haze_height = 0.75;
sky.model_custom.haze_smoothing = 0.3;
sky.model_preetham.turbidity = 2.0;
scenerySetSky(&sky); scenerySetSky(&sky);
skyDeleteDefinition(&sky); skyDeleteDefinition(&sky);

View file

@ -136,6 +136,13 @@ void colorGradationCopy(ColorGradation* source, ColorGradation* destination)
curveCopy(source->blue, destination->blue); curveCopy(source->blue, destination->blue);
} }
void colorGradationClear(ColorGradation* gradation)
{
curveClear(gradation->red);
curveClear(gradation->green);
curveClear(gradation->blue);
}
void colorGradationSave(PackStream* stream, ColorGradation* gradation) void colorGradationSave(PackStream* stream, ColorGradation* gradation)
{ {
curveSave(stream, gradation->red); curveSave(stream, gradation->red);

View file

@ -42,6 +42,7 @@ typedef struct ColorGradation ColorGradation;
ColorGradation* colorGradationCreate(); ColorGradation* colorGradationCreate();
void colorGradationDelete(ColorGradation* gradation); void colorGradationDelete(ColorGradation* gradation);
void colorGradationCopy(ColorGradation* source, ColorGradation* destination); void colorGradationCopy(ColorGradation* source, ColorGradation* destination);
void colorGradationClear(ColorGradation* gradation);
void colorGradationSave(PackStream* stream, ColorGradation* gradation); void colorGradationSave(PackStream* stream, ColorGradation* gradation);
void colorGradationLoad(PackStream* stream, ColorGradation* gradation); void colorGradationLoad(PackStream* stream, ColorGradation* gradation);

View file

@ -13,6 +13,7 @@
#define SPHERE_SIZE 1000.0 #define SPHERE_SIZE 1000.0
/******************************** Configuration ********************************/
void skyInit() void skyInit()
{ {
} }
@ -23,28 +24,38 @@ void skyQuit()
void skySave(PackStream* stream, SkyDefinition* definition) void skySave(PackStream* stream, SkyDefinition* definition)
{ {
packWriteInt(stream, (int*)&definition->model);
packWriteDouble(stream, &definition->daytime); packWriteDouble(stream, &definition->daytime);
colorGradationSave(stream, definition->sun_color); colorSave(stream, &definition->sun_color);
packWriteDouble(stream, &definition->sun_radius); packWriteDouble(stream, &definition->sun_radius);
packWriteDouble(stream, &definition->sun_halo_size); packWriteDouble(stream, &definition->sun_halo_size);
curveSave(stream, definition->sun_halo_profile); curveSave(stream, definition->sun_halo_profile);
colorGradationSave(stream, definition->zenith_color);
colorGradationSave(stream, definition->haze_color); packWriteInt(stream, &definition->model_custom.auto_from_daytime);
packWriteDouble(stream, &definition->haze_height); colorSave(stream, &definition->model_custom.zenith_color);
packWriteDouble(stream, &definition->haze_smoothing); colorSave(stream, &definition->model_custom.haze_color);
packWriteDouble(stream, &definition->model_custom.haze_height);
packWriteDouble(stream, &definition->model_custom.haze_smoothing);
packWriteDouble(stream, &definition->model_preetham.turbidity);
} }
void skyLoad(PackStream* stream, SkyDefinition* definition) void skyLoad(PackStream* stream, SkyDefinition* definition)
{ {
packReadInt(stream, (int*)&definition->model);
packReadDouble(stream, &definition->daytime); packReadDouble(stream, &definition->daytime);
colorGradationLoad(stream, definition->sun_color); colorLoad(stream, &definition->sun_color);
packReadDouble(stream, &definition->sun_radius); packReadDouble(stream, &definition->sun_radius);
packReadDouble(stream, &definition->sun_halo_size); packReadDouble(stream, &definition->sun_halo_size);
curveLoad(stream, definition->sun_halo_profile); curveLoad(stream, definition->sun_halo_profile);
colorGradationLoad(stream, definition->zenith_color);
colorGradationLoad(stream, definition->haze_color); packReadInt(stream, &definition->model_custom.auto_from_daytime);
packReadDouble(stream, &definition->haze_height); colorLoad(stream, &definition->model_custom.zenith_color);
packReadDouble(stream, &definition->haze_smoothing); colorLoad(stream, &definition->model_custom.haze_color);
packReadDouble(stream, &definition->model_custom.haze_height);
packReadDouble(stream, &definition->model_custom.haze_smoothing);
packReadDouble(stream, &definition->model_preetham.turbidity);
skyValidateDefinition(definition); skyValidateDefinition(definition);
} }
@ -53,15 +64,19 @@ SkyDefinition skyCreateDefinition()
{ {
SkyDefinition def; SkyDefinition def;
def.model = SKY_MODEL_CUSTOM;
def.daytime = 0.0; def.daytime = 0.0;
def.sun_color = colorGradationCreate(); def.sun_color = COLOR_BLACK;
def.sun_radius = 1.0; def.sun_radius = 1.0;
def.sun_halo_size = 0.0; def.sun_halo_size = 0.0;
def.sun_halo_profile = curveCreate(); def.sun_halo_profile = curveCreate();
def.zenith_color = colorGradationCreate(); def.model_custom.auto_from_daytime = 0;
def.haze_color = colorGradationCreate(); def.model_custom.zenith_color = COLOR_BLACK;
def.haze_height = 0.0; def.model_custom.haze_color = COLOR_BLACK;
def.haze_smoothing = 0.0; def.model_custom.haze_height = 0.0;
def.model_custom.haze_smoothing = 0.0;
def.model_custom._sky_gradation = colorGradationCreate();
def.model_preetham.turbidity = 0.0;
skyValidateDefinition(&def); skyValidateDefinition(&def);
@ -71,39 +86,72 @@ SkyDefinition skyCreateDefinition()
void skyDeleteDefinition(SkyDefinition* definition) void skyDeleteDefinition(SkyDefinition* definition)
{ {
curveDelete(definition->sun_halo_profile); curveDelete(definition->sun_halo_profile);
colorGradationDelete(definition->sun_color); colorGradationDelete(definition->model_custom._sky_gradation);
colorGradationDelete(definition->zenith_color);
colorGradationDelete(definition->haze_color);
} }
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination) void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination)
{ {
destination->model = source->model;
destination->daytime = source->daytime; destination->daytime = source->daytime;
destination->sun_color = source->sun_color;
destination->sun_radius = source->sun_radius; destination->sun_radius = source->sun_radius;
destination->sun_halo_size = source->sun_halo_size; destination->sun_halo_size = source->sun_halo_size;
destination->haze_height = source->haze_height; destination->model_custom.auto_from_daytime = source->model_custom.auto_from_daytime;
destination->haze_smoothing = source->haze_smoothing; destination->model_custom.zenith_color = source->model_custom.zenith_color;
destination->model_custom.haze_color = source->model_custom.haze_color;
destination->model_custom.haze_height = source->model_custom.haze_height;
destination->model_custom.haze_smoothing = source->model_custom.haze_smoothing;
destination->model_preetham.turbidity = source->model_preetham.turbidity;
curveCopy(source->sun_halo_profile, destination->sun_halo_profile); curveCopy(source->sun_halo_profile, destination->sun_halo_profile);
colorGradationCopy(source->sun_color, destination->sun_color); skyValidateDefinition(destination);
colorGradationCopy(source->zenith_color, destination->zenith_color); }
colorGradationCopy(source->haze_color, destination->haze_color);
colorGradationCopy(source->_sky_gradation, destination->_sky_gradation); static void _setAutoCustomModel(SkyDefinition* definition)
{
ColorGradation* zenith_gradation;
ColorGradation* haze_gradation;
zenith_gradation = colorGradationCreate();
haze_gradation = colorGradationCreate();
colorGradationQuickAddRgb(zenith_gradation, 0.2, 0.03, 0.03, 0.05);
colorGradationQuickAddRgb(zenith_gradation, 0.25, 0.25, 0.33, 0.37);
colorGradationQuickAddRgb(zenith_gradation, 0.35, 0.52, 0.63, 0.8);
colorGradationQuickAddRgb(zenith_gradation, 0.65, 0.52, 0.63, 0.8);
colorGradationQuickAddRgb(zenith_gradation, 0.75, 0.25, 0.33, 0.37);
colorGradationQuickAddRgb(zenith_gradation, 0.8, 0.03, 0.03, 0.05);
colorGradationQuickAddRgb(haze_gradation, 0.2, 0.05, 0.05, 0.08);
colorGradationQuickAddRgb(haze_gradation, 0.25, 0.55, 0.42, 0.42);
colorGradationQuickAddRgb(haze_gradation, 0.3, 0.6, 0.6, 0.6);
colorGradationQuickAddRgb(haze_gradation, 0.4, 0.92, 0.93, 1.0);
colorGradationQuickAddRgb(haze_gradation, 0.6, 0.92, 0.93, 1.0);
colorGradationQuickAddRgb(haze_gradation, 0.7, 0.6, 0.6, 0.8);
colorGradationQuickAddRgb(haze_gradation, 0.75, 0.62, 0.50, 0.42);
colorGradationQuickAddRgb(haze_gradation, 0.8, 0.05, 0.05, 0.08);
definition->model_custom.zenith_color = colorGradationGet(zenith_gradation, definition->daytime);
definition->model_custom.haze_color = colorGradationGet(haze_gradation, definition->daytime);
colorGradationDelete(zenith_gradation);
colorGradationDelete(haze_gradation);
} }
void skyValidateDefinition(SkyDefinition* definition) void skyValidateDefinition(SkyDefinition* definition)
{ {
Color zenith, haze; if (definition->model == SKY_MODEL_CUSTOM)
{
zenith = colorGradationGet(definition->zenith_color, definition->daytime); if (definition->model_custom.auto_from_daytime)
haze = colorGradationGet(definition->haze_color, definition->daytime); {
_setAutoCustomModel(definition);
definition->_sky_gradation = colorGradationCreate(); }
colorGradationQuickAdd(definition->_sky_gradation, 0.0, &haze); colorGradationClear(definition->model_custom._sky_gradation);
colorGradationQuickAdd(definition->_sky_gradation, definition->haze_height - definition->haze_smoothing, &haze); colorGradationQuickAdd(definition->model_custom._sky_gradation, 0.0, &definition->model_custom.haze_color);
colorGradationQuickAdd(definition->_sky_gradation, definition->haze_height, &zenith); colorGradationQuickAdd(definition->model_custom._sky_gradation, definition->model_custom.haze_height - definition->model_custom.haze_smoothing, &definition->model_custom.haze_color);
colorGradationQuickAdd(definition->_sky_gradation, 1.0, &zenith); colorGradationQuickAdd(definition->model_custom._sky_gradation, definition->model_custom.haze_height, &definition->model_custom.zenith_color);
colorGradationQuickAdd(definition->model_custom._sky_gradation, 1.0, &definition->model_custom.zenith_color);
}
} }
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights) int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
@ -123,7 +171,7 @@ int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
{ {
/* Light from the sun */ /* Light from the sun */
lights[0].direction = v3Scale(sun_direction, -1.0); lights[0].direction = v3Scale(sun_direction, -1.0);
lights[0].color = colorGradationGet(sky->sun_color, sky->daytime); lights[0].color = sky->sun_color;
lights[0].reflection = 1.0; lights[0].reflection = 1.0;
lights[0].filtered = 1; lights[0].filtered = 1;
lights[0].masked = 1; lights[0].masked = 1;
@ -135,7 +183,7 @@ int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
lights[1].direction.x = 0.0; lights[1].direction.x = 0.0;
lights[1].direction.y = -1.0; lights[1].direction.y = -1.0;
lights[1].direction.z = 0.0; lights[1].direction.z = 0.0;
lights[1].color = colorGradationGet(sky->zenith_color, sky->daytime); lights[1].color = sky->model_custom.zenith_color;
lights[1].color.r *= 0.6; lights[1].color.r *= 0.6;
lights[1].color.g *= 0.6; lights[1].color.g *= 0.6;
lights[1].color.b *= 0.6; lights[1].color.b *= 0.6;
@ -150,6 +198,7 @@ int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
return nblights; return nblights;
} }
/******************************** Preetham Model ********************************/
static inline double _angleBetween(double thetav, double phiv, double theta, double phi) 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); double cospsi = sin(thetav) * sin(theta) * cos(phi-phiv) + cos(thetav) * cos(theta);
@ -158,29 +207,28 @@ static inline double _angleBetween(double thetav, double phiv, double theta, dou
return acos(cospsi); return acos(cospsi);
} }
static inline Color _toColor(float x, float y, float Y) static inline Color _xyYToRGB(double x, double y, double Y)
{ {
float fX, fY, fZ; double fX, fY, fZ;
Color result; Color result;
fY = Y; fY = Y;
fX = x / y * Y; fX = x / y * Y;
fZ = ((1.0f - x - y) / y) * Y; fZ = ((1.0 - x - y) / y) * Y;
float r, g, b; 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;
r = 3.2404f * fX - 1.5371f * fY - 0.4985f * fZ; double expo = -(1.0 / 10000.0);
g = -0.9692f * fX + 1.8759f * fY + 0.0415f * fZ; r = 1.0 - exp(expo * r);
b = 0.0556f * fX - 0.2040f * fY + 1.0573f * fZ; g = 1.0 - exp(expo * g);
b = 1.0 - exp(expo * b);
float expo = -(1.0f / 10000.0f); if (r < 0.0) r = 0.0;
r = 1.0f - exp(expo * r); if (g < 0.0) g = 0.0;
g = 1.0f - exp(expo * g); if (b < 0.0) b = 0.0;
b = 1.0f - exp(expo * b);
if (r < 0.0f) r = 0.0f;
if (g < 0.0f) g = 0.0f;
if (b < 0.0f) b = 0.0f;
result.r = r; result.r = r;
result.g = g; result.g = g;
@ -197,7 +245,7 @@ static Color _preethamApproximate(SkyDefinition* definition, double theta, doubl
double thetaSun; double thetaSun;
double phiSun; double phiSun;
double gamma; double gamma;
double turbidity = 2.0; double turbidity = definition->model_preetham.turbidity;
/* Handle angles */ /* Handle angles */
if (theta > M_PI / 2.0) if (theta > M_PI / 2.0)
@ -262,26 +310,27 @@ static Color _preethamApproximate(SkyDefinition* definition, double theta, doubl
(-0.04214 * suntheta3 + 0.08970 * suntheta2 - 0.04153 * suntheta + 0.00516) * T + (-0.04214 * suntheta3 + 0.08970 * suntheta2 - 0.04153 * suntheta + 0.00516) * T +
( 0.15346 * suntheta3 - 0.26756 * suntheta2 + 0.06670 * suntheta + 0.26688); ( 0.15346 * suntheta3 - 0.26756 * suntheta2 + 0.06670 * suntheta + 0.26688);
double X = (4.0f / 9.0f - T / 120.0f) * (M_PI - 2.0 * suntheta); double X = (4.0 / 9.0 - T / 120.0) * (M_PI - 2.0 * suntheta);
double Yz = ((4.0453f * T - 4.9710) * tan(X) - 0.2155 * T + 2.4192) * 1000.0f; double Yz = ((4.0453 * T - 4.9710) * tan(X) - 0.2155 * T + 2.4192) * 1000.0;
double val1, val2; double val1, val2;
val1 = ( 1 + Ax * exp(Bx / cosTheta ) ) * ( 1 + Cx * exp(Dx * gamma) + Ex * sqrt(cosGamma) ); val1 = (1.0 + Ax * exp(Bx / cosTheta)) * (1.0 + Cx * exp(Dx * gamma) + Ex * sqrt(cosGamma));
val2 = ( 1 + Ax * exp(Bx) ) * ( 1 + Cx * exp(Dx * suntheta) + Ex * sqrt(cosSTheta) ); val2 = (1.0 + Ax * exp(Bx)) * (1.0 + Cx * exp(Dx * suntheta) + Ex * sqrt(cosSTheta));
double x = xz * val1 / val2; double x = xz * val1 / val2;
val1 = ( 1 + Ay * exp(By / cosTheta) ) * ( 1 + Cy * exp(Dy * gamma ) + Ey * sqrt(cosGamma ) ); val1 = (1.0 + Ay * exp(By / cosTheta)) * (1.0 + Cy * exp(Dy * gamma) + Ey * sqrt(cosGamma));
val2 = ( 1 + Ay * exp(By ) ) * ( 1 + Cy * exp(Dy * suntheta) + Ey * sqrt(cosSTheta) ); val2 = (1.0 + Ay * exp(By)) * (1.0 + Cy * exp(Dy * suntheta) + Ey * sqrt(cosSTheta));
double y = yz * val1 / val2; double y = yz * val1 / val2;
val1 = ( 1 + AY * exp(BY / cosTheta) ) * ( 1 + CY * exp(DY * gamma ) + EY * sqrt(cosGamma) ); val1 = (1.0 + AY * exp(BY / cosTheta)) * (1.0 + CY * exp(DY * gamma) + EY * sqrt(cosGamma));
val2 = ( 1 + AY * exp(BY ) ) * ( 1 + CY * exp(DY * suntheta) + EY * sqrt(cosSTheta) ); val2 = (1.0 + AY * exp(BY)) * (1.0 + CY * exp(DY * suntheta) + EY * sqrt(cosSTheta));
double Y = Yz * val1 / val2; double Y = Yz * val1 / val2;
return _toColor(x, y, Y); return _xyYToRGB(x, y, Y);
} }
/******************************** Rendering ********************************/
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look) Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look)
{ {
double dist; double dist;
@ -293,10 +342,18 @@ Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Ve
look = v3Normalize(look); look = v3Normalize(look);
dist = v3Norm(v3Sub(look, sun_position)); dist = v3Norm(v3Sub(look, sun_position));
sky_color = _preethamApproximate(definition, M_PI/2.0 - asin(look.y), atan2(-look.z, look.x)); if (definition->model == SKY_MODEL_PREETHAM)
{
sky_color = _preethamApproximate(definition, M_PI/2.0 - asin(look.y), atan2(-look.z, look.x));
}
else
{
sky_color = colorGradationGet(definition->model_custom._sky_gradation, look.y * 0.5 + 0.5);
}
if (dist < definition->sun_radius + definition->sun_halo_size) if (dist < definition->sun_radius + definition->sun_halo_size)
{ {
sun_color = colorGradationGet(definition->sun_color, definition->daytime); sun_color = definition->sun_color;
if (dist <= definition->sun_radius) if (dist <= definition->sun_radius)
{ {
return sun_color; return sun_color;
@ -396,10 +453,10 @@ Vector3 skyGetSunDirection(SkyDefinition* definition)
Color skyGetSunColor(SkyDefinition* definition) Color skyGetSunColor(SkyDefinition* definition)
{ {
return colorGradationGet(definition->sun_color, definition->daytime); return definition->sun_color;
} }
Color skyGetZenithColor(SkyDefinition* definition) Color skyGetZenithColor(SkyDefinition* definition)
{ {
return colorGradationGet(definition->zenith_color, definition->daytime); return definition->model_custom.zenith_color;
} }

View file

@ -10,18 +10,31 @@
extern "C" { extern "C" {
#endif #endif
typedef enum
{
SKY_MODEL_CUSTOM = 0,
SKY_MODEL_PREETHAM = 1
} SkyModel;
typedef struct typedef struct
{ {
SkyModel model;
double daytime; double daytime;
ColorGradation* sun_color; Color sun_color;
double sun_radius; double sun_radius;
double sun_halo_size; double sun_halo_size;
Curve* sun_halo_profile; Curve* sun_halo_profile;
ColorGradation* zenith_color; struct {
ColorGradation* haze_color; int auto_from_daytime;
double haze_height; Color zenith_color;
double haze_smoothing; Color haze_color;
ColorGradation* _sky_gradation; double haze_height;
double haze_smoothing;
ColorGradation* _sky_gradation;
} model_custom;
struct {
double turbidity;
} model_preetham;
} SkyDefinition; } SkyDefinition;
void skyInit(); void skyInit();