summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolwater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolwater.cpp')
-rw-r--r--indra/newview/lldrawpoolwater.cpp245
1 files changed, 114 insertions, 131 deletions
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 53d6e528b6..7d58511d41 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -176,173 +176,156 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
- // set up normal maps filtering
- for (auto norm_map : mWaterNormp)
- {
- if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
- }
+ LLTexUnit::eTextureFilterOptions filter_mode = has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT;
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
LLGLSLShader *shader = nullptr;
- // two passes, first with standard water shader bound, second with edge water shader bound
- for (int edge = 0; edge < 2; edge++)
+ // One pass, one of two shaders. Void water and region water share state.
+ // There isn't a good reason anymore to really have void water run in a separate pass.
+ // It also just introduced a bunch of weird state consistency stuff that we really don't need.
+ // Not to mention, re-binding the the same shader and state for that shader is kind of wasteful.
+ // - Geenz 2025-02-11
+ // select shader
+ if (underwater)
{
- // select shader
- if (underwater)
- {
- shader = &gUnderWaterProgram;
- }
- else
- {
- if (edge)
- {
- shader = &gWaterEdgeProgram;
- }
- else
- {
- shader = &gWaterProgram;
- }
- }
+ shader = &gUnderWaterProgram;
+ }
+ else
+ {
+ shader = &gWaterProgram;
+ }
- gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
- LLViewerTexture* tex_a = mWaterNormp[0];
- LLViewerTexture* tex_b = mWaterNormp[1];
+ F32 blend_factor = (F32)pwater->getBlendFactor();
- F32 blend_factor = (F32)pwater->getBlendFactor();
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b);
+ tex_b->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b);
+ tex_b->setFilteringOption(filter_mode);
+ }
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask);
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
- }
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
+ shader->bindTexture(LLShaderMgr::WATER_SCREENTEX, &gPipeline.mWaterDis);
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
+ }
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+ F32 water_height = environment.getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- if (mShaderLevel == 1)
- {
- fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
- }
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
- F32 water_height = environment.getWaterHeight();
- F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
- shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
- shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, fmaxf(0, pwater->getBlurMultiplier()) * 2);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ static LLStaticHashedString s_exposure("exposure");
+ static LLStaticHashedString tonemap_mix("tonemap_mix");
+ static LLStaticHashedString tonemap_type("tonemap_type");
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false);
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ shader->uniform1f(s_exposure, e);
+ static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
+ shader->uniform1i(tonemap_type, tonemap_type_setting);
+ shader->uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
- // SL-15861 This was changed from getRotatedLightNorm() as it was causing
- // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
- LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
- shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ // SL-15861 This was changed from getRotatedLightNorm() as it was causing
+ // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLGLDisable cullface(GL_CULL_FACE);
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
- LLVOWater* water = nullptr;
- for (LLFace* const& face : mDrawFace)
- {
- if (!face) continue;
- water = static_cast<LLVOWater*>(face->getViewerObject());
- if (!water) continue;
-
- if ((bool)edge == (bool)water->getIsEdgePatch())
- {
- face->renderIndexed();
-
- // Note non-void water being drawn, updates required
- if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
- {
- sNeedsReflectionUpdate = true;
- sNeedsDistortionUpdate = true;
- }
- }
- }
+ LLGLDisable cullface(GL_CULL_FACE);
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ // Only push the water planes once.
+ // Previously we did this twice: once for void water and one for region water.
+ // However, the void water and region water shaders are the same exact shader.
+ // They also had the same exact state with the sole exception setting an edge water flag.
+ // That flag was not actually used anywhere in the shaders.
+ // - Geenz 2025-02-11
+ pushWaterPlanes(0);
- // clean up
- gPipeline.unbindDeferredShader(*shader);
+ // clean up
+ gPipeline.unbindDeferredShader(*shader);
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ gGL.setColorMask(true, false);
+}
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+void LLDrawPoolWater::pushWaterPlanes(int pass)
+{
+ LLVOWater* water = nullptr;
+ for (LLFace* const& face : mDrawFace)
+ {
+ water = static_cast<LLVOWater*>(face->getViewerObject());
- gGL.setColorMask(true, false);
+ face->renderIndexed();
+
+ // Note non-void water being drawn, updates required
+ // Previously we had some logic to determine if this pass was also our water edge pass.
+ // Now we only have one pass. Check if we're doing a region water plane or void water plane.
+ // - Geenz 2025-02-11
+ if (!water->getIsEdgePatch())
+ {
+ sNeedsReflectionUpdate = true;
+ sNeedsDistortionUpdate = true;
+ }
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()