aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvosky.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llvosky.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llvosky.cpp1505
1 files changed, 640 insertions, 865 deletions
diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp
index ba4b20b..37f6f30 100644
--- a/linden/indra/newview/llvosky.cpp
+++ b/linden/indra/newview/llvosky.cpp
@@ -53,23 +53,29 @@
53#include "llviewerregion.h" 53#include "llviewerregion.h"
54#include "llworld.h" 54#include "llworld.h"
55#include "pipeline.h" 55#include "pipeline.h"
56#include "lldrawpoolwlsky.h"
57#include "llwlparammanager.h"
58#include "llwaterparammanager.h"
56 59
57const S32 NUM_TILES_X = 8; 60#undef min
58const S32 NUM_TILES_Y = 4; 61#undef max
59const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; 62
63static const S32 NUM_TILES_X = 8;
64static const S32 NUM_TILES_Y = 4;
65static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
60 66
61// Heavenly body constants 67// Heavenly body constants
62const F32 SUN_DISK_RADIUS = 0.5f; 68static const F32 SUN_DISK_RADIUS = 0.5f;
63const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f; 69static const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
64const F32 SUN_INTENSITY = 1e5; 70static const F32 SUN_INTENSITY = 1e5;
65const F32 SUN_DISK_INTENSITY = 24.f; 71static const F32 SUN_DISK_INTENSITY = 24.f;
66 72
67 73
68// Texture coordinates: 74// Texture coordinates:
69const LLVector2 TEX00 = LLVector2(0.f, 0.f); 75static const LLVector2 TEX00 = LLVector2(0.f, 0.f);
70const LLVector2 TEX01 = LLVector2(0.f, 1.f); 76static const LLVector2 TEX01 = LLVector2(0.f, 1.f);
71const LLVector2 TEX10 = LLVector2(1.f, 0.f); 77static const LLVector2 TEX10 = LLVector2(1.f, 0.f);
72const LLVector2 TEX11 = LLVector2(1.f, 1.f); 78static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
73 79
74// Exported globals 80// Exported globals
75LLUUID gSunTextureID = IMG_SUN; 81LLUUID gSunTextureID = IMG_SUN;
@@ -134,7 +140,7 @@ private:
134 F32 mTable[257]; // index 0 is unused 140 F32 mTable[257]; // index 0 is unused
135}; 141};
136 142
137LLFastLn gFastLn; 143static LLFastLn gFastLn;
138 144
139 145
140// Functions used a lot. 146// Functions used a lot.
@@ -163,42 +169,6 @@ inline LLColor3 color_norm(const LLColor3 &col)
163 else return col; 169 else return col;
164} 170}
165 171
166inline LLColor3 color_norm_fog(const LLColor3 &col)
167{
168 const F32 m = color_max(col);
169 if (m > 0.75f)
170 {
171 return 0.75f/m * col;
172 }
173 else return col;
174}
175
176
177inline LLColor4 color_norm_abs(const LLColor4 &col)
178{
179 const F32 m = color_max(col);
180 if (m > 1e-6)
181 {
182 return 1.f/m * col;
183 }
184 else
185 {
186 return col;
187 }
188}
189
190
191inline F32 color_intens ( const LLColor4 &col )
192{
193 return col.mV[0] + col.mV[1] + col.mV[2];
194}
195
196
197inline F32 color_avg ( const LLColor3 &col )
198{
199 return color_intens(col) / 3.f;
200}
201
202inline void color_gamma_correct(LLColor3 &col) 172inline void color_gamma_correct(LLColor3 &col)
203{ 173{
204 const F32 gamma_inv = 1.f/1.2f; 174 const F32 gamma_inv = 1.f/1.2f;
@@ -216,164 +186,6 @@ inline void color_gamma_correct(LLColor3 &col)
216 } 186 }
217} 187}
218 188
219inline F32 min_intens_factor( LLColor3& col, F32 min_intens, BOOL postmultiply = FALSE);
220inline F32 min_intens_factor( LLColor3& col, F32 min_intens, BOOL postmultiply)
221{
222 const F32 intens = color_intens(col);
223 F32 factor = 1;
224 if (0 == intens)
225 {
226 return 0;
227 }
228
229 if (intens < min_intens)
230 {
231 factor = min_intens / intens;
232 if (postmultiply)
233 col *= factor;
234 }
235 return factor;
236}
237
238inline LLVector3 move_vec(const LLVector3& v, const F32 cos_max_angle)
239{
240 LLVector3 v_norm = v;
241 v_norm.normVec();
242
243 LLVector2 v_norm_proj(v_norm.mV[0], v_norm.mV[1]);
244 const F32 projection2 = v_norm_proj.magVecSquared();
245 const F32 scale = sqrt((1 - cos_max_angle * cos_max_angle) / projection2);
246 return LLVector3(scale * v_norm_proj.mV[0], scale * v_norm_proj.mV[1], cos_max_angle);
247}
248
249
250/***************************************
251 Transparency Map
252***************************************/
253
254void LLTranspMap::init(const F32 elev, const F32 step, const F32 h, const LLHaze* const haze)
255{
256 mHaze = haze;
257 mAtmHeight = h;
258 mElevation = elev;
259 mStep = step;
260 mStepInv = 1.f / step;
261 F32 sin_angle = EARTH_RADIUS/(EARTH_RADIUS + mElevation);
262 mCosMaxAngle = -sqrt(1 - sin_angle * sin_angle);
263 mMapSize = S32(ceil((1 - mCosMaxAngle) * mStepInv + 1) + 0.5);
264 delete mT;
265 mT = new LLColor3[mMapSize];
266
267 for (S32 i = 0; i < mMapSize; ++i)
268 {
269 const F32 cos_a = 1 - i*mStep;
270 const LLVector3 dir(0, sqrt(1-cos_a*cos_a), cos_a);
271 mT[i] = calcAirTranspDir(mElevation, dir);
272 }
273}
274
275
276
277LLColor3 LLTranspMap::calcAirTranspDir(const F32 elevation, const LLVector3 &dir) const
278{
279 LLColor3 opt_depth(0, 0, 0);
280 const LLVector3 point(0, 0, EARTH_RADIUS + elevation);
281 F32 dist = -dir * point;
282 LLVector3 cur_point;
283 S32 s;
284
285 if (dist > 0)
286 {
287 cur_point = point + dist * dir;
288// const F32 K = log(dist * INV_FIRST_STEP + 1) * INV_NO_STEPS;
289// const F32 e_pow_k = LL_FAST_EXP(K);
290 const F32 e_pow_k = gFastLn.pow( dist * INV_FIRST_STEP + 1, INV_NO_STEPS );
291 F32 step = FIRST_STEP * (1 - 1 / e_pow_k);
292
293 for (s = 0; s < NO_STEPS; ++s)
294 {
295 const F32 h = cur_point.magVec() - EARTH_RADIUS;
296 step *= e_pow_k;
297 opt_depth += calcSigExt(h) * step;
298 cur_point -= dir * step;
299 }
300 opt_depth *= 2;
301 cur_point = point + 2 * dist * dir;
302 }
303 else
304 {
305 cur_point = point;
306 }
307
308 dist = hitsAtmEdge(cur_point, dir);
309// const F32 K = log(dist * INV_FIRST_STEP + 1) * INV_NO_STEPS;
310// const F32 e_pow_k = LL_FAST_EXP(K);
311 const F32 e_pow_k = gFastLn.pow( dist * INV_FIRST_STEP + 1, INV_NO_STEPS );
312 F32 step = FIRST_STEP * (1 - 1 / e_pow_k);
313
314 for (s = 0; s < NO_STEPS; ++s)
315 {
316 const F32 h = cur_point.magVec() - EARTH_RADIUS;
317 step *= e_pow_k;
318 opt_depth += calcSigExt(h) * step;
319 cur_point += dir * step;
320 }
321
322 opt_depth *= -4.0f*F_PI;
323 opt_depth.exp();
324 return opt_depth;
325}
326
327
328
329F32 LLTranspMap::hitsAtmEdge(const LLVector3& X, const LLVector3& dir) const
330{
331 const F32 tca = -dir * X;
332 const F32 R = EARTH_RADIUS + mAtmHeight;
333 const F32 thc2 = R * R - X.magVecSquared() + tca * tca;
334 return tca + sqrt ( thc2 );
335}
336
337
338
339
340
341void LLTranspMapSet::init(const S32 size, const F32 first_step, const F32 media_height, const LLHaze* const haze)
342{
343 const F32 angle_step = 0.005f;
344 mSize = size;
345 mMediaHeight = media_height;
346
347 delete[] mTransp;
348 mTransp = new LLTranspMap[mSize];
349
350 delete[] mHeights;
351 mHeights = new F32[mSize];
352
353 F32 h = 0;
354 mHeights[0] = h;
355 mTransp[0].init(h, angle_step, mMediaHeight, haze);
356 const F32 K = log(mMediaHeight / first_step + 1) / (mSize - 1);
357 const F32 e_pow_k = exp(K);
358 F32 step = first_step * (e_pow_k - 1);
359
360 for (S32 s = 1; s < mSize; ++s)
361 {
362 h += step;
363 mHeights[s] = h;
364 mTransp[s].init(h, angle_step, mMediaHeight, haze);
365 step *= e_pow_k;
366 }
367}
368
369LLTranspMapSet::~LLTranspMapSet()
370{
371 delete[] mTransp;
372 mTransp = NULL;
373 delete[] mHeights;
374 mHeights = NULL;
375}
376
377 189
378 190
379/*************************************** 191/***************************************
@@ -392,7 +204,7 @@ LLSkyTex::LLSkyTex()
392 204
393void LLSkyTex::init() 205void LLSkyTex::init()
394{ 206{
395 mSkyData = new LLColor3[sResolution * sResolution]; 207 mSkyData = new LLColor4[sResolution * sResolution];
396 mSkyDirs = new LLVector3[sResolution * sResolution]; 208 mSkyDirs = new LLVector3[sResolution * sResolution];
397 209
398 for (S32 i = 0; i < 2; ++i) 210 for (S32 i = 0; i < 2; ++i)
@@ -451,9 +263,9 @@ void LLSkyTex::initEmpty(const S32 tex)
451 createGLImage(tex); 263 createGLImage(tex);
452} 264}
453 265
454 266void LLSkyTex::create(const F32 brightness)
455void LLSkyTex::create(const F32 brightness_scale, const LLColor3& multiscatt)
456{ 267{
268 /// Brightness ignored for now.
457 U8* data = mImageRaw[sCurrent]->getData(); 269 U8* data = mImageRaw[sCurrent]->getData();
458 for (S32 i = 0; i < sResolution; ++i) 270 for (S32 i = 0; i < sResolution; ++i)
459 { 271 {
@@ -461,23 +273,17 @@ void LLSkyTex::create(const F32 brightness_scale, const LLColor3& multiscatt)
461 { 273 {
462 const S32 basic_offset = (i * sResolution + j); 274 const S32 basic_offset = (i * sResolution + j);
463 S32 offset = basic_offset * sComponents; 275 S32 offset = basic_offset * sComponents;
464 LLColor3 col(mSkyData[basic_offset]);
465 if (getDir(i, j).mV[VZ] >= -0.02f) {
466 col += 0.1f * multiscatt;
467 col *= brightness_scale;
468 col.clamp();
469 color_gamma_correct(col);
470 }
471
472 U32* pix = (U32*)(data + offset); 276 U32* pix = (U32*)(data + offset);
473 LLColor4 temp = LLColor4(col, 0); 277 LLColor4U temp = LLColor4U(mSkyData[basic_offset]);
474 LLColor4U temp1 = LLColor4U(temp); 278 *pix = temp.mAll;
475 *pix = temp1.mAll;
476 } 279 }
477 } 280 }
478 createGLImage(sCurrent); 281 createGLImage(sCurrent);
479} 282}
480 283
284
285
286
481void LLSkyTex::createGLImage(S32 which) 287void LLSkyTex::createGLImage(S32 which)
482{ 288{
483 mImageGL[which]->createGLTexture(0, mImageRaw[which]); 289 mImageGL[which]->createGLTexture(0, mImageRaw[which]);
@@ -495,8 +301,6 @@ void LLSkyTex::bindTexture(BOOL curr)
495 301
496F32 LLHeavenBody::sInterpVal = 0; 302F32 LLHeavenBody::sInterpVal = 0;
497 303
498F32 LLVOSky::sNighttimeBrightness = 1.5f;
499
500S32 LLVOSky::sResolution = LLSkyTex::getResolution(); 304S32 LLVOSky::sResolution = LLSkyTex::getResolution();
501S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; 305S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X;
502S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y; 306S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y;
@@ -511,8 +315,32 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
511 mCloudDensity(0.2f), 315 mCloudDensity(0.2f),
512 mWind(0.f), 316 mWind(0.f),
513 mForceUpdate(FALSE), 317 mForceUpdate(FALSE),
514 mWorldScale(1.f) 318 mWorldScale(1.f),
319 mBumpSunDir(0.f, 0.f, 1.f)
515{ 320{
321 bool error = false;
322
323 /// WL PARAMS
324 dome_radius = 1.f;
325 dome_offset_ratio = 0.f;
326 sunlight_color = LLColor3();
327 ambient = LLColor3();
328 gamma = 1.f;
329 lightnorm = LLVector4();
330 blue_density = LLColor3();
331 blue_horizon = LLColor3();
332 haze_density = 0.f;
333 haze_horizon = LLColor3();
334 density_multiplier = 0.f;
335 max_y = 0.f;
336 glow = LLColor3();
337 cloud_shadow = 0.f;
338 cloud_color = LLColor3();
339 cloud_scale = 0.f;
340 cloud_pos_density1 = LLColor3();
341 cloud_pos_density2 = LLColor3();
342
343
516 mInitialized = FALSE; 344 mInitialized = FALSE;
517 mbCanSelect = FALSE; 345 mbCanSelect = FALSE;
518 mUpdateTimer.reset(); 346 mUpdateTimer.reset();
@@ -520,6 +348,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
520 for (S32 i = 0; i < 6; i++) 348 for (S32 i = 0; i < 6; i++)
521 { 349 {
522 mSkyTex[i].init(); 350 mSkyTex[i].init();
351 mShinyTex[i].init();
523 } 352 }
524 for (S32 i=0; i<FACE_COUNT; i++) 353 for (S32 i=0; i<FACE_COUNT; i++)
525 { 354 {
@@ -529,9 +358,8 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
529 mCameraPosAgent = gAgent.getCameraPositionAgent(); 358 mCameraPosAgent = gAgent.getCameraPositionAgent();
530 mAtmHeight = ATM_HEIGHT; 359 mAtmHeight = ATM_HEIGHT;
531 mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); 360 mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
532 updateHaze();
533 361
534 mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition"); 362 mSunDefaultPosition = LLVector3(LLWLParamManager::instance()->mCurParams.getVector("lightnorm", error));
535 if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) 363 if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition"))
536 { 364 {
537 initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); 365 initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0));
@@ -551,6 +379,8 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
551 mMoonTexturep->setClamp(TRUE, TRUE); 379 mMoonTexturep->setClamp(TRUE, TRUE);
552 mBloomTexturep = gImageList.getImage(IMG_BLOOM1); 380 mBloomTexturep = gImageList.getImage(IMG_BLOOM1);
553 mBloomTexturep->setClamp(TRUE, TRUE); 381 mBloomTexturep->setClamp(TRUE, TRUE);
382
383 mHeavenlyBodyUpdated = FALSE ;
554} 384}
555 385
556 386
@@ -570,14 +400,11 @@ void LLVOSky::initClass()
570 400
571void LLVOSky::init() 401void LLVOSky::init()
572{ 402{
573 // index of refraction calculation. 403 const F32 haze_int = color_intens(mHaze.calcSigSca(0));
574 mTransp.init(NO_STEPS+1+4, FIRST_STEP, mAtmHeight, &mHaze);
575
576 const F32 haze_int = color_intens(mHaze.calcSigSca(0));
577 mHazeConcentration = haze_int / 404 mHazeConcentration = haze_int /
578 (color_intens(LLHaze::calcAirSca(0)) + haze_int); 405 (color_intens(LLHaze::calcAirSca(0)) + haze_int);
579 406
580 mBrightnessScaleNew = 0; 407 calcAtmospherics();
581 408
582 // Initialize the cached normalized direction vectors 409 // Initialize the cached normalized direction vectors
583 for (S32 side = 0; side < 6; ++side) 410 for (S32 side = 0; side < 6; ++side)
@@ -589,8 +416,16 @@ void LLVOSky::init()
589 } 416 }
590 } 417 }
591 418
592 calcBrightnessScaleAndColors(); 419 for (S32 i = 0; i < 6; ++i)
420 {
421 mSkyTex[i].create(1.0f);
422 mShinyTex[i].create(1.0f);
423 }
424
593 initCubeMap(); 425 initCubeMap();
426 mInitialized = true;
427
428 mHeavenlyBodyUpdated = FALSE ;
594} 429}
595 430
596void LLVOSky::initCubeMap() 431void LLVOSky::initCubeMap()
@@ -598,7 +433,7 @@ void LLVOSky::initCubeMap()
598 std::vector<LLPointer<LLImageRaw> > images; 433 std::vector<LLPointer<LLImageRaw> > images;
599 for (S32 side = 0; side < 6; side++) 434 for (S32 side = 0; side < 6; side++)
600 { 435 {
601 images.push_back(mSkyTex[side].getImageRaw()); 436 images.push_back(mShinyTex[side].getImageRaw());
602 } 437 }
603 if (mCubeMap) 438 if (mCubeMap)
604 { 439 {
@@ -639,7 +474,7 @@ void LLVOSky::restoreGL()
639 mBloomTexturep = gImageList.getImage(IMG_BLOOM1); 474 mBloomTexturep = gImageList.getImage(IMG_BLOOM1);
640 mBloomTexturep->setClamp(TRUE, TRUE); 475 mBloomTexturep->setClamp(TRUE, TRUE);
641 476
642 calcBrightnessScaleAndColors(); 477 calcAtmospherics();
643 478
644 if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap 479 if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap
645 && gFeatureManagerp->isFeatureAvailable("RenderCubeMap")) 480 && gFeatureManagerp->isFeatureAvailable("RenderCubeMap"))
@@ -649,7 +484,7 @@ void LLVOSky::restoreGL()
649 std::vector<LLPointer<LLImageRaw> > images; 484 std::vector<LLPointer<LLImageRaw> > images;
650 for (S32 side = 0; side < 6; side++) 485 for (S32 side = 0; side < 6; side++)
651 { 486 {
652 images.push_back(mSkyTex[side].getImageRaw()); 487 images.push_back(mShinyTex[side].getImageRaw());
653 } 488 }
654 489
655 if(cube_map) 490 if(cube_map)
@@ -666,67 +501,6 @@ void LLVOSky::restoreGL()
666 501
667} 502}
668 503
669
670void LLVOSky::updateHaze()
671{
672 static LLRandLagFib607 weather_generator(LLUUID::getRandomSeed());
673 if (gSavedSettings.getBOOL("FixedWeather"))
674 {
675 weather_generator.seed(8008135);
676 }
677
678 const F32 fo_upper_bound = 5;
679 const F32 sca_upper_bound = 6;
680 const F32 fo = 1 + (F32)weather_generator() *(fo_upper_bound - 1);
681 const static F32 upper = 0.5f / gFastLn.ln(fo_upper_bound);
682 mHaze.setFalloff(fo);
683 mHaze.setG((F32)weather_generator() * (0.0f + upper * gFastLn.ln(fo)));
684 LLColor3 sca;
685 const F32 cd = mCloudDensity * 3;
686 F32 min_r = cd - 1;
687 if (min_r < 0)
688 {
689 min_r = 0;
690 }
691 F32 max_r = cd + 1;
692 if (max_r > sca_upper_bound)
693 {
694 max_r = sca_upper_bound;
695 }
696
697 sca.mV[0] = min_r + (F32)weather_generator() * (max_r - min_r);
698
699 min_r = sca.mV[0] - 0.1f;
700 if (min_r < 0)
701 {
702 min_r = 0;
703 }
704 max_r = sca.mV[0] + 0.5f;
705 if (max_r > sca_upper_bound)
706 {
707 max_r = sca_upper_bound;
708 }
709
710 sca.mV[1] = min_r + (F32)weather_generator() * (max_r - min_r);
711
712 min_r = sca.mV[1];
713 if (min_r < 0)
714 {
715 min_r = 0;
716 }
717 max_r = sca.mV[1] + 1;
718 if (max_r > sca_upper_bound)
719 {
720 max_r = sca_upper_bound;
721 }
722
723 sca.mV[2] = min_r + (F32)weather_generator() * (max_r - min_r);
724
725 sca = AIR_SCA_AVG * sca;
726
727 mHaze.setSigSca(sca);
728}
729
730void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) 504void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
731{ 505{
732 S32 tile_x = tile % NUM_TILES_X; 506 S32 tile_x = tile % NUM_TILES_X;
@@ -754,6 +528,7 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
754 LLVector3 dir(coeff[0], coeff[1], coeff[2]); 528 LLVector3 dir(coeff[0], coeff[1], coeff[2]);
755 dir.normVec(); 529 dir.normVec();
756 mSkyTex[side].setDir(dir, x, y); 530 mSkyTex[side].setDir(dir, x, y);
531 mShinyTex[side].setDir(dir, x, y);
757 } 532 }
758 } 533 }
759} 534}
@@ -772,404 +547,491 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile)
772 for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) 547 for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
773 { 548 {
774 mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); 549 mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y);
550 mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y);
775 } 551 }
776 } 552 }
777} 553}
778 554
779 555static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
780LLColor3 LLVOSky::calcSkyColorInDir(const LLVector3 &dir)
781{ 556{
782 LLColor3 col, transp; 557 return LLColor3(left.mV[0]/right.mV[0],
783 558 left.mV[1]/right.mV[1],
784 if (dir.mV[VZ] < -0.02f) 559 left.mV[2]/right.mV[2]);
785 { 560}
786 col = LLColor3(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.27f));
787 float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]);
788 x *= x;
789 col.mV[0] *= x*x;
790 col.mV[1] *= powf(x, 2.5f);
791 col.mV[2] *= x*x*x;
792 return col;
793 }
794 561
795 562
796 calcSkyColorInDir(col, transp, dir); 563static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
797 F32 br = color_max(col); 564{
798 if (br > mBrightnessScaleNew) 565 return LLColor3(left.mV[0]*right.mV[0],
799 { 566 left.mV[1]*right.mV[1],
800 mBrightnessScaleNew = br; 567 left.mV[2]*right.mV[2]);
801 mBrightestPointNew = col;
802 }
803 return col;
804} 568}
805 569
806 570
807LLColor4 LLVOSky::calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exager = 1) const 571static inline LLColor3 componentExp(LLColor3 const &v)
808{ 572{
809 LLColor3 col, tr; 573 return LLColor3(exp(v.mV[0]),
810 calcInScatter(col, tr, point, exager); 574 exp(v.mV[1]),
811 col *= mBrightnessScaleGuess; 575 exp(v.mV[2]));
812 transp = LLColor4(tr);
813 return LLColor4(col);
814} 576}
815 577
578static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
579{
580 return LLColor3(pow(v.mV[0], exponent),
581 pow(v.mV[1], exponent),
582 pow(v.mV[2], exponent));
583}
816 584
817 585static inline LLColor3 componentSaturate(LLColor3 const &v)
818void LLVOSky::calcSkyColorInDir(LLColor3& res, LLColor3& transp, const LLVector3& dir) const
819{ 586{
820 const LLVector3& tosun = getToSunLast(); 587 return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
821 res.setToBlack(); 588 std::max(std::min(v.mV[1], 1.f), 0.f),
822 LLColor3 haze_res(0.f, 0.f, 0.f); 589 std::max(std::min(v.mV[2], 1.f), 0.f));
823 transp.setToWhite();
824 LLVector3 step_v ;
825 LLVector3 cur_pos = mCameraPosAgent;
826 F32 h;
827
828 F32 dist = calcHitsAtmEdge(mCameraPosAgent, dir);
829// const F32 K = log(dist / FIRST_STEP + 1) / NO_STEPS;
830 const F32 K = gFastLn.ln(dist / FIRST_STEP + 1) / NO_STEPS;
831 const F32 e_pow_k = (F32)LL_FAST_EXP(K);
832 F32 step = FIRST_STEP * (1 - 1 / e_pow_k);
833
834 // Initialize outside the loop because we write into them every iteration. JC
835 LLColor3 air_sca_opt_depth;
836 LLColor3 haze_sca_opt_depth;
837 LLColor3 air_transp;
838
839 for (S32 s = 0; s < NO_STEPS; ++s)
840 {
841 h = calcHeight(cur_pos);
842 step *= e_pow_k;
843 LLHaze::calcAirSca(h, air_sca_opt_depth);
844 air_sca_opt_depth *= step;
845
846 mHaze.calcSigSca(h, haze_sca_opt_depth);
847 haze_sca_opt_depth *= step;
848
849 LLColor3 haze_ext_opt_depth = haze_sca_opt_depth;
850 haze_ext_opt_depth *= (1.f + mHaze.getAbsCoef());
851
852 if (calcHitsEarth(cur_pos, tosun) < 0) // calculates amount of in-scattered light from the sun
853 {
854 //visibility check is too expensive
855 mTransp.calcTransp(calcUpVec(cur_pos) * tosun, h, air_transp);
856 air_transp *= transp;
857 res += air_sca_opt_depth * air_transp;
858 haze_res += haze_sca_opt_depth * air_transp;
859 }
860 LLColor3 temp(-4.f * F_PI * (air_sca_opt_depth + haze_ext_opt_depth));
861 temp.exp();
862 transp *= temp;
863 step_v = dir * step;
864 cur_pos += step_v;
865 }
866 const F32 cos_dir = dir * tosun;
867 res *= calcAirPhaseFunc(cos_dir);
868 res += haze_res * mHaze.calcPhase(cos_dir);
869 res *= mSun.getIntensity();
870} 590}
871 591
872 592
593static inline LLColor3 componentSqrt(LLColor3 const &v)
594{
595 return LLColor3(sqrt(v.mV[0]),
596 sqrt(v.mV[1]),
597 sqrt(v.mV[2]));
598}
873 599
600static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
601{
602 left.mV[0] *= right.mV[0];
603 left.mV[1] *= right.mV[1];
604 left.mV[2] *= right.mV[2];
605}
874 606
875void LLVOSky::calcInScatter(LLColor3& res, LLColor3& transp, 607static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
876 const LLVector3& P, const F32 exaggeration) const
877{ 608{
878 const LLVector3& tosun = getToSunLast(); 609 return (left + ((right - left) * amount));
879 res.setToBlack(); 610}
880 transp.setToWhite();
881 611
882 LLVector3 lower, upper; 612static inline F32 texture2D(LLPointer<LLImageRaw> const & tex, LLVector2 const & uv)
883 LLVector3 dir = P - mCameraPosAgent; 613{
614 U16 w = tex->getWidth();
615 U16 h = tex->getHeight();
884 616
885 F32 dist = exaggeration * dir.normVec(); 617 U16 r = U16(uv[0] * w) % w;
618 U16 c = U16(uv[1] * h) % h;
886 619
887 const F32 cos_dir = dir * tosun; 620 U8 const * imageBuffer = tex->getData();
888 621
889 if (dir.mV[VZ] > 0) 622 U8 sample = imageBuffer[r * w + c];
890 {
891 lower = mCameraPosAgent;
892 upper = P;
893 }
894 else
895 {
896 lower = P;
897 upper = mCameraPosAgent;
898 dir = -dir;
899 }
900 623
901 const F32 lower_h = calcHeight(lower); 624 return sample / 255.f;
902 const F32 upper_h = calcHeight(upper); 625}
903 const LLVector3 up_upper = calcUpVec(upper); 626
904 const LLVector3 up_lower = calcUpVec(lower); 627static inline LLColor3 smear(F32 val)
628{
629 return LLColor3(val, val, val);
630}
905 631
906 transp = color_div(mTransp.calcTransp(up_lower * dir, lower_h), 632void LLVOSky::initAtmospherics(void)
907 mTransp.calcTransp(up_upper * dir, upper_h)); 633{
908 color_pow(transp, exaggeration); 634 bool error;
635
636 // uniform parameters for convenience
637 dome_radius = LLWLParamManager::instance()->getDomeRadius();
638 dome_offset_ratio = LLWLParamManager::instance()->getDomeOffset();
639 sunlight_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("sunlight_color", error));
640 ambient = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("ambient", error));
641 //lightnorm = LLWLParamManager::instance()->mCurParams.getVector("lightnorm", error);
642 gamma = LLWLParamManager::instance()->mCurParams.getVector("gamma", error)[0];
643 blue_density = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_density", error));
644 blue_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_horizon", error));
645 haze_density = LLWLParamManager::instance()->mCurParams.getVector("haze_density", error)[0];
646 haze_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("haze_horizon", error));
647 density_multiplier = LLWLParamManager::instance()->mCurParams.getVector("density_multiplier", error)[0];
648 max_y = LLWLParamManager::instance()->mCurParams.getVector("max_y", error)[0];
649 glow = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("glow", error));
650 cloud_shadow = LLWLParamManager::instance()->mCurParams.getVector("cloud_shadow", error)[0];
651 cloud_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_color", error));
652 cloud_scale = LLWLParamManager::instance()->mCurParams.getVector("cloud_scale", error)[0];
653 cloud_pos_density1 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density1", error));
654 cloud_pos_density2 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density2", error));
655
656 // light norm is different. We need the sun's direction, not the light direction
657 // which could be from the moon. And we need to clamp it
658 // just like for the gpu
659 LLVector3 sunDir = gSky.getSunDirection();
660
661 // CFR_TO_OGL
662 lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0);
663 unclamped_lightnorm = lightnorm;
664 if(lightnorm.mV[1] < -0.1f)
665 {
666 lightnorm.mV[1] = -0.1f;
667 }
668
669}
909 670
910 if (calcHitsEarth(upper, tosun) > 0) 671LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny)
672{
673 F32 saturation = 0.3f;
674 if (dir.mV[VZ] < -0.02f)
911 { 675 {
912 const F32 avg = color_avg(transp); 676 LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f);
913 //const F32 avg = llmin(1.f, 1.2f * color_avg(transp)); 677 if (isShiny)
914 transp.setVec(avg, avg, avg); 678 {
915 return; 679 LLColor3 desat_fog = LLColor3(mFogColor);
680 F32 brightness = desat_fog.brightness();
681 // So that shiny somewhat shows up at night.
682 if (brightness < 0.15f)
683 {
684 brightness = 0.15f;
685 desat_fog = smear(0.15f);
686 }
687 LLColor3 greyscale = smear(brightness);
688 desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation);
689 if (!gPipeline.canUseWindLightShaders())
690 {
691 col = LLColor4(desat_fog, 0.f);
692 }
693 else
694 {
695 col = LLColor4(desat_fog * 0.5f, 0.f);
696 }
697 }
698 float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]);
699 x *= x;
700 col.mV[0] *= x*x;
701 col.mV[1] *= powf(x, 2.5f);
702 col.mV[2] *= x*x*x;
703 return col;
916 } 704 }
917 705
918 LLColor3 air_sca_opt_depth = LLHaze::calcAirSca(upper_h); 706 // undo OGL_TO_CFR_ROTATION and negate vertical direction.
919 LLColor3 haze_sca_opt_depth = mHaze.calcSigSca(upper_h); 707 LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
920 LLColor3 sun_transp;
921 mTransp.calcTransp(up_upper * tosun, upper_h, sun_transp);
922 708
923 if (calcHitsEarth(lower, tosun) < 0) 709 LLColor3 vary_HazeColor(0,0,0);
710 LLColor3 vary_CloudColorSun(0,0,0);
711 LLColor3 vary_CloudColorAmbient(0,0,0);
712 F32 vary_CloudDensity(0);
713 LLVector2 vary_HorizontalProjection[2];
714 vary_HorizontalProjection[0] = LLVector2(0,0);
715 vary_HorizontalProjection[1] = LLVector2(0,0);
716
717 calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
718 vary_CloudDensity, vary_HorizontalProjection);
719
720 LLColor3 sky_color = calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
721 vary_CloudDensity, vary_HorizontalProjection);
722 if (isShiny)
924 { 723 {
925 air_sca_opt_depth += LLHaze::calcAirSca(lower_h); 724 F32 brightness = sky_color.brightness();
926 air_sca_opt_depth *= 0.5; 725 LLColor3 greyscale = smear(brightness);
927 haze_sca_opt_depth += mHaze.calcSigSca(lower_h); 726 sky_color = sky_color * saturation + greyscale * (1.0f - saturation);
928 haze_sca_opt_depth *= 0.5; 727 sky_color *= (0.5f + 0.5f * brightness);
929 sun_transp += mTransp.calcTransp(up_lower * tosun, lower_h);
930 sun_transp *= 0.5;
931 } 728 }
932 729 return LLColor4(sky_color, 0.0f);
933 res = calcAirPhaseFunc(cos_dir) * air_sca_opt_depth;
934 res += mHaze.calcPhase(cos_dir) * haze_sca_opt_depth;
935 res = mSun.getIntensity() * dist * sun_transp * res;
936} 730}
937 731
732// turn on floating point precision
733// in vs2003 for this function. Otherwise
734// sky is aliased looking 7:10 - 8:50
735#if LL_MSVC && __MSVC_VER__ < 8
736#pragma optimize("p", on)
737#endif
938 738
739void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
740 LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
741 LLVector2 vary_HorizontalProjection[2])
742{
743 // project the direction ray onto the sky dome.
744 F32 phi = acos(Pn[1]);
745 F32 sinA = sin(F_PI - phi);
746 F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA;
939 747
748 Pn *= Plen;
940 749
750 vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]);
751 vary_HorizontalProjection[0] /= - 2.f * Plen;
941 752
942 753 // Set altitude
943F32 LLVOSky::calcHitsEarth(const LLVector3& orig, const LLVector3& dir) const 754 if (Pn[1] > 0.f)
944{
945 const LLVector3 from_earth_center = mEarthCenter - orig;
946 const F32 tca = dir * from_earth_center;
947 if ( tca < 0 )
948 { 755 {
949 return -1; 756 Pn *= (max_y / Pn[1]);
950 } 757 }
951 758 else
952 const F32 thc2 = EARTH_RADIUS * EARTH_RADIUS -
953 from_earth_center.magVecSquared() + tca * tca;
954 if (thc2 < 0 )
955 { 759 {
956 return -1; 760 Pn *= (-32000.f / Pn[1]);
957 } 761 }
958 762
959 return tca - sqrt ( thc2 ); 763 Plen = Pn.magVec();
960} 764 Pn /= Plen;
961 765
962F32 LLVOSky::calcHitsAtmEdge(const LLVector3& orig, const LLVector3& dir) const 766 // Initialize temp variables
963{ 767 LLColor3 sunlight = sunlight_color;
964 const LLVector3 from_earth_center = mEarthCenter - orig;
965 const F32 tca = dir * from_earth_center;
966 768
967 const F32 thc2 = (EARTH_RADIUS + mAtmHeight) * (EARTH_RADIUS + mAtmHeight) - 769 // Sunlight attenuation effect (hue and brightness) due to atmosphere
968 from_earth_center.magVecSquared() + tca * tca; 770 // this is used later for sunlight modulation at various altitudes
969 return tca + sqrt(thc2); 771 LLColor3 light_atten =
970} 772 (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
971 773
774 // Calculate relative weights
775 LLColor3 temp2(0.f, 0.f, 0.f);
776 LLColor3 temp1 = blue_density + smear(haze_density);
777 LLColor3 blue_weight = componentDiv(blue_density, temp1);
778 LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
972 779
973void LLVOSky::updateBrightestDir() 780 // Compute sunlight from P & lightnorm (for long rays like sky)
974{ 781 temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
975 LLColor3 br_pt, transp;
976 const S32 test_no = 5;
977 const F32 step = F_PI_BY_TWO / (test_no + 1);
978 for (S32 i = 0; i < test_no; ++i)
979 {
980 F32 cos_dir = cos ((i + 1) * step);
981 calcSkyColorInDir(br_pt, transp, move_vec(getToSunLast(), cos_dir));
982 const F32 br = color_max(br_pt);
983 if (br > mBrightnessScaleGuess)
984 {
985 mBrightnessScaleGuess = br;
986 mBrightestPointGuess = br_pt;
987 }
988 }
989}
990 782
783 temp2.mV[1] = 1.f / temp2.mV[1];
784 componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
991 785
992void LLVOSky::calcBrightnessScaleAndColors() 786 // Distance
993{ 787 temp2.mV[2] = Plen * density_multiplier;
994 // new correct normalization.
995 if (mBrightnessScaleNew < 1e-7)
996 {
997 mBrightnessScale = 1;
998 mBrightestPoint.setToBlack();
999 }
1000 else
1001 {
1002 mBrightnessScale = 1.f/mBrightnessScaleNew;
1003 mBrightestPoint = mBrightestPointNew;
1004 }
1005 788
1006 mBrightnessScaleNew = 0; 789 // Transparency (-> temp1)
1007 // and addition 790 temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
1008 791
1009 // Calculate Sun and Moon color
1010 const F32 h = llmax(0.0f, mCameraPosAgent.mV[2]);
1011 const LLColor3 sun_color = mSun.getIntensity() * mTransp.calcTransp(getToSunLast().mV[2], h);
1012 const LLColor3 moon_color = mNightColorShift *
1013 mMoon.getIntensity() * mTransp.calcTransp(getToMoonLast().mV[2], h);
1014 792
1015 F32 intens = color_intens(sun_color); 793 // Compute haze glow
1016 F32 increase_sun_br = (intens > 0) ? 1.2f * color_intens(mBrightestPoint) / intens : 1; 794 temp2.mV[0] = Pn * LLVector3(lightnorm);
1017 795
1018 intens = color_intens(moon_color); 796 temp2.mV[0] = 1.f - temp2.mV[0];
1019 F32 increase_moon_br = (intens > 0) ? 1.2f * llmax(1.0f, color_intens(mBrightestPoint) / intens) : 1; 797 // temp2.x is 0 at the sun and increases away from sun
798 temp2.mV[0] = llmax(temp2.mV[0], .001f);
799 // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
800 temp2.mV[0] *= glow.mV[0];
801 // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
802 temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]);
803 // glow.z should be negative, so we're doing a sort of (1 / "angle") function
1020 804
1021 mSun.setColor(mBrightnessScale * increase_sun_br * sun_color); 805 // Add "minimum anti-solar illumination"
1022 mMoon.setColor(mBrightnessScale * increase_moon_br * moon_color); 806 temp2.mV[0] += .25f;
1023 807
1024 const LLColor3 haze_col = color_norm_abs(mHaze.getSigSca());
1025 for (S32 i = 0; i < 6; ++i)
1026 {
1027 mSkyTex[i].create(mBrightnessScale, mHazeConcentration * mBrightestPoint * haze_col);
1028 }
1029 808
1030 mBrightnessScaleGuess = mBrightnessScale; 809 // Haze color above cloud
1031 mBrightestPointGuess = mBrightestPoint; 810 vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient)
811 + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + ambient)
812 );
1032 813
1033// calculateColors(); // MSMSM Moving this down to before generateScatterMap(), per Milo Lindens suggestion, to fix orange flashing bug. 814 // Increase ambient when there are more clouds
815 LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f;
1034 816
1035 mSun.renewDirection(); 817 // Dim sunlight by cloud shadow percentage
1036 mSun.renewColor(); 818 sunlight *= (1.f - cloud_shadow);
1037 mMoon.renewDirection();
1038 mMoon.renewColor();
1039 819
1040 LLColor3 transp; 820 // Haze color below cloud
821 LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient)
822 + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)
823 );
1041 824
1042 if (calcHitsEarth(mCameraPosAgent, getToSunLast()) < 0) 825 // Final atmosphere additive
1043 { 826 componentMultBy(vary_HazeColor, LLColor3::white - temp1);
1044 calcSkyColorInDir(mBrightestPointGuess, transp, getToSunLast()); 827
1045 mBrightnessScaleGuess = color_max(mBrightestPointGuess); 828 sunlight = sunlight_color;
1046 updateBrightestDir(); 829 temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f);
1047 mBrightnessScaleGuess = 1.f / llmax(1.0f, mBrightnessScaleGuess); 830 temp2.mV[1] = 1.f / temp2.mV[1];
1048 } 831 componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
1049 else if (getToSunLast().mV[2] > -0.5) 832
1050 { 833 // Attenuate cloud color by atmosphere
1051 const LLVector3 almost_to_sun = toHorizon(getToSunLast()); 834 temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds
1052 calcSkyColorInDir(mBrightestPointGuess, transp, almost_to_sun); 835
1053 mBrightnessScaleGuess = color_max(mBrightestPointGuess); 836 // At horizon, blend high altitude sky color towards the darker color below the clouds
1054 updateBrightestDir(); 837 vary_HazeColor +=
1055 mBrightnessScaleGuess = 1.f / llmax(1.0f, mBrightnessScaleGuess); 838 componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1));
1056 } 839
1057 else 840 if (Pn[1] < 0.f)
1058 { 841 {
1059 mBrightestPointGuess.setToBlack(); 842 // Eric's original:
1060 mBrightnessScaleGuess = 1; 843 // LLColor3 dark_brown(0.143f, 0.129f, 0.114f);
1061 } 844 LLColor3 dark_brown(0.082f, 0.076f, 0.066f);
845 LLColor3 brown(0.430f, 0.386f, 0.322f);
846 LLColor3 sky_lighting = sunlight + ambient;
847 F32 haze_brightness = vary_HazeColor.brightness();
1062 848
1063 calculateColors(); // MSMSM Moved this down here per Milo Lindens suggestion, to fix orange flashing bug at sunset. 849 if (Pn[1] < -0.05f)
850 {
851 vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness;
852 }
853
854 if (Pn[1] > -0.1f)
855 {
856 vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f));
857 }
858 }
1064} 859}
1065 860
861#if LL_MSVC && __MSVC_VER__ < 8
862#pragma optimize("p", off)
863#endif
1066 864
1067void LLVOSky::calculateColors() 865LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
866 LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
867 LLVector2 vary_HorizontalProjection[2])
1068{ 868{
1069 const F32 h = -0.1f; 869 LLColor3 res;
1070 const LLVector3& tosun = getToSunLast();
1071 870
1072 F32 full_on, full_off, on, on_cl; 871 LLColor3 color0 = vary_HazeColor;
1073 F32 sun_factor = 1;
1074 872
1075 // Sun Diffuse 873 if (!gPipeline.canUseWindLightShaders())
1076 F32 sun_height = tosun.mV[2]; 874 {
875 LLColor3 color1 = color0 * 2.0f;
876 color1 = smear(1.f) - componentSaturate(color1);
877 componentPow(color1, gamma);
878 res = smear(1.f) - color1;
879 }
880 else
881 {
882 res = color0;
883 }
884
885# ifndef LL_RELEASE_FOR_DOWNLOAD
886
887 LLColor3 color2 = 2.f * color0;
888
889 LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2);
890 componentPow(color3, gamma);
891 color3 = LLColor3(1.f, 1.f, 1.f) - color3;
892
893 static enum {
894 OUT_DEFAULT = 0,
895 OUT_SKY_BLUE = 1,
896 OUT_RED = 2,
897 OUT_PN = 3,
898 OUT_HAZE = 4,
899 } debugOut = OUT_DEFAULT;
900
901 switch(debugOut)
902 {
903 case OUT_DEFAULT:
904 break;
905 case OUT_SKY_BLUE:
906 res = LLColor3(0.4f, 0.4f, 0.9f);
907 break;
908 case OUT_RED:
909 res = LLColor3(1.f, 0.f, 0.f);
910 break;
911 case OUT_PN:
912 res = LLColor3(Pn[0], Pn[1], Pn[2]);
913 break;
914 case OUT_HAZE:
915 res = vary_HazeColor;
916 break;
917 }
918# endif // LL_RELEASE_FOR_DOWNLOAD
919 return res;
920}
1077 921
1078 if (sun_height <= 0.0) 922LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
1079 sun_height = 0.0; 923{
1080 924 return componentMult(diffuse, sundiffuse) * 4.0f +
1081 mSunDiffuse = mBrightnessScaleGuess * mSun.getIntensity() * mTransp.calcTransp(sun_height, h); 925 componentMult(ambient, sundiffuse) * 2.0f + sunambient;
926}
1082 927
1083 mSunDiffuse = 1.0f * color_norm(mSunDiffuse); 928LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
929{
930 return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f;
931}
1084 932
1085 // Sun Ambient 933
1086 full_off = -0.3f; 934void LLVOSky::calcAtmospherics(void)
1087 full_on = -0.03f; 935{
1088 if (tosun.mV[2] < full_off) 936 initAtmospherics();
1089 { 937
1090 mSunAmbient.setToBlack(); 938 LLColor3 vary_HazeColor;
1091 } 939 LLColor3 vary_SunlightColor;
1092 else 940 LLColor3 vary_AmbientColor;
1093 { 941 {
1094 on = (tosun.mV[2] - full_off) / (full_on - full_off); 942 // Initialize temp variables
1095 sun_factor = llmax(0.0f, llmin(on, 1.0f)); 943 LLColor3 sunlight = sunlight_color;
1096 944
1097 LLColor3 sun_amb = mAmbientScale * (0.8f * mSunDiffuse + 945 // Sunlight attenuation effect (hue and brightness) due to atmosphere
1098 0.2f * mBrightnessScaleGuess * mBrightestPointGuess); 946 // this is used later for sunlight modulation at various altitudes
947 LLColor3 light_atten =
948 (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
1099 949
1100 color_norm_pow(sun_amb, 0.1f, TRUE); 950 // Calculate relative weights
1101 sun_factor *= min_intens_factor(sun_amb, 1.9f); 951 LLColor3 temp2(0.f, 0.f, 0.f);
1102 mSunAmbient = LLColor4(sun_factor * sun_amb); 952 LLColor3 temp1 = blue_density + smear(haze_density);
1103 } 953 LLColor3 blue_weight = componentDiv(blue_density, temp1);
954 LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
1104 955
956 // Compute sunlight from P & lightnorm (for long rays like sky)
957 /// USE only lightnorm.
958 // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
959
960 // and vary_sunlight will work properly with moon light
961 F32 lighty = unclamped_lightnorm[1];
962 if(lighty < NIGHTTIME_ELEVATION_COS)
963 {
964 lighty = -lighty;
965 }
1105 966
1106 // Moon Diffuse 967 temp2.mV[1] = llmax(0.f, lighty);
1107 full_on = 0.3f; 968 temp2.mV[1] = 1.f / temp2.mV[1];
1108 full_off = 0.01f; 969 componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
1109 if (getToMoonLast().mV[2] < full_off)
1110 {
1111 mMoonDiffuse.setToBlack();
1112 }
1113 else
1114 {
1115 // Steve: Added moonlight diffuse factor scalar (was constant .3)
1116 F32 diffuse_factor = .1f + sNighttimeBrightness * .2f; // [.1, .5] default = .3
1117 on = (getToMoonLast().mV[2] - full_off) / (full_on - full_off);
1118 on_cl = llmin(on, 1.0f);
1119 mMoonDiffuse = on_cl * mNightColorShift * diffuse_factor;
1120 }
1121 970
1122 // Moon Ambient 971 // Distance
972 temp2.mV[2] = density_multiplier;
1123 973
1124 F32 moon_amb_factor = 1.f; 974 // Transparency (-> temp1)
975 temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
1125 976
1126 if (gAgent.inPrelude()) 977 // vary_AtmosAttenuation = temp1;
1127 { 978
1128 moon_amb_factor *= 2.0f; 979 //increase ambient when there are more clouds
1129 } 980 LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
981
982 //haze color
983 vary_HazeColor =
984 (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)
985 + componentMult(haze_horizon.mV[0] * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient)
986 );
987
988 //brightness of surface both sunlight and ambient
989 vary_SunlightColor = componentMult(sunlight, temp1) * 1.f;
990 vary_SunlightColor.clamp();
991 vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
992 vary_SunlightColor = componentPow(vary_SunlightColor, gamma);
993 vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
994 vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5;
995 vary_AmbientColor.clamp();
996 vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
997 vary_AmbientColor = componentPow(vary_AmbientColor, gamma);
998 vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
999
1000 componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1);
1130 1001
1131 full_on = 0.30f;
1132 full_off = 0.01f;
1133 if (getToMoonLast().mV[2] < full_off)
1134 {
1135 mMoonAmbient.setToBlack();
1136 }
1137 else
1138 {
1139 on = (getToMoonLast().mV[2] - full_off) / (full_on - full_off);
1140 on_cl = llmax(0.0f, llmin(on, 1.0f));
1141 mMoonAmbient = on_cl * moon_amb_factor * mMoonDiffuse;
1142 } 1002 }
1143 1003
1004 mSun.setColor(vary_SunlightColor);
1005 mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
1144 1006
1145 // Sun Diffuse 1007 mSun.renewDirection();
1146 full_off = -0.05f; 1008 mSun.renewColor();
1147 full_on = -0.00f; 1009 mMoon.renewDirection();
1148 if (tosun.mV[2] < full_off) 1010 mMoon.renewColor();
1011
1012 float dp = getToSunLast() * LLVector3(0,0,1.f);
1013 if (dp < 0)
1149 { 1014 {
1150 mSunDiffuse.setToBlack(); 1015 dp = 0;
1151 } 1016 }
1152 else
1153 {
1154 on = (getToSunLast().mV[2] - full_off) / (full_on - full_off);
1155 sun_factor = llmax(0.0f, llmin(on, 1.0f));
1156 1017
1157 color_norm_pow(mSunDiffuse, 0.12f, TRUE); 1018 // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
1158 sun_factor *= min_intens_factor(mSunDiffuse, 2.1f); 1019 // between sunlight and point lights in windlight to normalize point lights.
1159 mSunDiffuse *= sun_factor; 1020 F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
1160 } 1021 LLWLParamManager::instance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp);
1161 1022
1023 mSunDiffuse = vary_SunlightColor;
1024 mSunAmbient = vary_AmbientColor;
1025 mMoonDiffuse = vary_SunlightColor;
1026 mMoonAmbient = vary_AmbientColor;
1162 1027
1163 mTotalAmbient = mSunAmbient + mMoonAmbient; 1028 mTotalAmbient = vary_AmbientColor;
1164 mTotalAmbient.setAlpha(1); 1029 mTotalAmbient.setAlpha(1);
1165 //llinfos << "MoonDiffuse: " << mMoonDiffuse << llendl; 1030
1166 //llinfos << "TotalAmbient: " << mTotalAmbient << llendl;
1167
1168 mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; 1031 mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
1169 mFadeColor.setAlpha(0); 1032 mFadeColor.setAlpha(0);
1170} 1033}
1171 1034
1172
1173BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) 1035BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
1174{ 1036{
1175 return TRUE; 1037 return TRUE;
@@ -1177,7 +1039,7 @@ BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
1177 1039
1178BOOL LLVOSky::updateSky() 1040BOOL LLVOSky::updateSky()
1179{ 1041{
1180 if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))) 1042 if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
1181 { 1043 {
1182 return TRUE; 1044 return TRUE;
1183 } 1045 }
@@ -1196,7 +1058,7 @@ BOOL LLVOSky::updateSky()
1196 const S32 total_no_tiles = 6 * NUM_TILES; 1058 const S32 total_no_tiles = 6 * NUM_TILES;
1197 const S32 cycle_frame_no = total_no_tiles + 1; 1059 const S32 cycle_frame_no = total_no_tiles + 1;
1198 1060
1199// if (mUpdateTimer.getElapsedTimeF32() > 0.1f) 1061 if (mUpdateTimer.getElapsedTimeF32() > 0.001f)
1200 { 1062 {
1201 mUpdateTimer.reset(); 1063 mUpdateTimer.reset();
1202 const S32 frame = next_frame; 1064 const S32 frame = next_frame;
@@ -1205,12 +1067,13 @@ BOOL LLVOSky::updateSky()
1205 next_frame = next_frame % cycle_frame_no; 1067 next_frame = next_frame % cycle_frame_no;
1206 1068
1207 sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; 1069 sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
1070 // sInterpVal = (F32)next_frame / cycle_frame_no;
1208 LLSkyTex::setInterpVal( sInterpVal ); 1071 LLSkyTex::setInterpVal( sInterpVal );
1209 LLHeavenBody::setInterpVal( sInterpVal ); 1072 LLHeavenBody::setInterpVal( sInterpVal );
1210 calculateColors(); 1073 calcAtmospherics();
1074
1211 if (mForceUpdate || total_no_tiles == frame) 1075 if (mForceUpdate || total_no_tiles == frame)
1212 { 1076 {
1213 calcBrightnessScaleAndColors();
1214 LLSkyTex::stepCurrent(); 1077 LLSkyTex::stepCurrent();
1215 1078
1216 const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f); 1079 const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f);
@@ -1248,7 +1111,7 @@ BOOL LLVOSky::updateSky()
1248 } 1111 }
1249 } 1112 }
1250 1113
1251 calcBrightnessScaleAndColors(); 1114 calcAtmospherics();
1252 1115
1253 for (int side = 0; side < 6; side++) 1116 for (int side = 0; side < 6; side++)
1254 { 1117 {
@@ -1256,21 +1119,42 @@ BOOL LLVOSky::updateSky()
1256 LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); 1119 LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE);
1257 raw2->copy(raw1); 1120 raw2->copy(raw1);
1258 mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); 1121 mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE));
1122
1123 raw1 = mShinyTex[side].getImageRaw(TRUE);
1124 raw2 = mShinyTex[side].getImageRaw(FALSE);
1125 raw2->copy(raw1);
1126 mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE));
1259 } 1127 }
1260 next_frame = 0; 1128 next_frame = 0;
1261 } 1129 }
1130 }
1131 }
1262 1132
1263 std::vector<LLPointer<LLImageRaw> > images; 1133 /// *TODO really, sky texture and env map should be shared on a single texture
1264 for (S32 side = 0; side < 6; side++) 1134 /// I'll let Brad take this at some point
1265 { 1135
1266 images.push_back(mSkyTex[side].getImageRaw(FALSE)); 1136 // update the sky texture
1267 } 1137 for (S32 i = 0; i < 6; ++i)
1268 mCubeMap->init(images); 1138 {
1139 mSkyTex[i].create(1.0f);
1140 mShinyTex[i].create(1.0f);
1141 }
1142
1143 // update the environment map
1144 if (mCubeMap)
1145 {
1146 std::vector<LLPointer<LLImageRaw> > images;
1147 images.reserve(6);
1148 for (S32 side = 0; side < 6; side++)
1149 {
1150 images.push_back(mShinyTex[side].getImageRaw(TRUE));
1269 } 1151 }
1152 mCubeMap->init(images);
1270 } 1153 }
1271 1154
1272 gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); 1155 gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
1273 gPipeline.markRebuild(gSky.mVOStarsp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); 1156 // *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad.
1157 //gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
1274 1158
1275 mForceUpdate = FALSE; 1159 mForceUpdate = FALSE;
1276 } 1160 }
@@ -1282,15 +1166,13 @@ BOOL LLVOSky::updateSky()
1282 } 1166 }
1283 } 1167 }
1284 1168
1285 1169 if (mDrawable.notNull() && mDrawable->getFace(0) && mDrawable->getFace(0)->mVertexBuffer.isNull())
1286 if (mDrawable)
1287 { 1170 {
1288 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); 1171 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
1289 } 1172 }
1290 return TRUE; 1173 return TRUE;
1291} 1174}
1292 1175
1293
1294void LLVOSky::updateTextures(LLAgent &agent) 1176void LLVOSky::updateTextures(LLAgent &agent)
1295{ 1177{
1296 if (mSunTexturep) 1178 if (mSunTexturep)
@@ -1324,12 +1206,61 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
1324 return mDrawable; 1206 return mDrawable;
1325} 1207}
1326 1208
1209//by bao
1210//fake vertex buffer updating
1211//to guaranttee at least updating one VBO buffer every frame
1212//to walk around the bug caused by ATI card --> DEV-3855
1213//
1214void LLVOSky::createDummyVertexBuffer()
1215{
1216 if(!mFace[FACE_DUMMY])
1217 {
1218 LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
1219 mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL);
1220 }
1221
1222 if(mFace[FACE_DUMMY]->mVertexBuffer.isNull())
1223 {
1224 mFace[FACE_DUMMY]->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
1225 mFace[FACE_DUMMY]->mVertexBuffer->allocateBuffer(1, 1, TRUE);
1226 }
1227}
1228
1229void LLVOSky::updateDummyVertexBuffer()
1230{
1231 if(!LLVertexBuffer::sEnableVBOs)
1232 return ;
1233
1234 if(mHeavenlyBodyUpdated)
1235 {
1236 mHeavenlyBodyUpdated = FALSE ;
1237 return ;
1238 }
1239
1240 LLFastTimer t(LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE) ;
1241
1242 if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull())
1243 createDummyVertexBuffer() ;
1244
1245 LLStrider<LLVector3> vertices ;
1246 mFace[FACE_DUMMY]->mVertexBuffer->getVertexStrider(vertices, 0);
1247 *vertices = mCameraPosAgent ;
1248 mFace[FACE_DUMMY]->mVertexBuffer->setBuffer(0) ;
1249}
1250//----------------------------------
1251//end of fake vertex buffer updating
1252//----------------------------------
1253
1327BOOL LLVOSky::updateGeometry(LLDrawable *drawable) 1254BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1328{ 1255{
1256 LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY);
1329 if (mFace[FACE_REFLECTION] == NULL) 1257 if (mFace[FACE_REFLECTION] == NULL)
1330 { 1258 {
1331 LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); 1259 LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
1332 mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL); 1260 if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() != 0)
1261 {
1262 mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);
1263 }
1333 } 1264 }
1334 1265
1335 mCameraPosAgent = drawable->getPositionAgent(); 1266 mCameraPosAgent = drawable->getPositionAgent();
@@ -1342,14 +1273,14 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1342 F32 x_sgn = (i&1) ? 1.f : -1.f; 1273 F32 x_sgn = (i&1) ? 1.f : -1.f;
1343 F32 y_sgn = (i&2) ? 1.f : -1.f; 1274 F32 y_sgn = (i&2) ? 1.f : -1.f;
1344 F32 z_sgn = (i&4) ? 1.f : -1.f; 1275 F32 z_sgn = (i&4) ? 1.f : -1.f;
1345 v_agent[i] = HORIZON_DIST*0.25f * LLVector3(x_sgn, y_sgn, z_sgn); 1276 v_agent[i] = HORIZON_DIST * SKY_BOX_MULT * LLVector3(x_sgn, y_sgn, z_sgn);
1346 } 1277 }
1347 1278
1348 LLStrider<LLVector3> verticesp; 1279 LLStrider<LLVector3> verticesp;
1349 LLStrider<LLVector3> normalsp; 1280 LLStrider<LLVector3> normalsp;
1350 LLStrider<LLVector2> texCoordsp; 1281 LLStrider<LLVector2> texCoordsp;
1351 LLStrider<U32> indicesp; 1282 LLStrider<U16> indicesp;
1352 S32 index_offset; 1283 U16 index_offset;
1353 LLFace *face; 1284 LLFace *face;
1354 1285
1355 for (S32 side = 0; side < 6; ++side) 1286 for (S32 side = 0; side < 6; ++side)
@@ -1395,6 +1326,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1395 *indicesp++ = index_offset + 0; 1326 *indicesp++ = index_offset + 0;
1396 *indicesp++ = index_offset + 3; 1327 *indicesp++ = index_offset + 3;
1397 *indicesp++ = index_offset + 2; 1328 *indicesp++ = index_offset + 2;
1329
1330 face->mVertexBuffer->setBuffer(0);
1398 } 1331 }
1399 } 1332 }
1400 1333
@@ -1430,11 +1363,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1430 1363
1431 if (height_above_water > 0) 1364 if (height_above_water > 0)
1432 { 1365 {
1433#if 1 //1.9.1
1434 BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; 1366 BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
1435#else 1367
1436 BOOL render_ref = !(gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= LLDrawPoolWater::SHADER_LEVEL_RIPPLE);
1437#endif
1438 if (sun_flag) 1368 if (sun_flag)
1439 { 1369 {
1440 setDrawRefl(0); 1370 setDrawRefl(0);
@@ -1457,24 +1387,29 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1457 setDrawRefl(-1); 1387 setDrawRefl(-1);
1458 } 1388 }
1459 1389
1460
1461 LLPipeline::sCompiles++; 1390 LLPipeline::sCompiles++;
1462 return TRUE; 1391 return TRUE;
1463} 1392}
1464 1393
1465
1466BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, 1394BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun,
1467 LLHeavenBody& hb, const F32 cos_max_angle, 1395 LLHeavenBody& hb, const F32 cos_max_angle,
1468 const LLVector3 &up, const LLVector3 &right) 1396 const LLVector3 &up, const LLVector3 &right)
1469{ 1397{
1398 mHeavenlyBodyUpdated = TRUE ;
1399
1470 LLStrider<LLVector3> verticesp; 1400 LLStrider<LLVector3> verticesp;
1471 LLStrider<LLVector3> normalsp; 1401 LLStrider<LLVector3> normalsp;
1472 LLStrider<LLVector2> texCoordsp; 1402 LLStrider<LLVector2> texCoordsp;
1473 LLStrider<U32> indicesp; 1403 LLStrider<U16> indicesp;
1474 S32 index_offset; 1404 S32 index_offset;
1475 LLFace *facep; 1405 LLFace *facep;
1476 1406
1477 LLVector3 to_dir = hb.getDirection(); 1407 LLVector3 to_dir = hb.getDirection();
1408
1409 if (!is_sun)
1410 {
1411 to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f);
1412 }
1478 LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST; 1413 LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
1479 1414
1480 1415
@@ -1521,14 +1456,15 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
1521 1456
1522 if (facep->mVertexBuffer.isNull()) 1457 if (facep->mVertexBuffer.isNull())
1523 { 1458 {
1524 facep->setSize(4, 6); 1459 facep->setSize(4, 6);
1525 facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); 1460 facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
1526 facep->mVertexBuffer->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); 1461 facep->mVertexBuffer->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE);
1527 facep->setGeomIndex(0); 1462 facep->setGeomIndex(0);
1528 facep->setIndicesIndex(0); 1463 facep->setIndicesIndex(0);
1529 } 1464 }
1530 1465
1531 index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); 1466 index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
1467
1532 if (-1 == index_offset) 1468 if (-1 == index_offset)
1533 { 1469 {
1534 return TRUE; 1470 return TRUE;
@@ -1542,10 +1478,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
1542 1478
1543 *(texCoordsp++) = TEX01; 1479 *(texCoordsp++) = TEX01;
1544 *(texCoordsp++) = TEX00; 1480 *(texCoordsp++) = TEX00;
1545 //*(texCoordsp++) = (t_left > 0) ? LLVector2(0, t_left) : TEX00;
1546 *(texCoordsp++) = TEX11; 1481 *(texCoordsp++) = TEX11;
1547 *(texCoordsp++) = TEX10; 1482 *(texCoordsp++) = TEX10;
1548 //*(texCoordsp++) = (t_right > 0) ? LLVector2(1, t_right) : TEX10;
1549 1483
1550 *indicesp++ = index_offset + 0; 1484 *indicesp++ = index_offset + 0;
1551 *indicesp++ = index_offset + 2; 1485 *indicesp++ = index_offset + 2;
@@ -1555,6 +1489,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
1555 *indicesp++ = index_offset + 2; 1489 *indicesp++ = index_offset + 2;
1556 *indicesp++ = index_offset + 3; 1490 *indicesp++ = index_offset + 3;
1557 1491
1492 facep->mVertexBuffer->setBuffer(0);
1493
1558 if (is_sun) 1494 if (is_sun)
1559 { 1495 {
1560 if ((t_left > 0) && (t_right > 0)) 1496 if ((t_left > 0) && (t_right > 0))
@@ -1651,12 +1587,13 @@ F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos
1651 1587
1652void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) 1588void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable )
1653{ 1589{
1590#if 0
1654 const LLVector3* v_corner = mSun.corners(); 1591 const LLVector3* v_corner = mSun.corners();
1655 1592
1656 LLStrider<LLVector3> verticesp; 1593 LLStrider<LLVector3> verticesp;
1657 LLStrider<LLVector3> normalsp; 1594 LLStrider<LLVector3> normalsp;
1658 LLStrider<LLVector2> texCoordsp; 1595 LLStrider<LLVector2> texCoordsp;
1659 LLStrider<U32> indicesp; 1596 LLStrider<U16> indicesp;
1660 S32 index_offset; 1597 S32 index_offset;
1661 LLFace *face; 1598 LLFace *face;
1662 1599
@@ -1708,6 +1645,7 @@ void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable )
1708 *indicesp++ = index_offset + 1; 1645 *indicesp++ = index_offset + 1;
1709 *indicesp++ = index_offset + 2; 1646 *indicesp++ = index_offset + 2;
1710 *indicesp++ = index_offset + 3; 1647 *indicesp++ = index_offset + 3;
1648#endif
1711} 1649}
1712 1650
1713 1651
@@ -1932,7 +1870,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
1932 LLStrider<LLVector3> verticesp; 1870 LLStrider<LLVector3> verticesp;
1933 LLStrider<LLVector3> normalsp; 1871 LLStrider<LLVector3> normalsp;
1934 LLStrider<LLVector2> texCoordsp; 1872 LLStrider<LLVector2> texCoordsp;
1935 LLStrider<U32> indicesp; 1873 LLStrider<U16> indicesp;
1936 S32 index_offset; 1874 S32 index_offset;
1937 1875
1938 index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); 1876 index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
@@ -2063,6 +2001,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
2063 } 2001 }
2064 } 2002 }
2065 } 2003 }
2004
2005 face->mVertexBuffer->setBuffer(0);
2066} 2006}
2067 2007
2068 2008
@@ -2072,37 +2012,11 @@ void LLVOSky::updateFog(const F32 distance)
2072{ 2012{
2073 if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) 2013 if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
2074 { 2014 {
2075 /*gGLSFog.addCap(GL_FOG, FALSE);
2076 gGLSPipeline.addCap(GL_FOG, FALSE);
2077 gGLSPipelineAlpha.addCap(GL_FOG, FALSE);
2078 gGLSPipelinePixieDust.addCap(GL_FOG, FALSE);
2079 gGLSPipelineSelection.addCap(GL_FOG, FALSE);
2080 gGLSPipelineAvatar.addCap(GL_FOG, FALSE);
2081 gGLSPipelineAvatarAlphaOnePass.addCap(GL_FOG, FALSE);
2082 gGLSPipelineAvatarAlphaPass1.addCap(GL_FOG, FALSE);
2083 gGLSPipelineAvatarAlphaPass2.addCap(GL_FOG, FALSE);
2084 gGLSPipelineAvatarAlphaPass3.addCap(GL_FOG, FALSE);*/
2085 glFogf(GL_FOG_DENSITY, 0); 2015 glFogf(GL_FOG_DENSITY, 0);
2086 glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); 2016 glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
2087 glFogf(GL_FOG_END, 1000000.f); 2017 glFogf(GL_FOG_END, 1000000.f);
2088 return; 2018 return;
2089 } 2019 }
2090 else
2091 {
2092 /*gGLSFog.addCap(GL_FOG, TRUE);
2093 gGLSPipeline.addCap(GL_FOG, TRUE);
2094 gGLSPipelineAlpha.addCap(GL_FOG, TRUE);
2095 gGLSPipelinePixieDust.addCap(GL_FOG, TRUE);
2096 gGLSPipelineSelection.addCap(GL_FOG, TRUE);
2097 if (!gGLManager.mIsATI)
2098 {
2099 gGLSPipelineAvatar.addCap(GL_FOG, TRUE);
2100 gGLSPipelineAvatarAlphaOnePass.addCap(GL_FOG, TRUE);
2101 gGLSPipelineAvatarAlphaPass1.addCap(GL_FOG, TRUE);
2102 gGLSPipelineAvatarAlphaPass2.addCap(GL_FOG, TRUE);
2103 gGLSPipelineAvatarAlphaPass3.addCap(GL_FOG, TRUE);
2104 }*/
2105 }
2106 2020
2107 const BOOL hide_clip_plane = TRUE; 2021 const BOOL hide_clip_plane = TRUE;
2108 LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); 2022 LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
@@ -2120,7 +2034,6 @@ void LLVOSky::updateFog(const F32 distance)
2120 LLColor3 sky_fog_color = LLColor3::white; 2034 LLColor3 sky_fog_color = LLColor3::white;
2121 LLColor3 render_fog_color = LLColor3::white; 2035 LLColor3 render_fog_color = LLColor3::white;
2122 2036
2123 LLColor3 transp;
2124 LLVector3 tosun = getToSunLast(); 2037 LLVector3 tosun = getToSunLast();
2125 const F32 tosun_z = tosun.mV[VZ]; 2038 const F32 tosun_z = tosun.mV[VZ];
2126 tosun.mV[VZ] = 0.f; 2039 tosun.mV[VZ] = 0.f;
@@ -2140,9 +2053,10 @@ void LLVOSky::updateFog(const F32 distance)
2140 tosun_45.normVec(); 2053 tosun_45.normVec();
2141 2054
2142 // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. 2055 // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun.
2143 calcSkyColorInDir(res_color[0],transp, tosun); 2056 initAtmospherics();
2144 calcSkyColorInDir(res_color[1],transp, perp_tosun); 2057 res_color[0] = calcSkyColorInDir(tosun);
2145 calcSkyColorInDir(res_color[2],transp, tosun_45); 2058 res_color[1] = calcSkyColorInDir(perp_tosun);
2059 res_color[2] = calcSkyColorInDir(tosun_45);
2146 2060
2147 sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); 2061 sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
2148 2062
@@ -2163,54 +2077,59 @@ void LLVOSky::updateFog(const F32 distance)
2163 color_gamma_correct(sky_fog_color); 2077 color_gamma_correct(sky_fog_color);
2164 2078
2165 render_fog_color = sky_fog_color; 2079 render_fog_color = sky_fog_color;
2080
2081 F32 fog_density = 0.f;
2082 fog_distance = mFogRatio * distance;
2166 2083
2167 if (camera_height > water_height) 2084 if (camera_height > water_height)
2168 { 2085 {
2169 fog_distance = mFogRatio * distance;
2170 LLColor4 fog(render_fog_color); 2086 LLColor4 fog(render_fog_color);
2171 glFogfv(GL_FOG_COLOR, fog.mV); 2087 glFogfv(GL_FOG_COLOR, fog.mV);
2172 mGLFogCol = fog; 2088 mGLFogCol = fog;
2089
2090 if (hide_clip_plane)
2091 {
2092 // For now, set the density to extend to the cull distance.
2093 const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
2094 fog_density = f_log/fog_distance;
2095 glFogi(GL_FOG_MODE, GL_EXP2);
2096 }
2097 else
2098 {
2099 const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
2100 fog_density = (f_log)/fog_distance;
2101 glFogi(GL_FOG_MODE, GL_EXP);
2102 }
2173 } 2103 }
2174 else 2104 else
2175 { 2105 {
2176 // Interpolate between sky fog and water fog...
2177 F32 depth = water_height - camera_height; 2106 F32 depth = water_height - camera_height;
2178 F32 depth_frac = 1.f/(1.f + 200.f*depth); 2107
2179 F32 color_frac = 1.f/(1.f + 0.5f* depth)* 0.2f; 2108 // get the water param manager variables
2180 fog_distance = (mFogRatio * distance) * depth_frac + 30.f * (1.f-depth_frac); 2109 float water_fog_density = LLWaterParamManager::instance()->getFogDensity();
2181 fog_distance = llmin(75.f, fog_distance); 2110 LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV;
2182 2111
2183 F32 brightness = 1.f/(1.f + 0.05f*depth); 2112 // adjust the color based on depth. We're doing linear approximations
2184 F32 sun_brightness = getSunDiffuseColor().magVec() * 0.3f; 2113 float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
2185 brightness = llmin(1.f, brightness); 2114 float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),
2186 brightness = llmin(brightness, sun_brightness); 2115 gSavedSettings.getF32("WaterGLFogDepthFloor"));
2187 color_frac = llmin(0.7f, color_frac); 2116
2188 2117 LLColor4 fogCol = water_fog_color * depth_modifier;
2189 LLColor4 fogCol = brightness * (color_frac * render_fog_color + (1.f - color_frac) * LLColor4(0.f, 0.2f, 0.3f, 1.f));
2190 fogCol.setAlpha(1); 2118 fogCol.setAlpha(1);
2119
2120 // set the gl fog color
2191 glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); 2121 glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
2192 mGLFogCol = fogCol; 2122 mGLFogCol = fogCol;
2123
2124 // set the density based on what the shaders use
2125 fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
2126 glFogi(GL_FOG_MODE, GL_EXP2);
2193 } 2127 }
2194 2128
2195 mFogColor = sky_fog_color; 2129 mFogColor = sky_fog_color;
2196 mFogColor.setAlpha(1); 2130 mFogColor.setAlpha(1);
2197 LLGLSFog gls_fog; 2131 LLGLSFog gls_fog;
2198 2132
2199 F32 fog_density;
2200 if (hide_clip_plane)
2201 {
2202 // For now, set the density to extend to the cull distance.
2203 const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
2204 fog_density = f_log/fog_distance;
2205 glFogi(GL_FOG_MODE, GL_EXP2);
2206 }
2207 else
2208 {
2209 const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
2210 fog_density = (f_log)/fog_distance;
2211 glFogi(GL_FOG_MODE, GL_EXP);
2212 }
2213
2214 glFogf(GL_FOG_END, fog_distance*2.2f); 2133 glFogf(GL_FOG_END, fog_distance*2.2f);
2215 2134
2216 glFogf(GL_FOG_DENSITY, fog_density); 2135 glFogf(GL_FOG_DENSITY, fog_density);
@@ -2279,197 +2198,53 @@ F32 azimuth(const LLVector3 &v)
2279 return azimuth; 2198 return azimuth;
2280} 2199}
2281 2200
2282 2201void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
2283#if 0
2284// Not currently used
2285LLColor3 LLVOSky::calcGroundFog(LLColor3& transp, const LLVector3 &view_dir, F32 obj_dist) const
2286{
2287 LLColor3 col;
2288 calcGroundFog(col, transp, view_dir, obj_dist);
2289 col *= mBrightnessScaleGuess;
2290 return col;
2291}
2292#endif
2293
2294void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
2295{ 2202{
2296 LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir; 2203 LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir;
2297 sun_direction.normVec(); 2204 sun_direction.normVec();
2298 F32 dp = mSun.getDirection() * sun_direction;
2299 mSun.setDirection(sun_direction); 2205 mSun.setDirection(sun_direction);
2206 mSun.renewDirection();
2300 mSun.setAngularVelocity(sun_ang_velocity); 2207 mSun.setAngularVelocity(sun_ang_velocity);
2301 mMoon.setDirection(-sun_direction); 2208 mMoon.setDirection(-mSun.getDirection());
2302 if (dp < 0.995f) { //the sun jumped a great deal, update immediately 2209 mMoon.renewDirection();
2303 updateHaze(); 2210 mLastLightingDirection = mSun.getDirection();
2304 mWeatherChange = FALSE;
2305 mForceUpdate = TRUE;
2306 }
2307 else if (mWeatherChange && (mSun.getDirection().mV[VZ] > -0.5) )
2308 {
2309 updateHaze();
2310 init();
2311 mWeatherChange = FALSE;
2312 }
2313 else if (mSun.getDirection().mV[VZ] < -0.5)
2314 {
2315 mWeatherChange = TRUE;
2316 }
2317}
2318
2319#define INV_WAVELENGTH_R_POW4 (1.f/0.2401f) // = 1/0.7^4
2320#define INV_WAVELENGTH_G_POW4 (1.f/0.0789f) // = 1/0.53^4
2321#define INV_WAVELENGTH_B_POW4 (1.f/0.03748f) // = 1/0.44^4
2322
2323// Dummy class for globals used below. Replace when KILLERSKY is merged in.
2324class LLKillerSky
2325{
2326public:
2327 static F32 sRaleighGroundDensity;
2328 static F32 sMieFactor;
2329 static F32 sNearFalloffFactor;
2330 static F32 sSkyContrib;
2331
2332 static void getRaleighCoefficients(float eye_sun_dp, float density, float *coefficients)
2333 {
2334 float dp = eye_sun_dp;
2335 float angle_dep = density*(1 + dp*dp);
2336 coefficients[0] = angle_dep * INV_WAVELENGTH_R_POW4;
2337 coefficients[1] = angle_dep * INV_WAVELENGTH_G_POW4;
2338 coefficients[2] = angle_dep * INV_WAVELENGTH_B_POW4;
2339 }
2340
2341 static void getMieCoefficients(float eye_sun_dp, float density, float *coefficient)
2342 {
2343 // TOTALLY ARBITRARY FUNCTION. Seems to work though
2344 // If anyone can replace this with some *actual* mie function, that'd be great
2345 float dp = eye_sun_dp;
2346 float dp_highpower = dp*dp;
2347 float angle_dep = density * (llclamp(dp_highpower*dp, 0.f, 1.f) + 0.4f);
2348 *coefficient = angle_dep;
2349 }
2350};
2351
2352F32 LLKillerSky::sRaleighGroundDensity = 0.013f;
2353F32 LLKillerSky::sMieFactor = 50;
2354F32 LLKillerSky::sNearFalloffFactor = 1.5f;
2355F32 LLKillerSky::sSkyContrib = 0.06f;
2356
2357void LLVOSky::generateScatterMap()
2358{
2359 float raleigh[3], mie;
2360
2361 mScatterMap = new LLImageGL(FALSE);
2362 mScatterMapRaw = new LLImageRaw(256, 256, 4);
2363 U8 *data = mScatterMapRaw->getData();
2364 2211
2365 F32 light_brightness = gSky.getSunDirection().mV[VZ]+0.1f; 2212 calcAtmospherics();
2366 LLColor4 light_color;
2367 LLColor4 sky_color;
2368 if (light_brightness > 0)
2369 {
2370 F32 interp = sqrtf(light_brightness);
2371 light_brightness = sqrt(sqrtf(interp));
2372 light_color = lerp(gSky.getSunDiffuseColor(), LLColor4(1,1,1,1), interp) * light_brightness;
2373 sky_color = lerp(LLColor4(0,0,0,0), LLColor4(0.4f, 0.6f, 1.f, 1.f), light_brightness)*LLKillerSky::sSkyContrib;
2374 }
2375 else
2376 {
2377 light_brightness = /*0.3f*/sqrt(-light_brightness);
2378 light_color = gSky.getMoonDiffuseColor() * light_brightness;
2379 sky_color = LLColor4(0,0,0,1);
2380 }
2381 2213
2382 // x = distance [0..1024m] 2214 if ( !mInitialized )
2383 // y = dot product [-1,1]
2384 for (int y=0;y<256;y++)
2385 { 2215 {
2386 // Accumulate outward 2216 init();
2387 float accum_r = 0, accum_g = 0, accum_b = 0; 2217 LLSkyTex::stepCurrent();
2388 2218 }
2389 float dp = (((float)y)/255.f)*1.95f - 0.975f;
2390 U8 *scanline = &data[y*256*4];
2391 for (int x=0;x<256;x++)
2392 {
2393 float dist = ((float)x+1)*4; // x -> 2048
2394
2395 float raleigh_density = LLKillerSky::sRaleighGroundDensity * 0.05f; // Arbitrary? Perhaps...
2396 float mie_density = raleigh_density*LLKillerSky::sMieFactor;
2397
2398 float extinction_factor = dist/LLKillerSky::sNearFalloffFactor;
2399
2400 LLKillerSky::getRaleighCoefficients(dp, raleigh_density, raleigh);
2401 LLKillerSky::getMieCoefficients(dp, mie_density, &mie);
2402
2403 float falloff_r = pow(llclamp(0.985f-raleigh[0],0.f,1.f), extinction_factor);
2404 float falloff_g = pow(llclamp(0.985f-raleigh[1],0.f,1.f), extinction_factor);
2405 float falloff_b = pow(llclamp(0.985f-raleigh[2],0.f,1.f), extinction_factor);
2406
2407 float light_r = light_color.mV[0] * (raleigh[0]+mie+sky_color.mV[0]) * falloff_r;
2408 float light_g = light_color.mV[1] * (raleigh[1]+mie+sky_color.mV[1]) * falloff_g;
2409 float light_b = light_color.mV[2] * (raleigh[2]+mie+sky_color.mV[2]) * falloff_b;
2410
2411 accum_r += light_r;
2412 accum_g += light_g;
2413 accum_b += light_b;
2414
2415 scanline[x*4] = (U8)llclamp(accum_r*255.f, 0.f, 255.f);
2416 scanline[x*4+1] = (U8)llclamp(accum_g*255.f, 0.f, 255.f);
2417 scanline[x*4+2] = (U8)llclamp(accum_b*255.f, 0.f, 255.f);
2418 float alpha = ((falloff_r+falloff_g+falloff_b)*0.33f);
2419 scanline[x*4+3] = (U8)llclamp(alpha*255.f, 0.f, 255.f); // Avg falloff
2420
2421 // Output color Co, Input color Ci, Map channels Mrgb, Ma:
2422 // Co = (Ci * Ma) + Mrgb
2423 }
2424 }
2425
2426 mScatterMap->createGLTexture(0, mScatterMapRaw);
2427 mScatterMap->bind(0);
2428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2429 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2430} 2219}
2431 2220
2432#if 0 2221void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
2433// Not currently used
2434void LLVOSky::calcGroundFog(LLColor3& res, LLColor3& transp, const LLVector3 view_dir, F32 obj_dist) const
2435{ 2222{
2436 const LLVector3& tosun = getToSunLast();//use_old_value ? sunDir() : toSunLast(); 2223 LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir;
2437 res.setToBlack(); 2224 sun_direction.normVec();
2438 transp.setToWhite();
2439 const F32 dist = obj_dist * mWorldScale;
2440
2441 //LLVector3 view_dir = gCamera->getAtAxis();
2442
2443 const F32 cos_dir = view_dir * tosun;
2444 LLVector3 dir = view_dir;
2445 LLVector3 virtual_P = mCameraPosAgent + dist * dir;
2446 2225
2447 if (dir.mV[VZ] < 0) 2226 // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
2448 { 2227 // on the upward facing faces of cubes.
2449 dir = -dir; 2228 LLVector3 newDir = sun_direction;
2450 }
2451 2229
2452 const F32 z_dir = dir.mV[2]; 2230 // Same as dot product with the up direction + clamp.
2231 F32 sunDot = llmax(0.f, newDir.mV[2]);
2232 sunDot *= sunDot;
2453 2233
2454 const F32 h = mCameraPosAgent.mV[2]; 2234 // Create normalized vector that has the sunDir pushed south about an hour and change.
2235 LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
2455 2236
2456 transp = color_div(mTransp.calcTransp(dir * calcUpVec(virtual_P), 0), 2237 // Blend between normal sun dir and adjusted sun dir based on how close we are
2457 mTransp.calcTransp(z_dir, h)); 2238 // to having the sun overhead.
2239 mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot);
2240 mBumpSunDir.normVec();
2458 2241
2459 if (calcHitsEarth(mCameraPosAgent, tosun) > 0) 2242 F32 dp = mLastLightingDirection * sun_direction;
2460 { 2243 mSun.setDirection(sun_direction);
2461 const F32 avg = llmin(1.f, 1.2f * color_avg(transp)); 2244 mSun.setAngularVelocity(sun_ang_velocity);
2462 transp = LLColor3(avg, avg, avg); 2245 mMoon.setDirection(-sun_direction);
2463 return; 2246 calcAtmospherics();
2247 if (dp < 0.995f) { //the sun jumped a great deal, update immediately
2248 mForceUpdate = TRUE;
2464 } 2249 }
2465
2466 LLColor3 haze_sca_opt_depth = mHaze.getSigSca();
2467 LLColor3 sun_transp;
2468 mTransp.calcTransp(tosun.mV[2], -0.1f, sun_transp);
2469
2470 res = calcAirPhaseFunc(cos_dir) * LLHaze::getAirScaSeaLevel();
2471 res += mHaze.calcPhase(cos_dir) * mHaze.getSigSca();
2472 res = mSun.getIntensity() * dist * sun_transp * res;
2473} 2250}
2474
2475#endif