diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llvosky.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-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 'linden/indra/newview/llvosky.cpp')
-rw-r--r-- | linden/indra/newview/llvosky.cpp | 1505 |
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 | ||
57 | const S32 NUM_TILES_X = 8; | 60 | #undef min |
58 | const S32 NUM_TILES_Y = 4; | 61 | #undef max |
59 | const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; | 62 | |
63 | static const S32 NUM_TILES_X = 8; | ||
64 | static const S32 NUM_TILES_Y = 4; | ||
65 | static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; | ||
60 | 66 | ||
61 | // Heavenly body constants | 67 | // Heavenly body constants |
62 | const F32 SUN_DISK_RADIUS = 0.5f; | 68 | static const F32 SUN_DISK_RADIUS = 0.5f; |
63 | const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f; | 69 | static const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f; |
64 | const F32 SUN_INTENSITY = 1e5; | 70 | static const F32 SUN_INTENSITY = 1e5; |
65 | const F32 SUN_DISK_INTENSITY = 24.f; | 71 | static const F32 SUN_DISK_INTENSITY = 24.f; |
66 | 72 | ||
67 | 73 | ||
68 | // Texture coordinates: | 74 | // Texture coordinates: |
69 | const LLVector2 TEX00 = LLVector2(0.f, 0.f); | 75 | static const LLVector2 TEX00 = LLVector2(0.f, 0.f); |
70 | const LLVector2 TEX01 = LLVector2(0.f, 1.f); | 76 | static const LLVector2 TEX01 = LLVector2(0.f, 1.f); |
71 | const LLVector2 TEX10 = LLVector2(1.f, 0.f); | 77 | static const LLVector2 TEX10 = LLVector2(1.f, 0.f); |
72 | const LLVector2 TEX11 = LLVector2(1.f, 1.f); | 78 | static const LLVector2 TEX11 = LLVector2(1.f, 1.f); |
73 | 79 | ||
74 | // Exported globals | 80 | // Exported globals |
75 | LLUUID gSunTextureID = IMG_SUN; | 81 | LLUUID 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 | ||
137 | LLFastLn gFastLn; | 143 | static 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 | ||
166 | inline 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 | |||
177 | inline 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 | |||
191 | inline F32 color_intens ( const LLColor4 &col ) | ||
192 | { | ||
193 | return col.mV[0] + col.mV[1] + col.mV[2]; | ||
194 | } | ||
195 | |||
196 | |||
197 | inline F32 color_avg ( const LLColor3 &col ) | ||
198 | { | ||
199 | return color_intens(col) / 3.f; | ||
200 | } | ||
201 | |||
202 | inline void color_gamma_correct(LLColor3 &col) | 172 | inline 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 | ||
219 | inline F32 min_intens_factor( LLColor3& col, F32 min_intens, BOOL postmultiply = FALSE); | ||
220 | inline 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 | |||
238 | inline 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 | |||
254 | void 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 | |||
277 | LLColor3 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 | |||
329 | F32 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 | |||
341 | void 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 | |||
369 | LLTranspMapSet::~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 | ||
393 | void LLSkyTex::init() | 205 | void 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 | 266 | void LLSkyTex::create(const F32 brightness) | |
455 | void 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 | |||
481 | void LLSkyTex::createGLImage(S32 which) | 287 | void 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 | ||
496 | F32 LLHeavenBody::sInterpVal = 0; | 302 | F32 LLHeavenBody::sInterpVal = 0; |
497 | 303 | ||
498 | F32 LLVOSky::sNighttimeBrightness = 1.5f; | ||
499 | |||
500 | S32 LLVOSky::sResolution = LLSkyTex::getResolution(); | 304 | S32 LLVOSky::sResolution = LLSkyTex::getResolution(); |
501 | S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; | 305 | S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; |
502 | S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y; | 306 | S32 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 | ||
571 | void LLVOSky::init() | 401 | void 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 | ||
596 | void LLVOSky::initCubeMap() | 431 | void 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 | |||
670 | void 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 | |||
730 | void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) | 504 | void 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 | 555 | static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) | |
780 | LLColor3 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); | 563 | static 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 | ||
807 | LLColor4 LLVOSky::calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exager = 1) const | 571 | static 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 | ||
578 | static 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 | 585 | static inline LLColor3 componentSaturate(LLColor3 const &v) | |
818 | void 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 | ||
593 | static 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 | ||
600 | static 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 | ||
875 | void LLVOSky::calcInScatter(LLColor3& res, LLColor3& transp, | 607 | static 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; | 612 | static 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); | 627 | static 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), | 632 | void 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) | 671 | LLColor4 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 | ||
739 | void 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 | |
943 | F32 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 | ||
962 | F32 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 | ||
973 | void 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 | ||
992 | void 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 | ||
1067 | void LLVOSky::calculateColors() | 865 | LLColor3 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) | 922 | LLColor3 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); | 928 | LLColor3 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; | 934 | void 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 | |||
1173 | BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) | 1035 | BOOL 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 | ||
1178 | BOOL LLVOSky::updateSky() | 1040 | BOOL 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 | |||
1294 | void LLVOSky::updateTextures(LLAgent &agent) | 1176 | void 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 | // | ||
1214 | void 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 | |||
1229 | void 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 | |||
1327 | BOOL LLVOSky::updateGeometry(LLDrawable *drawable) | 1254 | BOOL 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 | |||
1466 | BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, | 1394 | BOOL 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 | ||
1652 | void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) | 1588 | void 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 | 2201 | void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) | |
2283 | #if 0 | ||
2284 | // Not currently used | ||
2285 | LLColor3 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 | |||
2294 | void 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. | ||
2324 | class LLKillerSky | ||
2325 | { | ||
2326 | public: | ||
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 | |||
2352 | F32 LLKillerSky::sRaleighGroundDensity = 0.013f; | ||
2353 | F32 LLKillerSky::sMieFactor = 50; | ||
2354 | F32 LLKillerSky::sNearFalloffFactor = 1.5f; | ||
2355 | F32 LLKillerSky::sSkyContrib = 0.06f; | ||
2356 | |||
2357 | void 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 | 2221 | void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) |
2433 | // Not currently used | ||
2434 | void 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 | ||