diff options
-rw-r--r-- | indra/newview/lllegacyatmospherics.cpp | 183 | ||||
-rw-r--r-- | indra/newview/lllegacyatmospherics.h | 5 | ||||
-rw-r--r-- | indra/newview/llvosky.cpp | 27 | ||||
-rw-r--r-- | indra/newview/llvosky.h | 2 |
4 files changed, 180 insertions, 37 deletions
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp index 13d5eb96c4..fb779bb1a7 100644 --- a/indra/newview/lllegacyatmospherics.cpp +++ b/indra/newview/lllegacyatmospherics.cpp @@ -205,12 +205,16 @@ void LLAtmospherics::init() LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny) { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + return calcSkyColorInDir(psky, vars, dir, isShiny); +} +LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny) +{ F32 saturation = 0.3f; if (isShiny && dir.mV[VZ] < -0.02f) { - LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); + LLColor4 col; LLColor3 desat_fog = LLColor3(mFogColor); F32 brightness = desat_fog.brightness(); // So that shiny somewhat shows up at night. @@ -219,8 +223,8 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVecto brightness = 0.15f; desat_fog = smear(0.15f); } - LLColor3 greyscale = smear(brightness); - desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); + F32 greyscale_sat = brightness * (1.0f - saturation); + desat_fog = desat_fog * saturation + smear(greyscale_sat); if (!gPipeline.canUseWindLightShaders()) { col = LLColor4(desat_fog, 0.f); @@ -240,36 +244,34 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVecto // undo OGL_TO_CFR_ROTATION and negate vertical direction. LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); - calcSkyColorWLVert(Pn, vars); - - bool low_end = !gPipeline.canUseWindLightShaders(); - - LLColor3 sky_color = isShiny ? vars.hazeColor : - low_end ? vars.hazeColor * 2.0f : psky->gammaCorrect(vars.hazeColor * 2.0f); + //calculates hazeColor + calcSkyColorWLVert(psky, Pn, vars); if (isShiny) { - F32 brightness = sky_color.brightness(); - LLColor3 greyscale = smear(brightness); - sky_color = sky_color * saturation + greyscale * (1.0f - saturation); + F32 brightness = vars.hazeColor.brightness(); + F32 greyscale_sat = brightness * (1.0f - saturation); + LLColor3 sky_color = vars.hazeColor * saturation + smear(greyscale_sat); sky_color *= (0.5f + 0.5f * brightness); + return LLColor4(sky_color, 0.0f); } + + bool low_end = !gPipeline.canUseWindLightShaders(); + LLColor3 sky_color = low_end ? vars.hazeColor * 2.0f : psky->gammaCorrect(vars.hazeColor * 2.0f); + return LLColor4(sky_color, 0.0f); } const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees const F32 NIGHTTIME_ELEVATION_SIN = (F32)sinf(NIGHTTIME_ELEVATION*DEG_TO_RAD); -void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) +void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars) { - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLColor3 blue_density = vars.blue_density; LLColor3 blue_horizon = vars.blue_horizon; F32 haze_horizon = vars.haze_horizon; F32 haze_density = vars.haze_density; F32 density_multiplier = vars.density_multiplier; - F32 distance_multiplier = vars.distance_multiplier; F32 max_y = vars.max_y; LLVector4 sun_norm = vars.sun_norm; @@ -316,13 +318,10 @@ void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) LLColor3 temp1 = vars.total_density; LLColor3 blue_weight = componentDiv(blue_density, temp1); + LLColor3 blue_factor = blue_horizon * blue_weight; LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + LLColor3 haze_factor = haze_horizon * haze_weight; - F32 lighty = sun_norm.mV[1]; - if(lighty < NIGHTTIME_ELEVATION_SIN) - { - lighty = -lighty; - } // Compute sunlight from P & lightnorm (for long rays like sky) temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + sun_norm.mV[1] ); @@ -335,8 +334,7 @@ void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) temp2.mV[2] = Plen * density_multiplier; // Transparency (-> temp1) - temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);// * distance_multiplier); - (void)distance_multiplier; + temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); // Compute haze glow temp2.mV[0] = Pn * LLVector3(sun_norm); @@ -357,7 +355,7 @@ void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) // Haze color above cloud - vars.hazeColor = (blue_horizon * blue_weight * (sunlight + ambient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient)); + vars.hazeColor = (blue_factor * (sunlight + ambient) + componentMult(haze_factor, sunlight * temp2.mV[0] + ambient)); // Increase ambient when there are more clouds LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; @@ -366,7 +364,7 @@ void LLAtmospherics::calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars) sunlight *= (1.f - cloud_shadow); // Haze color below cloud - vars.hazeColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)); + vars.hazeColorBelowCloud = (blue_factor * (sunlight + tmpAmbient) + componentMult(haze_factor, sunlight * temp2.mV[0] + tmpAmbient)); LLColor3 final_atten = LLColor3::white - temp1; final_atten.mV[0] = llmax(final_atten.mV[0], 0.0f); @@ -716,3 +714,138 @@ bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b) return true; } + +bool aproximately_equal(const F32 &a, const F32 &b, const F32 &fraction_treshold) +{ + F32 diff = fabs(a - b); + if (diff < F_APPROXIMATELY_ZERO || diff < llmax(fabs(a), fabs(b)) * fraction_treshold) + { + return true; + } + return false; +} + +bool aproximately_equal(const LLColor3 &a, const LLColor3 &b, const F32 &fraction_treshold) +{ + return aproximately_equal(a.mV[0], b.mV[0], fraction_treshold) + && aproximately_equal(a.mV[1], b.mV[1], fraction_treshold) + && aproximately_equal(a.mV[2], b.mV[2], fraction_treshold); +} + +bool aproximately_equal(const LLVector4 &a, const LLVector4 &b, const F32 &fraction_treshold) +{ + return aproximately_equal(a.mV[0], b.mV[0], fraction_treshold) + && aproximately_equal(a.mV[1], b.mV[1], fraction_treshold) + && aproximately_equal(a.mV[2], b.mV[2], fraction_treshold) + && aproximately_equal(a.mV[3], b.mV[3], fraction_treshold); +} + +bool aproximatelyEqual(const AtmosphericsVars& a, const AtmosphericsVars& b, const F32 fraction_treshold) +{ + if (!aproximately_equal(a.hazeColor, b.hazeColor, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.hazeColorBelowCloud, b.hazeColorBelowCloud, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.cloudColorSun, b.cloudColorSun, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.cloudColorAmbient, b.cloudColorAmbient, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.cloudDensity, b.cloudDensity, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.density_multiplier, b.density_multiplier, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.haze_horizon, b.haze_horizon, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.haze_density, b.haze_density, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.blue_horizon, b.blue_horizon, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.blue_density, b.blue_density, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.dome_offset, b.dome_offset, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.dome_radius, b.dome_radius, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.cloud_shadow, b.cloud_shadow, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.glow, b.glow, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.ambient, b.ambient, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.sunlight, b.sunlight, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.sun_norm, b.sun_norm, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.gamma, b.gamma, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.max_y, b.max_y, fraction_treshold)) + { + return false; + } + + if (!aproximately_equal(a.distance_multiplier, b.distance_multiplier, fraction_treshold)) + { + return false; + } + + // light_atten, light_transmittance, total_density + // are ignored as they always change when the values above do + // they're just shared calc across the sky map generation to save cycles + + return true; +} + diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h index cdfcead7a4..5dd8c41a32 100644 --- a/indra/newview/lllegacyatmospherics.h +++ b/indra/newview/lllegacyatmospherics.h @@ -207,6 +207,8 @@ public: } friend bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b); + // returns true if values are within treshold of each other. + friend bool aproximatelyEqual(const AtmosphericsVars& a, const AtmosphericsVars& b, const F32 fraction_treshold = 0.0005); LLColor3 hazeColor; LLColor3 hazeColorBelowCloud; @@ -256,10 +258,11 @@ public: void setWind ( const LLVector3& wind ) { mWind = wind.length(); } LLColor4 calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false); + LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false); protected: - void calcSkyColorWLVert(LLVector3 & Pn, AtmosphericsVars& vars); + void calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars); LLColor3 getHazeColor(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, F32 costheta, F32 cloud_shadow); LLHaze mHaze; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 19299f55a2..3ef148e473 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -498,8 +498,7 @@ void LLVOSky::init() for (S32 tile = 0; tile < NUM_TILES; ++tile) { initSkyTextureDirs(side, tile); - createSkyTexture(m_atmosphericsVars, side, tile, mSkyTex); - createSkyTexture(m_atmosphericsVars, side, tile, mShinyTex, true); + createSkyTexture(m_atmosphericsVars, side, tile); } mSkyTex[side].create(1.0f); mShinyTex[side].create(1.0f); @@ -647,8 +646,10 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) } } -void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile, LLSkyTex* tex, bool is_shiny) +void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile) { + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + S32 tile_x = tile % NUM_TILES_X; S32 tile_y = tile / NUM_TILES_X; @@ -660,7 +661,8 @@ void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 { for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) { - tex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, tex[side].getDir(x, y), is_shiny), x, y); + mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex[side].getDir(x, y), false), x, y); + mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true), x, y); } } } @@ -710,8 +712,6 @@ bool LLVOSky::updateSky() return TRUE; } - bool is_alm_wl_sky = gPipeline.canUseWindLightShaders(); - static S32 next_frame = 0; const S32 total_no_tiles = NUM_CUBEMAP_FACES * NUM_TILES; const S32 cycle_frame_no = total_no_tiles + 1; @@ -737,7 +737,7 @@ bool LLVOSky::updateSky() LL_RECORD_BLOCK_TIME(FTM_VOSKY_CALC); calc(); - bool same_atmospherics = m_lastAtmosphericsVars == m_atmosphericsVars; + bool same_atmospherics = aproximatelyEqual(m_lastAtmosphericsVars, m_atmosphericsVars); mNeedUpdate = mNeedUpdate || !same_atmospherics; @@ -754,6 +754,8 @@ bool LLVOSky::updateSky() LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED); LLSkyTex::stepCurrent(); + bool is_alm_wl_sky = gPipeline.canUseWindLightShaders(); + int tex = mSkyTex[0].getWhich(TRUE); for (int side = 0; side < NUM_CUBEMAP_FACES; side++) @@ -807,14 +809,19 @@ bool LLVOSky::updateSky() } mCubeMapUpdateStage = -1; } + // run 0 to 5 faces, each face in own frame else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES) { LL_RECORD_BLOCK_TIME(FTM_VOSKY_CREATETEXTURES); S32 side = mCubeMapUpdateStage; - for (int tile = 0; tile < NUM_TILES; tile++) + // CPU hungry part, createSkyTexture() is math heavy + // Prior to EEP it was mostly per tile, but since EPP it is per face. + // This still can be optimized further + // (i.e. potentially can be made per tile again, can be moved to thread + // instead of executing per face, or may be can be moved to shaders) + for (S32 tile = 0; tile < NUM_TILES; tile++) { - createSkyTexture(m_atmosphericsVars, side, tile, mSkyTex); - createSkyTexture(m_atmosphericsVars, side, tile, mShinyTex, true); + createSkyTexture(m_atmosphericsVars, side, tile); } mCubeMapUpdateStage++; } diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index b1a01a9366..fc577ab5f8 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -302,7 +302,7 @@ protected: void updateDirections(void); void initSkyTextureDirs(const S32 side, const S32 tile); - void createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile, LLSkyTex* tex, bool is_shiny = false); + void createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile); LLPointer<LLViewerFetchedTexture> mSunTexturep[2]; LLPointer<LLViewerFetchedTexture> mMoonTexturep[2]; |