00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _SKYLIGHT_HPP_
00024 #define _SKYLIGHT_HPP_
00025
00026 #include <cmath>
00027 #include <QDebug>
00028 #include "StelUtils.hpp"
00029
00030 typedef struct {
00031 float zenithAngle;
00032 float distSun;
00033 float color[3];
00034 } skylightStruct;
00035
00036 typedef struct {
00037 float pos[3];
00038 float color[3];
00039 } skylightStruct2;
00040
00041 class Skylight
00042 {
00043 public:
00044 Skylight();
00045 virtual ~Skylight();
00046
00047
00048 void setParams(float sunZenithAngle, float turbidity);
00049
00050
00051
00052 inline void getZenithColor(float * v) const;
00053
00054
00055
00056 void setParamsv(const float * sunPos, float turbidity);
00057
00058
00059
00060
00061
00062 void getxyYValuev(skylightStruct2& p) const
00063 {
00064 const float cosDistSun = sunPos[0]*p.pos[0] + sunPos[1]*p.pos[1] + sunPos[2]*p.pos[2];
00065 const float distSun = StelUtils::fastAcos(cosDistSun);
00066 const float cosDistSun_q = cosDistSun*cosDistSun;
00067
00068 Q_ASSERT(p.pos[2] >= 0.f);
00069 const float oneOverCosZenithAngle = (p.pos[2]==0.) ? 1e99 : 1.f / p.pos[2];
00070 p.color[0] = term_x * (1.f + Ax * std::exp(Bx*oneOverCosZenithAngle))
00071 * (1.f + Cx * std::exp(Dx*distSun) + Ex * cosDistSun_q);
00072
00073 p.color[1] = term_y * (1.f + Ay * std::exp(By*oneOverCosZenithAngle))
00074 * (1.f + Cy * std::exp(Dy*distSun) + Ey * cosDistSun_q);
00075
00076
00077
00078
00079
00080 if (p.color[0] < 0. || p.color[1] < 0.)
00081 {
00082 p.color[0] = 0.25;
00083 p.color[1] = 0.25;
00084 p.color[2] = 0.;
00085 }
00086 }
00087
00088 void getShadersParams(Vec3f& asunPos, float& aterm_x, float& aAx, float& aBx, float& aCx, float& aDx, float& aEx,
00089 float& aterm_y, float& aAy, float& aBy, float& aCy, float& aDy, float& aEy) const
00090 {
00091 asunPos=sunPos;
00092 aterm_x=term_x;aAx=Ax;aBx=Bx;aCx=Cx;aDx=Dx;aEx=Ex;
00093 aterm_y=term_y;aAy=Ay;aBy=By;aCy=Cy;aDy=Dy;aEy=Ey;
00094 }
00095
00096
00097
00098 private:
00099 float thetas;
00100 float T;
00101
00102
00103
00104
00105
00106
00107
00108
00109 float zenithLuminance;
00110 float zenithColorX;
00111 float zenithColorY;
00112
00113 float eyeLumConversion;
00114
00115
00116 float AY, BY, CY, DY, EY;
00117 float Ax, Bx, Cx, Dx, Ex;
00118 float Ay, By, Cy, Dy, Ey;
00119
00120 float term_x;
00121 float term_y;
00122 float term_Y;
00123
00124 float sunPos[3];
00125
00126
00127 inline void computeZenithLuminance(void);
00128
00129 inline void computeZenithColor(void);
00130
00131 inline void computeLuminanceDistributionCoefs(void);
00132
00133 inline void computeColorDistributionCoefs(void);
00134 };
00135
00136
00137 inline void Skylight::getZenithColor(float * v) const
00138 {
00139 v[0] = zenithColorX;
00140 v[1] = zenithColorY;
00141 v[2] = zenithLuminance;
00142 }
00143
00144
00145 inline void Skylight::computeZenithLuminance(void)
00146 {
00147 zenithLuminance = 1000.f * ((4.0453f*T - 4.9710f) * std::tan( (0.4444f - T/120.f) * (M_PI-2.f*thetas) ) -
00148 0.2155f*T + 2.4192f);
00149 if (zenithLuminance<=0.f) zenithLuminance=0.00000000001;
00150 }
00151
00152
00153
00154 inline void Skylight::computeZenithColor(void)
00155 {
00156 static float thetas2;
00157 static float thetas3;
00158 static float T2;
00159
00160 thetas2 = thetas * thetas;
00161 thetas3 = thetas2 * thetas;
00162 T2 = T * T;
00163
00164 zenithColorX = ( 0.00216f*thetas3 - 0.00375f*thetas2 + 0.00209f*thetas) * T2 +
00165 (-0.02903f*thetas3 + 0.06377f*thetas2 - 0.03202f*thetas + 0.00394f) * T +
00166 ( 0.10169f*thetas3 - 0.21196f*thetas2 + 0.06052f*thetas + 0.25886f);
00167
00168 zenithColorY = ( 0.00275f*thetas3 - 0.00610f*thetas2 + 0.00317f*thetas) * T2 +
00169 (-0.04214f*thetas3 + 0.08970f*thetas2 - 0.04153f*thetas + 0.00516f) * T +
00170 ( 0.14535f*thetas3 - 0.26756f*thetas2 + 0.06670f*thetas + 0.26688f);
00171
00172 }
00173
00174
00175
00176 inline void Skylight::computeLuminanceDistributionCoefs(void)
00177 {
00178 AY = 0.2787f*T - 1.0630f;
00179 BY =-0.3554f*T + 0.4275f;
00180 CY =-0.0227f*T + 6.3251f;
00181 DY = 0.1206f*T - 2.5771f;
00182 EY =-0.0670f*T + 0.3703f;
00183
00184 Q_ASSERT(BY <= 0.0);
00185 }
00186
00187
00188
00189 inline void Skylight::computeColorDistributionCoefs(void)
00190 {
00191 Ax =-0.0148f*T - 0.1703f;
00192 Bx =-0.0664f*T + 0.0011f;
00193 Cx =-0.0005f*T + 0.2127f;
00194 Dx =-0.0641f*T - 0.8992f;
00195 Ex =-0.0035f*T + 0.0453f;
00196
00197 Ay =-0.0131f*T - 0.2498f;
00198 By =-0.0951f*T + 0.0092f;
00199 Cy =-0.0082f*T + 0.2404f;
00200 Dy =-0.0438f*T - 1.0539f;
00201 Ey =-0.0109f*T + 0.0531f;
00202
00203 Q_ASSERT(Bx <= 0.0);
00204 Q_ASSERT(By <= 0.0);
00205 }
00206
00207
00208 #endif // _SKYLIGHT_H_
00209