llvosky.cpp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146
  1. /**
  2. * @file llvosky.cpp
  3. * @brief LLVOSky class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llvosky.h"
  34. #include "imageids.h"
  35. #include "llcubemap.h"
  36. #include "llfasttimer.h"
  37. #include "llgl.h"
  38. #include "llagent.h"
  39. #include "lldrawable.h"
  40. #include "lldrawpoolsky.h"
  41. #include "lldrawpoolwater.h"
  42. #include "lldrawpoolwlsky.h"
  43. #include "llenvironment.h"
  44. #include "llface.h"
  45. #include "llfeaturemanager.h"
  46. #include "llpipeline.h"
  47. #include "llsky.h"
  48. #include "llviewercamera.h"
  49. #include "llviewercontrol.h"
  50. #include "llviewerobjectlist.h"
  51. #include "llviewerregion.h"
  52. #include "llviewertexturelist.h"
  53. #include "llworld.h"
  54. // Constants
  55. // Exported
  56. const F32 NIGHTTIME_ELEVATION_COS = sinf(NIGHTTIME_ELEVATION * DEG_TO_RAD);
  57. constexpr S32 NUM_TILES_X = 8;
  58. constexpr S32 NUM_TILES_Y = 4;
  59. constexpr S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
  60. // Amortize updating face; see sTileResX
  61. constexpr S32 UPDATE_TILES = NUM_TILES / 8;
  62. constexpr S32 NUM_CUBEMAP_FACES = 6;
  63. constexpr S32 TOTAL_TILES = NUM_CUBEMAP_FACES * NUM_TILES;
  64. constexpr S32 MAX_TILES = TOTAL_TILES + 1;
  65. // Heavenly body constants
  66. constexpr F32 SUN_DISK_RADIUS = 0.5f;
  67. constexpr F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
  68. constexpr F32 SUN_INTENSITY = 1e5f;
  69. // Texture coordinates:
  70. const LLVector2 TEX00 = LLVector2(0.f, 0.f);
  71. const LLVector2 TEX01 = LLVector2(0.f, 1.f);
  72. const LLVector2 TEX10 = LLVector2(1.f, 0.f);
  73. const LLVector2 TEX11 = LLVector2(1.f, 1.f);
  74. constexpr F32 UPDATE_EXPIRY = 0.05f;
  75. constexpr F32 UPDATE_MIN_DELTA_THRESHOLD = 0.001f;
  76. // Exported globals
  77. LLUUID gSunTextureID = IMG_SUN;
  78. LLUUID gMoonTextureID = IMG_MOON;
  79. // Helpers
  80. bool almost_equal(const F32& a, const F32& b)
  81. {
  82. F32 diff = fabs(a - b);
  83. if (diff < F_APPROXIMATELY_ZERO)
  84. {
  85. return true;
  86. }
  87. if (diff < llmax(fabs(a), fabs(b)) * UPDATE_MIN_DELTA_THRESHOLD)
  88. {
  89. return true;
  90. }
  91. return false;
  92. }
  93. bool almost_equal(const LLColor3& a, const LLColor3& b)
  94. {
  95. return almost_equal((F32)a.mV[0], (F32)b.mV[0]) &&
  96. almost_equal((F32)a.mV[1], (F32)b.mV[1]) &&
  97. almost_equal((F32)a.mV[2], (F32)b.mV[2]);
  98. }
  99. bool almost_equal(const LLVector4& a, const LLVector4& b)
  100. {
  101. return almost_equal((F32)a.mV[0], (F32)b.mV[0]) &&
  102. almost_equal((F32)a.mV[1], (F32)b.mV[1]) &&
  103. almost_equal((F32)a.mV[2], (F32)b.mV[2]) &&
  104. almost_equal((F32)a.mV[3], (F32)b.mV[3]);
  105. }
  106. // Clip quads with top and bottom sides parallel to horizon.
  107. F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1,
  108. F32 cos_max_angle)
  109. {
  110. const LLVector3 V = V1 - V0;
  111. const F32 k2 = 1.f / (cos_max_angle * cos_max_angle) - 1.f;
  112. const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] -
  113. k2 * V.mV[2] * V.mV[2];
  114. const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] -
  115. k2 * V0.mV[2] * V.mV[2];
  116. const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] -
  117. k2 * V0.mV[2] * V0.mV[2];
  118. if (fabsf(A) < 1e-7f)
  119. {
  120. return -0.1f; // v0 is cone origin and v1 is on the surface of the cone
  121. }
  122. const F32 det = sqrtf(B * B - A * C);
  123. const F32 t1 = (-B - det) / A;
  124. const F32 t2 = (-B + det) / A;
  125. const F32 z1 = V0.mV[2] + t1 * V.mV[2];
  126. const F32 z2 = V0.mV[2] + t2 * V.mV[2];
  127. if (z1 * cos_max_angle < 0.f)
  128. {
  129. return t2;
  130. }
  131. else if (z2 * cos_max_angle < 0.f)
  132. {
  133. return t1;
  134. }
  135. else if (t1 < 0.f || t1 > 1.f)
  136. {
  137. return t2;
  138. }
  139. else
  140. {
  141. return t1;
  142. }
  143. }
  144. class LLFastLn
  145. {
  146. public:
  147. LLFastLn()
  148. {
  149. mTable[0] = 0.f;
  150. for (S32 i = 1; i < 257; ++i)
  151. {
  152. mTable[i] = logf((F32)i);
  153. }
  154. }
  155. F32 ln(F32 x)
  156. {
  157. constexpr F32 OO_255 = 0.003921568627450980392156862745098f;
  158. constexpr F32 LN_255 = 5.5412635451584261462455391880218f;
  159. if (x < OO_255)
  160. {
  161. return logf(x);
  162. }
  163. else if (x < 1.f)
  164. {
  165. x *= 255.f;
  166. S32 index = llfloor(x);
  167. F32 t = x - (F32)index;
  168. F32 low = mTable[index];
  169. F32 high = mTable[index + 1];
  170. return low + t * (high - low) - LN_255;
  171. }
  172. else if (x <= 255.f)
  173. {
  174. S32 index = llfloor(x);
  175. F32 t = x - (F32)index;
  176. F32 low = mTable[index];
  177. F32 high = mTable[index + 1];
  178. return low + t * (high - low);
  179. }
  180. else
  181. {
  182. return logf(x);
  183. }
  184. }
  185. F32 pow(F32 x, F32 y)
  186. {
  187. return (F32)LL_FAST_EXP(y * ln(x));
  188. }
  189. private:
  190. F32 mTable[257]; // index 0 is unused
  191. };
  192. static LLFastLn gFastLn;
  193. // Functions used a lot.
  194. LL_INLINE void color_pow(LLColor3& col, F32 e)
  195. {
  196. col.mV[0] = gFastLn.pow(col.mV[0], e);
  197. col.mV[1] = gFastLn.pow(col.mV[1], e);
  198. col.mV[2] = gFastLn.pow(col.mV[2], e);
  199. }
  200. LL_INLINE LLColor3 componentPowF(const LLColor3& v, F32 exponent)
  201. {
  202. return LLColor3(gFastLn.pow(v.mV[0], exponent),
  203. gFastLn.pow(v.mV[1], exponent),
  204. gFastLn.pow(v.mV[2], exponent));
  205. }
  206. LL_INLINE LLColor3 color_norm(const LLColor3& col)
  207. {
  208. const F32 m = color_max(col);
  209. if (m > 1.f)
  210. {
  211. return 1.f / m * col;
  212. }
  213. else return col;
  214. }
  215. LL_INLINE void color_gamma_correct(LLColor3& col)
  216. {
  217. constexpr F32 gamma_inv = 1.f / 1.2f;
  218. if (col.mV[0] != 0.f)
  219. {
  220. col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv);
  221. }
  222. if (col.mV[1] != 0.f)
  223. {
  224. col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv);
  225. }
  226. if (col.mV[2] != 0.f)
  227. {
  228. col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv);
  229. }
  230. }
  231. /***************************************
  232. SkyTex
  233. ***************************************/
  234. S32 LLSkyTex::sComponents = 4;
  235. S32 LLSkyTex::sResolution = 64;
  236. F32 LLSkyTex::sInterpVal = 0.f;
  237. S32 LLSkyTex::sCurrent = 0;
  238. LLSkyTex::LLSkyTex()
  239. : mSkyData(NULL),
  240. mSkyDirs(NULL),
  241. mIsShiny(false)
  242. {
  243. }
  244. void LLSkyTex::init(bool shiny)
  245. {
  246. mIsShiny = shiny;
  247. mSkyData = new LLColor4U[sResolution * sResolution];
  248. mSkyDirs = new LLVector3[sResolution * sResolution];
  249. for (S32 i = 0; i < 2; ++i)
  250. {
  251. mTexture[i] = LLViewerTextureManager::getLocalTexture(false);
  252. mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  253. mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
  254. initEmpty(i);
  255. }
  256. }
  257. void LLSkyTex::cleanupGL()
  258. {
  259. mTexture[0] = NULL;
  260. mTexture[1] = NULL;
  261. }
  262. void LLSkyTex::restoreGL()
  263. {
  264. for (S32 i = 0; i < 2; ++i)
  265. {
  266. mTexture[i] = LLViewerTextureManager::getLocalTexture(false);
  267. mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  268. }
  269. }
  270. LLSkyTex::~LLSkyTex()
  271. {
  272. delete[] mSkyData;
  273. mSkyData = NULL;
  274. delete[] mSkyDirs;
  275. mSkyDirs = NULL;
  276. }
  277. void LLSkyTex::initEmpty(S32 tex)
  278. {
  279. U8* data = mImageRaw[tex]->getData();
  280. if (data)
  281. {
  282. for (S32 i = 0; i < sResolution; ++i)
  283. {
  284. for (S32 j = 0; j < sResolution; ++j)
  285. {
  286. const S32 basic_offset = i * sResolution + j;
  287. S32 offset = basic_offset * sComponents;
  288. data[offset] = 0;
  289. data[++offset] = 0;
  290. data[++offset] = 0;
  291. data[++offset] = 255;
  292. mSkyData[basic_offset].setToBlack();
  293. }
  294. }
  295. }
  296. createGLImage(tex);
  297. }
  298. void LLSkyTex::create()
  299. {
  300. U8* data = mImageRaw[sCurrent]->getData();
  301. if (data)
  302. {
  303. for (S32 i = 0; i < sResolution; ++i)
  304. {
  305. for (S32 j = 0; j < sResolution; ++j)
  306. {
  307. const S32 basic_offset = i * sResolution + j;
  308. S32 offset = basic_offset * sComponents;
  309. U32* pix = (U32*)(data + offset);
  310. *pix = mSkyData[basic_offset].asRGBA();
  311. }
  312. }
  313. }
  314. createGLImage(sCurrent);
  315. }
  316. void LLSkyTex::createGLImage(S32 which)
  317. {
  318. mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
  319. mTexture[which]->createGLTexture(0, mImageRaw[which], 0, true);
  320. mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
  321. }
  322. void LLSkyTex::bindTexture(bool curr)
  323. {
  324. gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]);
  325. }
  326. /***************************************
  327. Sky
  328. ***************************************/
  329. F32 LLHeavenBody::sInterpVal = 0.f;
  330. S32 LLVOSky::sResolution = LLSkyTex::getResolution();
  331. S32 LLVOSky::sTileResX = sResolution / NUM_TILES_X;
  332. S32 LLVOSky::sTileResY = sResolution / NUM_TILES_Y;
  333. LLVOSky::LLVOSky(const LLUUID& id, LLViewerRegion* regionp)
  334. : LLStaticViewerObject(id, LL_VO_SKY, regionp, true),
  335. mSun(SUN_DISK_RADIUS),
  336. mMoon(MOON_DISK_RADIUS),
  337. mBrightnessScale(1.f),
  338. mBrightnessScaleNew(0.f),
  339. mBrightnessScaleGuess(1.f),
  340. mCloudDensity(0.2f),
  341. mWind(0.f),
  342. mWorldScale(1.f),
  343. mSunScale(1.f),
  344. mMoonScale(1.f),
  345. mInterpVal(0.f),
  346. mAtmHeight(ATM_HEIGHT),
  347. mBumpSunDir(0.f, 0.f, 1.f),
  348. mDrawRefl(0),
  349. mDomeRadius(SKY_DOME_RADIUS),
  350. mDomeOffset(SKY_DOME_OFFSET),
  351. mGamma(1.f),
  352. mHazeDensity(0.f),
  353. mDensityMultiplier(0.f),
  354. mCloudShadow(0.f),
  355. mMaxY(0.f),
  356. mHazeHorizon(1.f),
  357. mCubeMapUpdateStage(-1),
  358. mCubeMapUpdateTile(0),
  359. mWeatherChange(false),
  360. mForceUpdate(false),
  361. mNeedUpdate(true),
  362. mHeavenlyBodyUpdated(false),
  363. mInitialized(false)
  364. {
  365. mCanSelect = false;
  366. mUpdateTimer.reset();
  367. mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPIRY);
  368. mForceUpdateThrottle.reset();
  369. for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
  370. {
  371. mSkyTex[i].init(false);
  372. mShinyTex[i].init(true);
  373. }
  374. for (S32 i = 0; i < FACE_COUNT; ++i)
  375. {
  376. mFace[i] = NULL;
  377. }
  378. mCameraPosAgent = gAgent.getCameraPositionAgent();
  379. mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1],
  380. -EARTH_RADIUS);
  381. mSun.setIntensity(SUN_INTENSITY);
  382. mMoon.setIntensity(SUN_INTENSITY *
  383. gSavedSettings.getF32("RenderMoonLightIntensity"));
  384. mAmbientScale = gSavedSettings.getF32("SkyAmbientScale");
  385. mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift");
  386. mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
  387. mFogColor.mV[VALPHA] = 0.f;
  388. if (gSunTextureID != IMG_SUN ||
  389. LLViewerFetchedTexture::sDefaultSunImagep.isNull())
  390. {
  391. mSunTexturep[0] =
  392. LLViewerTextureManager::getFetchedTexture(gSunTextureID,
  393. FTT_DEFAULT, true,
  394. LLGLTexture::BOOST_UI);
  395. mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  396. }
  397. else
  398. {
  399. mSunTexturep[0] = LLViewerFetchedTexture::sDefaultSunImagep;
  400. }
  401. if (gMoonTextureID != IMG_MOON ||
  402. LLViewerFetchedTexture::sDefaultMoonImagep.isNull())
  403. {
  404. mMoonTexturep[0] =
  405. LLViewerTextureManager::getFetchedTexture(gMoonTextureID,
  406. FTT_DEFAULT, true,
  407. LLGLTexture::BOOST_UI);
  408. mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  409. }
  410. else
  411. {
  412. mMoonTexturep[0] = LLViewerFetchedTexture::sDefaultMoonImagep;
  413. }
  414. mBloomTexturep[0] = LLViewerFetchedTexture::sBloomImagep;
  415. mCloudNoiseTexturep[0] = LLViewerFetchedTexture::sDefaultCloudNoiseImagep;
  416. }
  417. LLVOSky::~LLVOSky()
  418. {
  419. // Do not delete images: they will get deleted by gTextureList on shutdown
  420. // This needs to be done for each texture
  421. mCubeMap = NULL;
  422. }
  423. void LLVOSky::init()
  424. {
  425. LLSettingsSky::ptr_t skyp = gEnvironment.getCurrentSky();
  426. bool has_sky = false;
  427. if (skyp) // Paranoia
  428. {
  429. has_sky = true;
  430. skyp->update();
  431. updateDirections(skyp);
  432. initAtmospherics(skyp);
  433. }
  434. // Initialize the cached normalized direction vectors
  435. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  436. {
  437. for (S32 tile = 0; tile < NUM_TILES; ++tile)
  438. {
  439. initSkyTextureDirs(side, tile);
  440. if (has_sky) // Paranoia
  441. {
  442. createSkyTexture(skyp, side, tile);
  443. }
  444. }
  445. mSkyTex[side].create();
  446. mShinyTex[side].create();
  447. }
  448. initCubeMap();
  449. mInitialized = true;
  450. mHeavenlyBodyUpdated = false;
  451. }
  452. void LLVOSky::initCubeMap()
  453. {
  454. std::vector<LLPointer<LLImageRaw> > images;
  455. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  456. {
  457. images.emplace_back(mShinyTex[side].getImageRaw());
  458. }
  459. if (mCubeMap)
  460. {
  461. mCubeMap->init(images);
  462. }
  463. else if (LLPipeline::sRenderWater)
  464. {
  465. mCubeMap = new LLCubeMap();
  466. mCubeMap->init(images);
  467. }
  468. gGL.getTexUnit(0)->disable();
  469. }
  470. void LLVOSky::cleanupGL()
  471. {
  472. for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
  473. {
  474. mSkyTex[i].cleanupGL();
  475. }
  476. if (getCubeMap())
  477. {
  478. getCubeMap()->destroyGL();
  479. }
  480. }
  481. void LLVOSky::restoreGL()
  482. {
  483. for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
  484. {
  485. mSkyTex[i].restoreGL();
  486. }
  487. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  488. if (skyp) // Paranoia
  489. {
  490. setSunTextures(skyp->getSunTextureId(), skyp->getNextSunTextureId());
  491. setMoonTextures(skyp->getMoonTextureId(),
  492. skyp->getNextMoonTextureId());
  493. updateDirections(skyp);
  494. }
  495. if (LLPipeline::sRenderWater)
  496. {
  497. initCubeMap();
  498. }
  499. mForceUpdate = mNeedUpdate = true;
  500. mCubeMapUpdateStage = -1;
  501. mCubeMapUpdateTile = 0;
  502. if (mDrawable)
  503. {
  504. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
  505. }
  506. }
  507. void LLVOSky::initSkyTextureDirs(S32 side, S32 tile)
  508. {
  509. S32 tile_x = tile % NUM_TILES_X;
  510. S32 tile_y = tile / NUM_TILES_X;
  511. S32 tile_x_pos = tile_x * sTileResX;
  512. S32 tile_y_pos = tile_y * sTileResY;
  513. F32 coeff[3] = { 0.f, 0.f, 0.f };
  514. const S32 curr_coef = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
  515. const S32 side_dir = ((side & 1) << 1) - 1; // even = -1, odd = 1
  516. const S32 x_coef = (curr_coef + 1) % 3;
  517. const S32 y_coef = (x_coef + 1) % 3;
  518. coeff[curr_coef] = (F32)side_dir;
  519. F32 inv_res = 1.f / sResolution;
  520. for (S32 y = tile_y_pos; y < tile_y_pos + sTileResY; ++y)
  521. {
  522. for (S32 x = tile_x_pos; x < tile_x_pos + sTileResX; ++x)
  523. {
  524. coeff[x_coef] = F32((x << 1) + 1) * inv_res - 1.f;
  525. coeff[y_coef] = F32((y << 1) + 1) * inv_res - 1.f;
  526. LLVector3 dir(coeff[0], coeff[1], coeff[2]);
  527. dir.normalize();
  528. mSkyTex[side].setDir(dir, x, y);
  529. mShinyTex[side].setDir(dir, x, y);
  530. }
  531. }
  532. }
  533. void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t& skyp, S32 side,
  534. S32 tile)
  535. {
  536. S32 tile_x = tile % NUM_TILES_X;
  537. S32 tile_y = tile / NUM_TILES_X;
  538. S32 tile_x_pos = tile_x * sTileResX;
  539. S32 tile_y_pos = tile_y * sTileResY;
  540. for (S32 y = tile_y_pos; y < tile_y_pos + sTileResY; ++y)
  541. {
  542. for (S32 x = tile_x_pos; x < tile_x_pos + sTileResX; ++x)
  543. {
  544. const LLVector3& sky_dir = mSkyTex[side].getDir(x, y);
  545. mSkyTex[side].setPixel(calcSkyColorInDir(skyp, sky_dir), x, y);
  546. const LLVector3& shiny_dir = mShinyTex[side].getDir(x, y);
  547. mShinyTex[side].setPixel(calcSkyColorInDir(skyp, shiny_dir, true),
  548. x, y);
  549. }
  550. }
  551. }
  552. void LLVOSky::initAtmospherics(const LLSettingsSky::ptr_t& skyp)
  553. {
  554. mGamma = skyp->getGamma();
  555. mBlueDensity = skyp->getBlueDensity();
  556. mBlueHorizon = skyp->getBlueHorizon();
  557. mHazeDensity = skyp->getHazeDensity();
  558. mHazeHorizon = skyp->getHazeHorizon();
  559. mDensityMultiplier = skyp->getDensityMultiplier();
  560. mMaxY = skyp->getMaxY();
  561. mSunNorm = gEnvironment.getClampedSunNorm();
  562. mSunlight = skyp->getIsSunUp() ? skyp->getSunlightColor()
  563. : skyp->getMoonlightColor();
  564. mAmbient = skyp->getAmbientColor();
  565. mGlow = skyp->getGlow();
  566. mCloudShadow = skyp->getCloudShadow();
  567. // Note: the following components are derived from the already fetched
  568. // settings above; the (simple) formulae to compute them have been kept as
  569. // inlined static methods of LLSettingsSky, so that should they get changed
  570. // it will be easy to find them rather than scattering them among the rest
  571. // of the viewer sources). HB
  572. mTotalDensity = LLSettingsSky::totalDensity(mBlueDensity, mHazeDensity);
  573. mLightAttenuation = LLSettingsSky::lightAttenuation(mBlueDensity,
  574. mHazeDensity,
  575. mDensityMultiplier,
  576. mMaxY);
  577. mLightTransmittance = LLSettingsSky::lightTransmittance(mTotalDensity,
  578. mDensityMultiplier,
  579. mMaxY);
  580. LLUUID tex_id = skyp->getRainbowTextureId();
  581. if (mRainbowMap.isNull() || mRainbowMap->getID() != tex_id)
  582. {
  583. mRainbowMap =
  584. LLViewerTextureManager::getFetchedTexture(tex_id, FTT_DEFAULT,
  585. true,
  586. LLGLTexture::BOOST_UI);
  587. }
  588. tex_id = skyp->getHaloTextureId();
  589. if (mHaloMap.isNull() || mHaloMap->getID() != tex_id)
  590. {
  591. mHaloMap =
  592. LLViewerTextureManager::getFetchedTexture(tex_id, FTT_DEFAULT,
  593. true,
  594. LLGLTexture::BOOST_UI);
  595. }
  596. #if LL_VARIABLE_SKY_DOME_SIZE
  597. // NOTE: this is for now a constant equal to SKY_DOME_RADIUS.
  598. mDomeRadius = skyp->getDomeRadius();
  599. // NOTE: this is for now a constant equal to SKY_DOME_OFFSET.
  600. mDomeOffset = skyp->getDomeOffset();
  601. #endif
  602. }
  603. LLColor4 LLVOSky::calcSkyColorInDir(const LLSettingsSky::ptr_t& skyp,
  604. const LLVector3& dir, bool is_shiny)
  605. {
  606. constexpr F32 sky_saturation = 0.25f;
  607. constexpr F32 land_saturation = 0.1f;
  608. if (is_shiny && dir.mV[VZ] < -0.02f)
  609. {
  610. LLColor4 col;
  611. LLColor3 desat_fog(mFogColor);
  612. F32 brightness = desat_fog.brightness();
  613. // So that shiny somewhat shows up at night.
  614. if (brightness < 0.15f)
  615. {
  616. brightness = 0.15f;
  617. desat_fog = smear(0.15f);
  618. }
  619. F32 greyscale_sat = brightness * (1.f - land_saturation);
  620. desat_fog = desat_fog * land_saturation + smear(greyscale_sat);
  621. if (gPipeline.canUseWindLightShaders())
  622. {
  623. col = LLColor4(desat_fog * 0.5f, 0.f);
  624. }
  625. else
  626. {
  627. col = LLColor4(desat_fog, 0.f);
  628. }
  629. F32 x = 1.f - fabsf(-0.1f - dir.mV[VZ]);
  630. x *= x;
  631. col.mV[0] *= x * x;
  632. col.mV[1] *= powf(x, 2.5f);
  633. col.mV[2] *= x * x * x;
  634. return col;
  635. }
  636. // Undo OGL_TO_CFR_ROTATION and negate vertical direction.
  637. LLVector3 pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
  638. // Calculate mHazeColor
  639. calcSkyColorVert(pn);
  640. LLColor3 sky_color;
  641. if (is_shiny)
  642. {
  643. F32 brightness = mHazeColor.brightness();
  644. F32 greyscale_sat = brightness * (1.f - sky_saturation);
  645. sky_color = mHazeColor * sky_saturation + smear(greyscale_sat);
  646. #if 0 // SL-12574 EEP sky is being attenuated too much
  647. sky_color *= 0.5f + 0.5f * brightness;
  648. #endif
  649. }
  650. else if (gPipeline.canUseWindLightShaders())
  651. {
  652. sky_color = LLSettingsSky::gammaCorrect(mHazeColor * 2.f, mGamma);
  653. }
  654. else
  655. {
  656. sky_color = mHazeColor * 2.f;
  657. }
  658. return LLColor4(sky_color, 0.f);
  659. }
  660. void LLVOSky::calcSkyColorVert(LLVector3& pn)
  661. {
  662. // Project the direction ray onto the sky dome.
  663. F32 phi = acosf(pn[1]);
  664. F32 sin_a = sinf(F_PI - phi);
  665. if (fabsf(sin_a) < 0.01f)
  666. {
  667. // Avoid division by zero
  668. sin_a = 0.01f;
  669. }
  670. F32 p_len = mDomeRadius *
  671. sinf(F_PI + phi + asinf(mDomeOffset * sin_a)) / sin_a;
  672. pn *= p_len;
  673. // Set altitude
  674. if (pn[1] > 0.f)
  675. {
  676. pn *= mMaxY / pn[1];
  677. }
  678. else
  679. {
  680. pn *= -32000.f / pn[1];
  681. }
  682. p_len = pn.length();
  683. pn /= p_len;
  684. // Initialize temp variables
  685. LLColor3 sunlight = mSunlight;
  686. // Calculate relative weights
  687. LLColor3 temp1 = mTotalDensity;
  688. LLColor3 blue_factor = mBlueHorizon *
  689. componentDiv(mBlueDensity, temp1);
  690. LLColor3 haze_factor = mHazeHorizon *
  691. componentDiv(smear(mHazeDensity), temp1);
  692. // Compute sunlight from P & lightnorm (for long rays like sky)
  693. LLColor3 temp2;
  694. temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO,
  695. llmax(0.f, pn[1]) + mSunNorm.mV[1]);
  696. temp2.mV[1] = 1.f / temp2.mV[1];
  697. componentMultBy(sunlight, componentExp(mLightAttenuation * -temp2.mV[1]));
  698. componentMultBy(sunlight, mLightTransmittance);
  699. // Distance
  700. temp2.mV[2] = p_len * mDensityMultiplier;
  701. // Transparency (-> temp1)
  702. temp1 = componentExp(temp1 * -temp2.mV[2]);
  703. // Compute haze glow
  704. temp2.mV[0] = pn * LLVector3(mSunNorm);
  705. // temp2.x is 0 at the sun and increases away from sun
  706. temp2.mV[0] = 1.f - temp2.mV[0];
  707. // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
  708. temp2.mV[0] = llmax(temp2.mV[0], 0.001f);
  709. // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
  710. temp2.mV[0] *= mGlow.mV[0];
  711. // glow.z should be negative, so we are doing a sort of (1 / "angle")
  712. // function
  713. temp2.mV[0] = powf(temp2.mV[0], mGlow.mV[2]);
  714. // Add "minimum anti-solar illumination"
  715. temp2.mV[0] += 0.25f;
  716. // Haze color above cloud
  717. mHazeColor = blue_factor * (sunlight + mAmbient) +
  718. componentMult(haze_factor, sunlight * temp2.mV[0] + mAmbient);
  719. #if 0 // 'hazeColorBelowCloud' in LL's EEP viewer (which would be
  720. // mHazeColorBelowCloud for the Cool VL Viewer) is never used...
  721. // Increase ambient when there are more clouds
  722. LLColor3 ambient = mAmbient + (LLColor3::white - mAmbient) *
  723. mCloudShadow * 0.5f;
  724. // Dim sunlight by cloud shadow percentage
  725. sunlight *= 1.f - mCloudShadow;
  726. // Haze color below cloud
  727. mHazeColorBelowCloud = blue_factor * (sunlight + ambient) +
  728. componentMult(mHazeColor,
  729. sunlight * temp2.mV[0] + ambient);
  730. // Final atmosphere additive
  731. componentMultBy(mHazeColor, LLColor3::white - temp1);
  732. // Attenuate cloud color by atmosphere (less atmos opacity/more
  733. // transparency below clouds)
  734. temp1 = componentSqrt(temp1);
  735. // At horizon, blend high altitude sky color towards the darker color below
  736. // the clouds
  737. mHazeColor += componentMult(mHazeColorBelowCloud - mHazeColor,
  738. LLColor3::white - componentSqrt(temp1));
  739. #else
  740. // Final atmosphere additive
  741. componentMultBy(mHazeColor, LLColor3::white - temp1);
  742. #endif
  743. }
  744. void LLVOSky::calcAtmospherics()
  745. {
  746. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  747. if (skyp) // Paranoia
  748. {
  749. initAtmospherics(skyp);
  750. mSun.setColor(skyp->getSunDiffuse());
  751. }
  752. mMoon.setColor(LLColor3::white);
  753. mSun.renewDirection();
  754. mSun.renewColor();
  755. mMoon.renewDirection();
  756. mMoon.renewColor();
  757. }
  758. bool LLVOSky::updateSky()
  759. {
  760. if (mDead || gGLManager.mIsDisabled ||
  761. !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
  762. {
  763. return true;
  764. }
  765. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  766. if (!skyp) // Paranoia
  767. {
  768. return true;
  769. }
  770. static S32 next_frame = 0;
  771. mNeedUpdate = mForceUpdate;
  772. ++next_frame;
  773. next_frame = next_frame % MAX_TILES;
  774. mInterpVal = mInitialized ? (F32)next_frame / (F32)MAX_TILES : 1.f;
  775. LLSkyTex::setInterpVal(mInterpVal);
  776. LLHeavenBody::setInterpVal(mInterpVal);
  777. updateDirections(skyp);
  778. if (!mCubeMap || LLPipeline::sReflectionProbesEnabled)
  779. {
  780. mCubeMapUpdateStage = NUM_CUBEMAP_FACES;
  781. mForceUpdate = false;
  782. return true;
  783. }
  784. if (mCubeMapUpdateStage < 0)
  785. {
  786. LL_TRACY_TIMER(TRC_VOSKY_CALC);
  787. calcAtmospherics();
  788. if (!mNeedUpdate)
  789. {
  790. mNeedUpdate = haveValuesChanged();
  791. }
  792. if (mNeedUpdate && (mForceUpdate || mForceUpdateThrottle.hasExpired()))
  793. {
  794. // Start updating cube map sides
  795. updateFog(gViewerCamera.getFar());
  796. mCubeMapUpdateStage = 0;
  797. mCubeMapUpdateTile = 0;
  798. mForceUpdate = false;
  799. }
  800. }
  801. else if (mCubeMapUpdateStage >= NUM_CUBEMAP_FACES &&
  802. !LLPipeline::sReflectionProbesEnabled)
  803. {
  804. LL_TRACY_TIMER(TRC_VOSKY_UPDATEFORCED);
  805. LLSkyTex::stepCurrent();
  806. bool cannot_use_wl = !gPipeline.canUseWindLightShaders();
  807. S32 tex = mSkyTex[0].getWhich(true);
  808. LLImageRaw* raw1;
  809. LLImageRaw* raw2;
  810. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  811. {
  812. if (cannot_use_wl)
  813. {
  814. raw1 = mSkyTex[side].getImageRaw(true);
  815. raw2 = mSkyTex[side].getImageRaw(false);
  816. raw2->copy(raw1);
  817. mSkyTex[side].createGLImage(tex);
  818. }
  819. raw1 = mShinyTex[side].getImageRaw(true);
  820. raw2 = mShinyTex[side].getImageRaw(false);
  821. raw2->copy(raw1);
  822. mShinyTex[side].createGLImage(tex);
  823. }
  824. next_frame = 0;
  825. // Update the sky texture
  826. if (cannot_use_wl)
  827. {
  828. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  829. {
  830. mSkyTex[side].create();
  831. }
  832. }
  833. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  834. {
  835. mShinyTex[side].create();
  836. }
  837. // Update the environment map
  838. initCubeMap();
  839. saveCurrentValues();
  840. mNeedUpdate = mForceUpdate = false;
  841. mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPIRY);
  842. if (mDrawable.notNull() && mDrawable->getFace(0) &&
  843. !mDrawable->getFace(0)->getVertexBuffer())
  844. {
  845. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
  846. }
  847. mCubeMapUpdateStage = -1;
  848. mCubeMapUpdateTile = 0;
  849. }
  850. // mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES
  851. else if (!LLPipeline::sReflectionProbesEnabled)
  852. {
  853. LL_TRACY_TIMER(TRC_VOSKY_CREATETEXTURES);
  854. S32 side = mCubeMapUpdateStage;
  855. S32 start_tile = mCubeMapUpdateTile;
  856. for (S32 tile = 0; tile < UPDATE_TILES; ++tile)
  857. {
  858. createSkyTexture(skyp, side, start_tile + tile);
  859. }
  860. mCubeMapUpdateTile += UPDATE_TILES;
  861. if (mCubeMapUpdateTile >= NUM_TILES)
  862. {
  863. ++mCubeMapUpdateStage;
  864. mCubeMapUpdateTile = 0;
  865. }
  866. }
  867. return true;
  868. }
  869. bool LLVOSky::haveValuesChanged()
  870. {
  871. if (!almost_equal(mOldCloudShadow, mCloudShadow))
  872. {
  873. return true;
  874. }
  875. if (!almost_equal(mOldHazeDensity, mHazeDensity))
  876. {
  877. return true;
  878. }
  879. if (!almost_equal(mOldHazeHorizon, mHazeHorizon))
  880. {
  881. return true;
  882. }
  883. if (!almost_equal(mOldSunNorm, mSunNorm))
  884. {
  885. return true;
  886. }
  887. if (!almost_equal(mOldSunlight, mSunlight))
  888. {
  889. return true;
  890. }
  891. if (!almost_equal(mOldAmbient, mAmbient))
  892. {
  893. return true;
  894. }
  895. if (!almost_equal(mOldBlueDensity, mBlueDensity))
  896. {
  897. return true;
  898. }
  899. if (!almost_equal(mOldBlueHorizon, mBlueHorizon))
  900. {
  901. return true;
  902. }
  903. if (!almost_equal(mOldDensityMultiplier, mDensityMultiplier))
  904. {
  905. return true;
  906. }
  907. if (!almost_equal(mOldGlow, mGlow))
  908. {
  909. return true;
  910. }
  911. if (!almost_equal(mOldMaxY, mMaxY))
  912. {
  913. return true;
  914. }
  915. if (!almost_equal(mOldGamma, mGamma))
  916. {
  917. return true;
  918. }
  919. #if 0 // These components are derived from the above ones, so need to save
  920. // and test them... HB
  921. if (!almost_equal(mOldLightAttenuation, mLightAttenuation))
  922. {
  923. return true;
  924. }
  925. if (!almost_equal(mOldLightTransmittance, mLightTransmittance))
  926. {
  927. return true;
  928. }
  929. if (!almost_equal(mOldTotalDensity, mTotalDensity))
  930. {
  931. return true;
  932. }
  933. #endif
  934. return false;
  935. }
  936. void LLVOSky::saveCurrentValues()
  937. {
  938. mOldGamma = mGamma;
  939. mOldHazeDensity = mHazeDensity;
  940. mOldHazeHorizon = mHazeHorizon;
  941. mOldDensityMultiplier = mDensityMultiplier;
  942. mOldMaxY = mMaxY;
  943. mOldCloudShadow = mCloudShadow;
  944. mOldSunNorm = mSunNorm;
  945. mOldGlow = mGlow;
  946. mOldSunlight = mSunlight;
  947. mOldAmbient = mAmbient;
  948. mOldBlueDensity = mBlueDensity;
  949. mOldBlueHorizon = mBlueHorizon;
  950. #if 0 // These components are derived from the above ones, so need to save
  951. // and test them... HB
  952. mOldLightAttenuation = mLightAttenuation;
  953. mOldLightTransmittance = mLightTransmittance;
  954. mOldTotalDensity = mTotalDensity;
  955. #endif
  956. }
  957. void LLVOSky::updateTextures()
  958. {
  959. F32 max_area = gMaxImageSizeDefault * gMaxImageSizeDefault;
  960. if (mSunTexturep[0])
  961. {
  962. mSunTexturep[0]->addTextureStats(max_area);
  963. }
  964. if (mMoonTexturep[0])
  965. {
  966. mMoonTexturep[0]->addTextureStats(max_area);
  967. }
  968. if (mBloomTexturep[0])
  969. {
  970. mBloomTexturep[0]->addTextureStats(max_area);
  971. }
  972. if (mCloudNoiseTexturep[0])
  973. {
  974. mCloudNoiseTexturep[0]->addTextureStats(max_area);
  975. }
  976. if (mSunTexturep[1])
  977. {
  978. mSunTexturep[1]->addTextureStats(max_area);
  979. }
  980. if (mMoonTexturep[1])
  981. {
  982. mMoonTexturep[1]->addTextureStats(max_area);
  983. }
  984. if (mBloomTexturep[1])
  985. {
  986. mBloomTexturep[1]->addTextureStats(max_area);
  987. }
  988. if (mCloudNoiseTexturep[1])
  989. {
  990. mCloudNoiseTexturep[1]->addTextureStats(max_area);
  991. }
  992. }
  993. LLDrawable* LLVOSky::createDrawable()
  994. {
  995. gPipeline.allocDrawable(this);
  996. mDrawable->setLit(false);
  997. LLDrawPoolSky* poolp =
  998. (LLDrawPoolSky*)gPipeline.getPool(LLDrawPool::POOL_SKY);
  999. poolp->setSkyTex(mSkyTex);
  1000. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_SKY);
  1001. for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
  1002. {
  1003. mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
  1004. }
  1005. mFace[FACE_SUN] = mDrawable->addFace(poolp, NULL);
  1006. mFace[FACE_MOON] = mDrawable->addFace(poolp, NULL);
  1007. mFace[FACE_BLOOM] = mDrawable->addFace(poolp, NULL);
  1008. mFace[FACE_SUN]->setMediaAllowed(false);
  1009. mFace[FACE_MOON]->setMediaAllowed(false);
  1010. mFace[FACE_BLOOM]->setMediaAllowed(false);
  1011. return mDrawable;
  1012. }
  1013. bool LLVOSky::updateGeometry(LLDrawable* drawable)
  1014. {
  1015. LL_FAST_TIMER(FTM_GEO_SKY);
  1016. if (mFace[FACE_REFLECTION] == NULL)
  1017. {
  1018. LLDrawPoolWater* poolp =
  1019. (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
  1020. if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel())
  1021. {
  1022. mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);
  1023. }
  1024. }
  1025. mCameraPosAgent = drawable->getPositionAgent();
  1026. mEarthCenter.mV[0] = mCameraPosAgent.mV[0];
  1027. mEarthCenter.mV[1] = mCameraPosAgent.mV[1];
  1028. LLVector3 v_agent[8];
  1029. for (S32 i = 0; i < 8; ++i)
  1030. {
  1031. F32 x_sgn = (i & 1) ? 1.f : -1.f;
  1032. F32 y_sgn = (i & 2) ? 1.f : -1.f;
  1033. F32 z_sgn = (i & 4) ? 1.f : -1.f;
  1034. v_agent[i] = HORIZON_DIST * SKY_BOX_MULT *
  1035. LLVector3(x_sgn, y_sgn, z_sgn);
  1036. }
  1037. LLStrider<LLVector3> verticesp;
  1038. LLStrider<LLVector3> normalsp;
  1039. LLStrider<LLVector2> texcoordsp;
  1040. LLStrider<U16> indicesp;
  1041. for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
  1042. {
  1043. LLFace* face = mFace[FACE_SIDE0 + side];
  1044. if (!face || face->getVertexBuffer())
  1045. {
  1046. continue;
  1047. }
  1048. face->setSize(4, 6);
  1049. face->setGeomIndex(0);
  1050. face->setIndicesIndex(0);
  1051. LLVertexBuffer* buff =
  1052. new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
  1053. buff->allocateBuffer(4, 6);
  1054. face->setVertexBuffer(buff);
  1055. U16 index_offset = face->getGeometry(verticesp, normalsp, texcoordsp,
  1056. indicesp);
  1057. S32 vtx = 0;
  1058. S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
  1059. S32 side_dir = side & 1; // even - 0, odd - 1
  1060. S32 i_bit = (curr_bit + 2) % 3;
  1061. S32 j_bit = (i_bit + 2) % 3;
  1062. LLVector3 axis;
  1063. axis.mV[curr_bit] = 1.f;
  1064. face->mCenterAgent = (F32)((side_dir << 1) - 1) * axis * HORIZON_DIST;
  1065. vtx = side_dir << curr_bit;
  1066. *verticesp++ = v_agent[vtx];
  1067. *verticesp++ = v_agent[vtx | 1 << j_bit];
  1068. *verticesp++ = v_agent[vtx | 1 << i_bit];
  1069. *verticesp++ = v_agent[vtx | 1 << i_bit | 1 << j_bit];
  1070. *texcoordsp++ = TEX00;
  1071. *texcoordsp++ = TEX01;
  1072. *texcoordsp++ = TEX10;
  1073. *texcoordsp++ = TEX11;
  1074. // Triangles for each side
  1075. *indicesp++ = index_offset;
  1076. *indicesp++ = index_offset + 1;
  1077. *indicesp++ = index_offset + 3;
  1078. *indicesp++ = index_offset;
  1079. *indicesp++ = index_offset + 3;
  1080. *indicesp++ = index_offset + 2;
  1081. buff->unmapBuffer();
  1082. }
  1083. const LLVector3& look_at = gViewerCamera.getAtAxis();
  1084. LLVector3 right = look_at % LLVector3::z_axis;
  1085. LLVector3 up = right % look_at;
  1086. right.normalize();
  1087. up.normalize();
  1088. constexpr F32 cos_max_angle = 1.f;
  1089. bool draw_sun = updateHeavenlyBodyGeometry(drawable, true, mSun,
  1090. cos_max_angle, up, right);
  1091. bool draw_moon = updateHeavenlyBodyGeometry(drawable, false, mMoon,
  1092. cos_max_angle, up, right);
  1093. draw_sun &= gEnvironment.getIsSunUp();
  1094. draw_moon &= gEnvironment.getIsMoonUp();
  1095. mSun.setDraw(draw_sun);
  1096. mMoon.setDraw(draw_moon);
  1097. F32 water_height = 0.01f;
  1098. LLViewerRegion* regionp = gAgent.getRegion();
  1099. if (regionp)
  1100. {
  1101. water_height += regionp->getWaterHeight();
  1102. }
  1103. F32 camera_height = mCameraPosAgent.mV[2];
  1104. F32 height_above_water = camera_height - water_height;
  1105. bool sun_flag = !mMoon.isVisible() || look_at * mSun.getDirection() > 0.f;
  1106. if (height_above_water > 0)
  1107. {
  1108. bool render_ref =
  1109. gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() == 0;
  1110. if (sun_flag)
  1111. {
  1112. setDrawRefl(0);
  1113. if (render_ref)
  1114. {
  1115. updateReflectionGeometry(drawable, height_above_water, mSun);
  1116. }
  1117. }
  1118. else
  1119. {
  1120. setDrawRefl(1);
  1121. if (render_ref)
  1122. {
  1123. updateReflectionGeometry(drawable, height_above_water, mMoon);
  1124. }
  1125. }
  1126. }
  1127. else
  1128. {
  1129. setDrawRefl(-1);
  1130. }
  1131. return true;
  1132. }
  1133. bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable* drawable, bool is_sun,
  1134. LLHeavenBody& hb, F32 cos_max_angle,
  1135. const LLVector3& up,
  1136. const LLVector3& right)
  1137. {
  1138. mHeavenlyBodyUpdated = true;
  1139. LLVector3 to_dir, hb_right, hb_up;
  1140. LLQuaternion rot = hb.getRotation();
  1141. to_dir = LLVector3::x_axis * rot;
  1142. hb_right = to_dir % LLVector3::z_axis;
  1143. hb_up = hb_right % to_dir;
  1144. // At zenith so math below fails spectacularly
  1145. if (to_dir * LLVector3::z_axis > 0.99f)
  1146. {
  1147. hb_right = LLVector3::y_axis_neg * rot;
  1148. hb_up = LLVector3::z_axis * rot;
  1149. }
  1150. hb_right.normalize();
  1151. hb_up.normalize();
  1152. LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
  1153. const F32 enlargm_factor = 1.f - to_dir.mV[2];
  1154. F32 horiz_enlargement = 1.f + enlargm_factor * 0.3f;
  1155. F32 vert_enlargement = 1.f + enlargm_factor * 0.2f;
  1156. LLVector3 v_clipped[4];
  1157. F32 scale = is_sun ? mSunScale : mMoonScale;
  1158. scale *= HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
  1159. const LLVector3 scaled_right = horiz_enlargement * scale *
  1160. hb.getDiskRadius() * hb_right;
  1161. const LLVector3 scaled_up = vert_enlargement * scale *
  1162. hb.getDiskRadius() * hb_up;
  1163. v_clipped[0] = draw_pos - scaled_right + scaled_up;
  1164. v_clipped[1] = draw_pos - scaled_right - scaled_up;
  1165. v_clipped[2] = draw_pos + scaled_right + scaled_up;
  1166. v_clipped[3] = draw_pos + scaled_right - scaled_up;
  1167. hb.setVisible(true);
  1168. const S32 f = is_sun ? FACE_SUN : FACE_MOON;
  1169. LLFace* facep = mFace[f];
  1170. if (!facep) return false;
  1171. if (!facep->getVertexBuffer())
  1172. {
  1173. facep->setSize(4, 6);
  1174. LLVertexBuffer* buff =
  1175. new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
  1176. if (!buff->allocateBuffer(facep->getGeomCount(),
  1177. facep->getIndicesCount()))
  1178. {
  1179. llwarns << "Failure to allocate a vertex buffer with "
  1180. << facep->getGeomCount() << " vertices and "
  1181. << facep->getIndicesCount() << " indices" << llendl;
  1182. return true;
  1183. }
  1184. facep->setGeomIndex(0);
  1185. facep->setIndicesIndex(0);
  1186. facep->setVertexBuffer(buff);
  1187. }
  1188. LLStrider<LLVector3> verticesp;
  1189. LLStrider<LLVector3> normalsp;
  1190. LLStrider<LLVector2> texcoordsp;
  1191. LLStrider<U16> indicesp;
  1192. S32 index_offset = facep->getGeometry(verticesp, normalsp, texcoordsp,
  1193. indicesp);
  1194. if (index_offset == -1)
  1195. {
  1196. return true;
  1197. }
  1198. for (S32 vtx = 0; vtx < 4; ++vtx)
  1199. {
  1200. hb.corner(vtx) = v_clipped[vtx];
  1201. *(verticesp++) = hb.corner(vtx) + mCameraPosAgent;
  1202. }
  1203. *texcoordsp++ = TEX01;
  1204. *texcoordsp++ = TEX00;
  1205. *texcoordsp++ = TEX11;
  1206. *texcoordsp++ = TEX10;
  1207. *indicesp++ = index_offset;
  1208. *indicesp++ = index_offset + 2;
  1209. *indicesp++ = index_offset + 1;
  1210. *indicesp++ = index_offset + 1;
  1211. *indicesp++ = index_offset + 2;
  1212. *indicesp++ = index_offset + 3;
  1213. facep->getVertexBuffer()->unmapBuffer();
  1214. return true;
  1215. }
  1216. F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top,
  1217. F32 sin_dir_from_top, F32 diff_angl_dir)
  1218. {
  1219. LLVector3 P = p;
  1220. P.normalize();
  1221. const F32 cos_dir_angle = -P.mV[VZ];
  1222. const F32 sin_dir_angle = sqrtf(1.f - cos_dir_angle * cos_dir_angle);
  1223. F32 cos_diff_angles = cos_dir_angle * cos_dir_from_top +
  1224. sin_dir_angle * sin_dir_from_top;
  1225. F32 diff_angles;
  1226. if (cos_diff_angles > 1.f - 1e-7f)
  1227. {
  1228. diff_angles = 0.f;
  1229. }
  1230. else
  1231. {
  1232. diff_angles = acosf(cos_diff_angles);
  1233. }
  1234. const F32 rel_diff_angles = diff_angles / diff_angl_dir;
  1235. const F32 dt = 1.f - rel_diff_angles;
  1236. return dt >= 0.f ? dt : 0.f;
  1237. }
  1238. F32 dtClip(const LLVector3& v0, const LLVector3& v1, F32 far_clip2)
  1239. {
  1240. const LLVector3 otrezok = v1 - v0;
  1241. const F32 A = otrezok.lengthSquared();
  1242. const F32 B = v0 * otrezok;
  1243. const F32 C = v0.lengthSquared() - far_clip2;
  1244. const F32 det = sqrtf(B * B - A * C);
  1245. F32 dt_clip = (-B - det) / A;
  1246. if (dt_clip < 0.f || dt_clip > 1.f)
  1247. {
  1248. dt_clip = (-B + det) / A;
  1249. }
  1250. return dt_clip;
  1251. }
  1252. void LLVOSky::updateReflectionGeometry(LLDrawable* drawable, F32 h,
  1253. const LLHeavenBody& hb)
  1254. {
  1255. const LLVector3& look_at = gViewerCamera.getAtAxis();
  1256. LLVector3 to_dir = hb.getDirection();
  1257. LLVector3 hb_pos = to_dir * (HORIZON_DIST - 10.f);
  1258. LLVector3 to_dir_proj = to_dir;
  1259. to_dir_proj.mV[VZ] = 0.f;
  1260. to_dir_proj.normalize();
  1261. LLVector3 right = to_dir % LLVector3::z_axis;
  1262. LLVector3 up = right % to_dir;
  1263. right.normalize();
  1264. up.normalize();
  1265. // Finding angle between look direction and sprite.
  1266. LLVector3 look_at_right = look_at % LLVector3::z_axis;
  1267. look_at_right.normalize();
  1268. const F32 enlargm_factor = 1.f - to_dir.mV[2];
  1269. F32 horiz_enlargement = 1.f + enlargm_factor * 0.3f;
  1270. F32 vert_enlargement = 1.f + enlargm_factor * 0.2f;
  1271. F32 vert_size =
  1272. vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius();
  1273. right *= horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius();
  1274. up *= vert_size;
  1275. LLVector3 v_corner[2];
  1276. LLVector3 stretch_corner[2];
  1277. LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - right + up;
  1278. v_corner[1] = stretch_corner[1] = hb_pos - right - up;
  1279. LLVector2 TEX0t = TEX00;
  1280. LLVector2 TEX1t = TEX10;
  1281. LLVector3 lower_corner = v_corner[1];
  1282. top_hb.normalize();
  1283. const F32 cos_angle_of_view = fabsf(top_hb.mV[VZ]);
  1284. const F32 extension = llmin(5.f, 1.f / cos_angle_of_view);
  1285. constexpr S32 cols = 1;
  1286. const S32 raws = lltrunc(16 * extension);
  1287. S32 quads = cols * raws;
  1288. stretch_corner[0] = lower_corner + extension *
  1289. (stretch_corner[0] - lower_corner);
  1290. stretch_corner[1] = lower_corner + extension *
  1291. (stretch_corner[1] - lower_corner);
  1292. F32 cos_dir_from_top[2];
  1293. LLVector3 dir = stretch_corner[0];
  1294. dir.normalize();
  1295. cos_dir_from_top[0] = dir.mV[VZ];
  1296. dir = stretch_corner[1];
  1297. dir.normalize();
  1298. cos_dir_from_top[1] = dir.mV[VZ];
  1299. const F32 sin_dir_from_top = sqrtf(1.f - cos_dir_from_top[0] *
  1300. cos_dir_from_top[0]);
  1301. const F32 sin_dir_from_top2 = sqrtf(1.f - cos_dir_from_top[1] *
  1302. cos_dir_from_top[1]);
  1303. const F32 cos_diff_dir = cos_dir_from_top[0] * cos_dir_from_top[1] +
  1304. sin_dir_from_top * sin_dir_from_top2;
  1305. const F32 diff_angl_dir = acosf(cos_diff_dir);
  1306. v_corner[0] = stretch_corner[0];
  1307. v_corner[1] = lower_corner;
  1308. LLVector2 TEX0tt = TEX01;
  1309. LLVector2 TEX1tt = TEX11;
  1310. LLVector3 v_refl_corner[4];
  1311. LLVector3 v_sprite_corner[4];
  1312. for (S32 vtx = 0; vtx < 2; ++vtx)
  1313. {
  1314. LLVector3 light_proj = v_corner[vtx];
  1315. light_proj.normalize();
  1316. const F32 z = light_proj.mV[VZ];
  1317. const F32 sin_angle = sqrtf(1.f - z * z);
  1318. light_proj *= 1.f / sin_angle;
  1319. light_proj.mV[VZ] = 0.f;
  1320. const F32 to_refl_point = h * sin_angle / fabsf(z);
  1321. v_refl_corner[vtx] = to_refl_point * light_proj;
  1322. }
  1323. for (S32 vtx = 2; vtx < 4; ++vtx)
  1324. {
  1325. const LLVector3 to_dir_vec = (to_dir_proj * v_refl_corner[vtx - 2]) *
  1326. to_dir_proj;
  1327. v_refl_corner[vtx] = v_refl_corner[vtx - 2] +
  1328. 2.f * (to_dir_vec - v_refl_corner[vtx - 2]);
  1329. }
  1330. for (S32 vtx = 0; vtx < 4; ++vtx)
  1331. {
  1332. v_refl_corner[vtx].mV[VZ] -= h;
  1333. }
  1334. LLVector3 refl_corn_norm[2];
  1335. refl_corn_norm[0] = v_refl_corner[1];
  1336. refl_corn_norm[0].normalize();
  1337. refl_corn_norm[1] = v_refl_corner[3];
  1338. refl_corn_norm[1].normalize();
  1339. F32 cos_refl_look_at[2];
  1340. cos_refl_look_at[0] = refl_corn_norm[0] * look_at;
  1341. cos_refl_look_at[1] = refl_corn_norm[1] * look_at;
  1342. S32 side = 0;
  1343. if (cos_refl_look_at[1] > cos_refl_look_at[0])
  1344. {
  1345. side = 2;
  1346. }
  1347. #if 0
  1348. const F32 far_clip = (gViewerCamera.getFar() - 0.01f) / far_clip_factor;
  1349. const F32 far_clip2 = far_clip * far_clip;
  1350. #else
  1351. constexpr F32 far_clip = 512;
  1352. constexpr F32 far_clip2 = far_clip * far_clip;
  1353. #endif
  1354. F32 dt_clip;
  1355. if (v_refl_corner[side].lengthSquared() > far_clip2)
  1356. {
  1357. // Whole thing is sprite: reflection is beyond far clip plane.
  1358. dt_clip = 1.1f;
  1359. quads = 1;
  1360. }
  1361. else if (v_refl_corner[side + 1].lengthSquared() > far_clip2)
  1362. {
  1363. // Part is reflection, the rest is sprite.
  1364. dt_clip = dtClip(v_refl_corner[side + 1], v_refl_corner[side],
  1365. far_clip2);
  1366. const LLVector3 p = (1.f - dt_clip) * v_refl_corner[side + 1] +
  1367. dt_clip * v_refl_corner[side];
  1368. F32 dt_tex = dtReflection(p, cos_dir_from_top[0], sin_dir_from_top,
  1369. diff_angl_dir);
  1370. TEX0tt = LLVector2(0.f, dt_tex);
  1371. TEX1tt = LLVector2(1.f, dt_tex);
  1372. ++quads;
  1373. }
  1374. else
  1375. {
  1376. // Whole thing is correct reflection.
  1377. dt_clip = -0.1f;
  1378. }
  1379. LLFace* face = mFace[FACE_REFLECTION];
  1380. if (!face) return;
  1381. if (!face->getVertexBuffer() || face->getGeomCount() != quads * 4)
  1382. {
  1383. face->setSize(quads * 4, quads * 6);
  1384. LLVertexBuffer* buff =
  1385. new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK);
  1386. if (!buff->allocateBuffer(face->getGeomCount(),
  1387. face->getIndicesCount()))
  1388. {
  1389. llwarns << "Failure to allocate a vertex buffer with "
  1390. << face->getGeomCount() << " vertices and "
  1391. << face->getIndicesCount() << " indices" << llendl;
  1392. return;
  1393. }
  1394. face->setIndicesIndex(0);
  1395. face->setGeomIndex(0);
  1396. face->setVertexBuffer(buff);
  1397. }
  1398. LLStrider<LLVector3> verticesp;
  1399. LLStrider<LLVector3> normalsp;
  1400. LLStrider<LLVector2> texcoordsp;
  1401. LLStrider<U16> indicesp;
  1402. S32 index_offset = face->getGeometry(verticesp, normalsp, texcoordsp,
  1403. indicesp);
  1404. if (index_offset == -1)
  1405. {
  1406. return;
  1407. }
  1408. LLColor3 hb_col3 = hb.getInterpColor();
  1409. hb_col3.clamp();
  1410. const LLColor4 hb_col = LLColor4(hb_col3);
  1411. constexpr F32 min_attenuation = 0.4f;
  1412. constexpr F32 max_attenuation = 0.7f;
  1413. const F32 attenuation = min_attenuation +
  1414. cos_angle_of_view *
  1415. (max_attenuation - min_attenuation);
  1416. LLColor4 hb_refl_col = (1.f - attenuation) * hb_col + attenuation *
  1417. mFogColor;
  1418. face->setFaceColor(hb_refl_col);
  1419. LLVector3 v_far[2];
  1420. v_far[0] = v_refl_corner[1];
  1421. v_far[1] = v_refl_corner[3];
  1422. if (dt_clip > 0.f)
  1423. {
  1424. if (dt_clip >= 1.f)
  1425. {
  1426. for (S32 vtx = 0; vtx < 4; ++vtx)
  1427. {
  1428. F32 ratio = far_clip / v_refl_corner[vtx].length();
  1429. *verticesp++ = v_refl_corner[vtx] = ratio *
  1430. v_refl_corner[vtx] +
  1431. mCameraPosAgent;
  1432. }
  1433. const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
  1434. v_refl_corner[1] +
  1435. v_refl_corner[2] +
  1436. v_refl_corner[3]);
  1437. face->mCenterAgent = draw_pos;
  1438. }
  1439. else
  1440. {
  1441. F32 ratio = far_clip / v_refl_corner[1].length();
  1442. v_sprite_corner[1] = v_refl_corner[1] * ratio;
  1443. ratio = far_clip / v_refl_corner[3].length();
  1444. v_sprite_corner[3] = v_refl_corner[3] * ratio;
  1445. v_refl_corner[1] = (1.f - dt_clip) * v_refl_corner[1] +
  1446. dt_clip * v_refl_corner[0];
  1447. v_refl_corner[3] = (1.f - dt_clip) * v_refl_corner[3] +
  1448. dt_clip * v_refl_corner[2];
  1449. v_sprite_corner[0] = v_refl_corner[1];
  1450. v_sprite_corner[2] = v_refl_corner[3];
  1451. for (S32 vtx = 0; vtx < 4; ++vtx)
  1452. {
  1453. *verticesp++ = v_sprite_corner[vtx] + mCameraPosAgent;
  1454. }
  1455. const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
  1456. v_sprite_corner[1] +
  1457. v_refl_corner[2] +
  1458. v_sprite_corner[3]);
  1459. face->mCenterAgent = draw_pos;
  1460. }
  1461. *texcoordsp++ = TEX0tt;
  1462. *texcoordsp++ = TEX0t;
  1463. *texcoordsp++ = TEX1tt;
  1464. *texcoordsp++ = TEX1t;
  1465. *indicesp++ = index_offset;
  1466. *indicesp++ = index_offset + 2;
  1467. *indicesp++ = index_offset + 1;
  1468. *indicesp++ = index_offset + 1;
  1469. *indicesp++ = index_offset + 2;
  1470. *indicesp++ = index_offset + 3;
  1471. index_offset += 4;
  1472. }
  1473. if (dt_clip < 1.f)
  1474. {
  1475. if (dt_clip <= 0.f)
  1476. {
  1477. const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
  1478. v_refl_corner[1] +
  1479. v_refl_corner[2] +
  1480. v_refl_corner[3]);
  1481. face->mCenterAgent = draw_pos;
  1482. }
  1483. const F32 raws_inv = 1.f / raws;
  1484. const F32 cols_inv = 1.f / cols;
  1485. LLVector3 left = v_refl_corner[0] - v_refl_corner[1];
  1486. LLVector3 right = v_refl_corner[2] - v_refl_corner[3];
  1487. left *= raws_inv;
  1488. right *= raws_inv;
  1489. F32 dt_v0, dt_v1;
  1490. for (S32 raw = 0; raw < raws; ++raw)
  1491. {
  1492. const LLVector3 bl = v_refl_corner[1] + (F32)raw * left;
  1493. const LLVector3 br = v_refl_corner[3] + (F32)raw * right;
  1494. const LLVector3 el = bl + left;
  1495. const LLVector3 er = br + right;
  1496. dt_v1 = dtReflection(el, cos_dir_from_top[0], sin_dir_from_top,
  1497. diff_angl_dir);
  1498. dt_v0 = dt_v1;
  1499. for (S32 col = 0; col < cols; ++col)
  1500. {
  1501. F32 dt_h0 = col * cols_inv;
  1502. *verticesp++ = (1.f - dt_h0) * el + dt_h0 * er +
  1503. mCameraPosAgent;
  1504. *verticesp++ = (1.f - dt_h0) * bl + dt_h0 * br +
  1505. mCameraPosAgent;
  1506. F32 dt_h1 = (col + 1) * cols_inv;
  1507. *verticesp++ = (1.f - dt_h1) * el + dt_h1 * er +
  1508. mCameraPosAgent;
  1509. *verticesp++ = (1.f - dt_h1) * bl + dt_h1 * br +
  1510. mCameraPosAgent;
  1511. *texcoordsp++ = LLVector2(dt_h0, dt_v1);
  1512. *texcoordsp++ = LLVector2(dt_h0, dt_v0);
  1513. *texcoordsp++ = LLVector2(dt_h1, dt_v1);
  1514. *texcoordsp++ = LLVector2(dt_h1, dt_v0);
  1515. *indicesp++ = index_offset;
  1516. *indicesp++ = index_offset + 2;
  1517. *indicesp++ = index_offset + 1;
  1518. *indicesp++ = index_offset + 1;
  1519. *indicesp++ = index_offset + 2;
  1520. *indicesp++ = index_offset + 3;
  1521. index_offset += 4;
  1522. }
  1523. }
  1524. }
  1525. face->getVertexBuffer()->unmapBuffer();
  1526. }
  1527. void LLVOSky::updateFog(F32 distance)
  1528. {
  1529. if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
  1530. {
  1531. return;
  1532. }
  1533. F32 water_height = 0.01f;
  1534. LLViewerRegion* regionp = gAgent.getRegion();
  1535. if (regionp)
  1536. {
  1537. water_height += regionp->getWaterHeight();
  1538. }
  1539. F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
  1540. F32 near_clip_height = gViewerCamera.getAtAxis().mV[VZ] *
  1541. gViewerCamera.getNear();
  1542. camera_height += near_clip_height;
  1543. LLColor3 res_color[3];
  1544. LLColor3 sky_fog_color = LLColor3::white;
  1545. LLColor3 render_fog_color = LLColor3::white;
  1546. LLVector3 tosun;
  1547. tosun.set(gEnvironment.getClampedLightNorm());
  1548. const F32 tosun_z = tosun.mV[VZ];
  1549. tosun.mV[VZ] = 0.f;
  1550. tosun.normalize();
  1551. LLVector3 perp_tosun;
  1552. perp_tosun.mV[VX] = -tosun.mV[VY];
  1553. perp_tosun.mV[VY] = tosun.mV[VX];
  1554. LLVector3 tosun_45 = tosun + perp_tosun;
  1555. tosun_45.normalize();
  1556. constexpr F32 delta = 0.06f;
  1557. tosun.mV[VZ] = perp_tosun.mV[VZ] = tosun_45.mV[VZ] = delta;
  1558. tosun.normalize();
  1559. perp_tosun.normalize();
  1560. tosun_45.normalize();
  1561. // Sky colors, just slightly above the horizon in the direction of the sun,
  1562. // perpendicular to the sun, and at a 45 degree angle to the sun.
  1563. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  1564. initAtmospherics(skyp);
  1565. res_color[0] = calcSkyColorInDir(skyp, tosun);
  1566. res_color[1] = calcSkyColorInDir(skyp, perp_tosun);
  1567. res_color[2] = calcSkyColorInDir(skyp, tosun_45);
  1568. sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
  1569. constexpr F32 full_off = -0.25f;
  1570. constexpr F32 full_on = 0.f;
  1571. F32 on = llclamp((tosun_z - full_off) / (full_on - full_off), 0.01f, 1.f);
  1572. sky_fog_color *= 0.5f * on;
  1573. // We need to clamp these to non-zero, in order for the gamma correction to
  1574. // work. 0^y = ???
  1575. for (S32 i = 0; i < 3; ++i)
  1576. {
  1577. sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]);
  1578. }
  1579. color_gamma_correct(sky_fog_color);
  1580. render_fog_color = sky_fog_color;
  1581. if (camera_height > water_height)
  1582. {
  1583. LLColor4 fog(render_fog_color);
  1584. mGLFogCol = fog;
  1585. }
  1586. else
  1587. {
  1588. F32 depth = water_height - camera_height;
  1589. // Adjust the color based on depth. We are doing linear approximations.
  1590. static LLCachedControl<F32> gldepthscale(gSavedSettings,
  1591. "WaterGLFogDepthScale");
  1592. F32 depth_scale = gldepthscale > 0.f ? gldepthscale : 1.f;
  1593. static LLCachedControl<F32> gldepthfloor(gSavedSettings,
  1594. "WaterGLFogDepthFloor");
  1595. F32 depth_floor = gldepthfloor > 0.f ? gldepthfloor : 0.f;
  1596. F32 depth_modifier = 1.f - llmin(llmax(depth / depth_scale, 0.01f),
  1597. depth_floor);
  1598. LLColor4 fog_col = LLDrawPoolWater::sWaterFogColor * depth_modifier;
  1599. fog_col.setAlpha(1.f);
  1600. // Set the gl fog color
  1601. mGLFogCol = fog_col;
  1602. }
  1603. mFogColor = sky_fog_color;
  1604. mFogColor.setAlpha(1.f);
  1605. stop_glerror();
  1606. }
  1607. void LLVOSky::initSunDirection(const LLVector3& sun_dir)
  1608. {
  1609. LLVector3 sun_direction = sun_dir.length() != 0.f ? sun_dir
  1610. : LLVector3::x_axis;
  1611. sun_direction.normalize();
  1612. mSun.setDirection(sun_direction);
  1613. mSun.renewDirection();
  1614. mSun.setAngularVelocity(LLVector3::zero);
  1615. mMoon.setDirection(-mSun.getDirection());
  1616. mMoon.renewDirection();
  1617. mLastLightingDirection = mSun.getDirection();
  1618. if (!mInitialized)
  1619. {
  1620. init();
  1621. LLSkyTex::stepCurrent();
  1622. }
  1623. }
  1624. void LLVOSky::setSunDirection(const LLVector3& sun_dir,
  1625. const LLVector3& sun_ang_velocity)
  1626. {
  1627. LLVector3 sun_direction = sun_dir.length() != 0.f ? sun_dir
  1628. : LLVector3::x_axis;
  1629. sun_direction.normalize();
  1630. // Push the sun "South" as it approaches directly overhead so that we can
  1631. // always see bump mapping on the upward facing faces of cubes.
  1632. LLVector3 new_dir = sun_direction;
  1633. // Same as dot product with the up direction + clamp.
  1634. F32 sun_dot = llmax(0.f, new_dir.mV[2]);
  1635. sun_dot *= sun_dot;
  1636. // Create normalized vector that has the sun_dir pushed south about an hour
  1637. // and change.
  1638. LLVector3 adjusted_dir = (new_dir + LLVector3(0.f, -0.70711f, 0.70711f)) *
  1639. 0.5f;
  1640. // Blend between normal sun dir and adjusted sun dir based on how close we
  1641. // are to having the sun overhead.
  1642. mBumpSunDir = adjusted_dir * sun_dot + new_dir * (1.f - sun_dot);
  1643. mBumpSunDir.normalize();
  1644. mSun.setDirection(sun_direction);
  1645. mSun.setAngularVelocity(sun_ang_velocity);
  1646. mMoon.setDirection(-sun_direction);
  1647. F32 dp = mLastLightingDirection * sun_direction;
  1648. if (dp < 0.995f)
  1649. {
  1650. // The sun jumped a great deal, update immediately
  1651. mForceUpdate = true;
  1652. }
  1653. }
  1654. void LLVOSky::setSunDirectionCFR(const LLVector3& sun_dir_cfr)
  1655. {
  1656. mSun.setDirection(sun_dir_cfr);
  1657. mSun.setAngularVelocity(LLVector3::zero);
  1658. // Push the sun "South" as it approaches directly overhead so that we can
  1659. // always see bump mapping on the upward facing faces of cubes.
  1660. // Same as dot product with the up direction + clamp.
  1661. F32 sun_dot = llmax(0.f, sun_dir_cfr.mV[2]);
  1662. sun_dot *= sun_dot;
  1663. // Create normalized vector that has the sun_dir pushed south about an hour
  1664. // and change.
  1665. LLVector3 adjusted_dir = (sun_dir_cfr +
  1666. LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
  1667. // Blend between normal sun dir and adjusted sun dir based on how close we
  1668. // are to having the sun overhead.
  1669. mBumpSunDir = adjusted_dir * sun_dot + sun_dir_cfr * (1.f - sun_dot);
  1670. mBumpSunDir.normalize();
  1671. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  1672. if (skyp) // Paranoia
  1673. {
  1674. updateDirections(skyp);
  1675. }
  1676. }
  1677. void LLVOSky::setMoonDirectionCFR(const LLVector3& moon_dir)
  1678. {
  1679. mMoon.setDirection(moon_dir);
  1680. const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
  1681. if (skyp) // Paranoia
  1682. {
  1683. updateDirections(skyp);
  1684. }
  1685. }
  1686. void LLVOSky::updateDirections(const LLSettingsSky::ptr_t& skyp)
  1687. {
  1688. mSun.setDirection(skyp->getSunDirection());
  1689. mSun.setAngularVelocity(LLVector3::zero);
  1690. mSun.setRotation(skyp->getSunRotation());
  1691. mMoon.setDirection(skyp->getMoonDirection());
  1692. mMoon.setRotation(skyp->getMoonRotation());
  1693. mSun.renewDirection();
  1694. mMoon.renewDirection();
  1695. }
  1696. void LLVOSky::setSunTextures(const LLUUID& sun_tex1, const LLUUID& sun_tex2)
  1697. {
  1698. if (sun_tex1.isNull())
  1699. {
  1700. if (gSunTextureID != IMG_SUN)
  1701. {
  1702. mSunTexturep[0] =
  1703. LLViewerTextureManager::getFetchedTexture(gSunTextureID,
  1704. FTT_DEFAULT, true,
  1705. LLGLTexture::BOOST_UI);
  1706. mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1707. }
  1708. else
  1709. {
  1710. mSunTexturep[0] = LLViewerFetchedTexture::sDefaultSunImagep;
  1711. }
  1712. }
  1713. else
  1714. {
  1715. mSunTexturep[0] =
  1716. LLViewerTextureManager::getFetchedTexture(sun_tex1,
  1717. FTT_DEFAULT, true,
  1718. LLGLTexture::BOOST_UI);
  1719. mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1720. }
  1721. if (sun_tex2.isNull())
  1722. {
  1723. mSunTexturep[1] = NULL;
  1724. }
  1725. else
  1726. {
  1727. mSunTexturep[1] =
  1728. LLViewerTextureManager::getFetchedTexture(sun_tex2,
  1729. FTT_DEFAULT, true,
  1730. LLGLTexture::BOOST_UI);
  1731. mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1732. }
  1733. LLFace* facep = mFace[FACE_SUN];
  1734. if (!facep)
  1735. {
  1736. return;
  1737. }
  1738. LLViewerTexture* tex = facep->getTexture(LLRender::DIFFUSE_MAP);
  1739. if (tex && tex != mSunTexturep[0] && tex->isViewerMediaTexture())
  1740. {
  1741. ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
  1742. }
  1743. tex = facep->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
  1744. if (tex && tex != mSunTexturep[1] && tex->isViewerMediaTexture())
  1745. {
  1746. ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
  1747. }
  1748. facep->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
  1749. if (mSunTexturep[1] && gPipeline.canUseWindLightShaders())
  1750. {
  1751. facep->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
  1752. }
  1753. }
  1754. void LLVOSky::setMoonTextures(const LLUUID& moon_tex1, const LLUUID& moon_tex2)
  1755. {
  1756. if (moon_tex1.isNull())
  1757. {
  1758. if (gMoonTextureID != IMG_MOON)
  1759. {
  1760. mMoonTexturep[0] =
  1761. LLViewerTextureManager::getFetchedTexture(gMoonTextureID,
  1762. FTT_DEFAULT, true,
  1763. LLGLTexture::BOOST_UI);
  1764. mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1765. }
  1766. else
  1767. {
  1768. mMoonTexturep[0] = LLViewerFetchedTexture::sDefaultMoonImagep;
  1769. }
  1770. }
  1771. else
  1772. {
  1773. mMoonTexturep[0] =
  1774. LLViewerTextureManager::getFetchedTexture(moon_tex1,
  1775. FTT_DEFAULT, true,
  1776. LLGLTexture::BOOST_UI);
  1777. mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1778. }
  1779. if (moon_tex2.isNull())
  1780. {
  1781. mMoonTexturep[1] = NULL;
  1782. }
  1783. else
  1784. {
  1785. mMoonTexturep[1] =
  1786. LLViewerTextureManager::getFetchedTexture(moon_tex2,
  1787. FTT_DEFAULT, true,
  1788. LLGLTexture::BOOST_UI);
  1789. mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1790. }
  1791. LLFace* facep = mFace[FACE_MOON];
  1792. if (!facep)
  1793. {
  1794. return;
  1795. }
  1796. LLViewerTexture* tex = facep->getTexture(LLRender::DIFFUSE_MAP);
  1797. if (tex && tex != mMoonTexturep[0] && tex->isViewerMediaTexture())
  1798. {
  1799. ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
  1800. }
  1801. tex = facep->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
  1802. if (tex && tex != mMoonTexturep[1] && tex->isViewerMediaTexture())
  1803. {
  1804. ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
  1805. }
  1806. facep->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
  1807. if (mMoonTexturep[1] && gPipeline.canUseWindLightShaders())
  1808. {
  1809. facep->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
  1810. }
  1811. }
  1812. void LLVOSky::setCloudNoiseTextures(const LLUUID& tex1, const LLUUID& tex2)
  1813. {
  1814. if (tex1.isNull())
  1815. {
  1816. mCloudNoiseTexturep[0] =
  1817. LLViewerFetchedTexture::sDefaultCloudNoiseImagep;
  1818. }
  1819. else
  1820. {
  1821. mCloudNoiseTexturep[0] =
  1822. LLViewerTextureManager::getFetchedTexture(tex1, FTT_DEFAULT, true,
  1823. LLGLTexture::BOOST_UI);
  1824. mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
  1825. }
  1826. if (tex2.isNull())
  1827. {
  1828. mCloudNoiseTexturep[1] = NULL;
  1829. return;
  1830. }
  1831. mCloudNoiseTexturep[1] =
  1832. LLViewerTextureManager::getFetchedTexture(tex2, FTT_DEFAULT, true,
  1833. LLGLTexture::BOOST_UI);
  1834. mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP);
  1835. }
  1836. void LLVOSky::setBloomTextures(const LLUUID& tex1, const LLUUID& tex2)
  1837. {
  1838. if (tex1.isNull())
  1839. {
  1840. mBloomTexturep[0] = LLViewerFetchedTexture::sBloomImagep;
  1841. }
  1842. else
  1843. {
  1844. mBloomTexturep[0] =
  1845. LLViewerTextureManager::getFetchedTexture(tex1, FTT_DEFAULT, true,
  1846. LLGLTexture::BOOST_UI);
  1847. if (mBloomTexturep[0])
  1848. {
  1849. mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1850. }
  1851. }
  1852. if (tex2.isNull())
  1853. {
  1854. mBloomTexturep[1] = mBloomTexturep[0];
  1855. return;
  1856. }
  1857. mBloomTexturep[1] =
  1858. LLViewerTextureManager::getFetchedTexture(tex2, FTT_DEFAULT, true,
  1859. LLGLTexture::BOOST_UI);
  1860. mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
  1861. }