summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/lllegacyatmospherics.cpp183
-rw-r--r--indra/newview/lllegacyatmospherics.h5
-rw-r--r--indra/newview/llvosky.cpp27
-rw-r--r--indra/newview/llvosky.h2
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];