summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/testplans/material_preview.md81
-rw-r--r--indra/llrender/llrendertarget.cpp27
-rw-r--r--indra/llrender/llrendertarget.h3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl6
-rw-r--r--indra/newview/lldynamictexture.cpp3
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp28
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.h8
-rw-r--r--indra/newview/lltexturectrl.cpp15
-rw-r--r--indra/newview/lltexturectrl.h42
-rw-r--r--indra/newview/llviewershadermgr.cpp17
-rw-r--r--indra/newview/llviewershadermgr.h1
-rw-r--r--indra/newview/pipeline.cpp71
-rw-r--r--indra/newview/pipeline.h2
13 files changed, 246 insertions, 58 deletions
diff --git a/doc/testplans/material_preview.md b/doc/testplans/material_preview.md
new file mode 100644
index 0000000000..d653fc45ca
--- /dev/null
+++ b/doc/testplans/material_preview.md
@@ -0,0 +1,81 @@
+# Material Preview
+
+## Overview
+
+Material preview is a UI feature which displays a lit spherical preview of a PBR material. It can be found in the following UIs:
+
+- The material picker swatch
+ - In the build floater, in the Texture tab, when applying a PBR material
+ - (If the feature is enabled) In the Region/Estate floater, in the Terrain tab, when applying PBR materials to terrain
+- In the floater to select a material from inventory, which can be opened by clicking the material picker swatch
+
+## Known Issues
+
+These are known issues that the current implementation of this feature does not address:
+
+- Material swatch preview is a preview of the base material ID only, and ignores other properties on the prim face like material overrides
+- Alpha mask previews as alpha blend
+- Double-sided previews as single-sided
+- Material swatch preview inherits some of its lighting from the current environment, and reflections from the default reflection probe
+
+## General Regression Testing
+
+- Check that the material preview swatch looks OK with different materials selected
+- Check that the material preview swatch runs reasonably well on different systems, especially when the select material from inventory floater is also open
+ - In particular: AMD, MacOS, minimum spec machines
+- Watch out for regressions in rendering caused by opening a floater with a material preview swatch
+
+## Bug Fixes
+
+### Disappearing Objects Fix Test
+
+This test is recommended for verifying that secondlife/viewer-issues#72 is fixed.
+
+#### Symptoms
+
+The following types of objects could randomly disappear until relog in the main view when the bug occured:
+
+- Objects
+- Water level in current region
+- Adjacent region/void water
+
+Note: Disappearing objects in reflections have a different root cause and are not covered by the fix.
+
+#### Bug Reproduction Steps
+
+Verify the disappearing objects bug does not reproduce, given the following steps:
+
+- Runtime prerequisites: Material preview swatch is enabled ("UIPreviewMaterial") by visiting a test region with the feature enabled, or by manually enabling "UIPreviewMaterial" in the advanced settings for the current session
+- Region prerequisites: Unknown, but a region with lots of stuff in it (like Rumpus Room 2048 on Aditi) seems to increase repro rate
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Ensure "Apply now" is checked in the inventory selection floater
+- Alternate between different materials from the inventory selection floater
+- Look around the world and check for permanently disappeared objects.
+
+### Dynamic Exposure Influence Fix Test
+
+This test is recommended for verifying that secondlife/viewer-issues#72 is fixed.
+
+#### Symptoms
+
+Dynamic exposure in the world could be influenced by the material preview being displayed. If a material preview was being generated in a given frame, then, depending on the current environment, the user would observe an unpleasant flashing effect in the environment:
+
+- The world view could suddenly get darker and then fade back to normal exposure levels
+- The world view could suddenly get brighter and then fade back to normal exposure levels
+
+#### Bug Reproduction Steps
+
+Verify the dynamic exposure influence bug does not reproduce. Test using a few environment presets such as Default Midday, Sunset, and Midnight.
+
+- Right click an object and select, "Edit item"
+- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory
+- Alternate between different materials from the inventory selection floater
+
+#### Regression Testing
+
+Dynamic exposure in the world should continue to work correctly. In particular:
+
+- Exposure should fade gradually from high exposure to low exposure and back as needed
+- Exposure should decrease in brighter environments
+- Exposure should increase in darker environments
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 88c48e5166..9cd7527d3e 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -567,4 +567,31 @@ bool LLRenderTarget::isBoundInStack() const
return cur == this;
}
+void LLRenderTarget::swapFBORefs(LLRenderTarget& other)
+{
+ // Must be initialized
+ llassert(mFBO);
+ llassert(other.mFBO);
+ // Must be unbound
+ // *NOTE: mPreviousRT can be non-null even if this target is unbound - presumably for debugging purposes?
+ llassert(sCurFBO != mFBO);
+ llassert(sCurFBO != other.mFBO);
+ llassert(!isBoundInStack());
+ llassert(!other.isBoundInStack());
+
+ // Must be same type
+ llassert(sUseFBO == other.sUseFBO);
+ llassert(mResX == other.mResX);
+ llassert(mResY == other.mResY);
+ llassert(mInternalFormat == other.mInternalFormat);
+ llassert(mTex.size() == other.mTex.size());
+ llassert(mDepth == other.mDepth);
+ llassert(mUseDepth == other.mUseDepth);
+ llassert(mGenerateMipMaps == other.mGenerateMipMaps);
+ llassert(mMipLevels == other.mMipLevels);
+ llassert(mUsage == other.mUsage);
+
+ std::swap(mFBO, other.mFBO);
+ std::swap(mTex, other.mTex);
+}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 9fcea35e3d..da401572d1 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -169,6 +169,9 @@ public:
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+ // *HACK
+ void swapFBORefs(LLRenderTarget& other);
+
protected:
U32 mResX;
U32 mResY;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 9ac4ceb37e..eff7221ae7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -28,7 +28,9 @@
out vec4 frag_color;
uniform sampler2D emissiveRect;
+#ifdef USE_LAST_EXPOSURE
uniform sampler2D exposureMap;
+#endif
uniform float dt;
uniform vec2 noiseVec;
@@ -51,10 +53,12 @@ void main()
L /= max_L;
L = pow(L, 2.0);
float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L);
-
+
+#ifdef USE_LAST_EXPOSURE
float prev = texture(exposureMap, vec2(0.5,0.5)).r;
s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
+#endif
frag_color = max(vec4(s, s, s, dt), vec4(0.0));
}
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index a66c3876fc..24818241ab 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -118,6 +118,8 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
//use the bottom left corner
mOrigin.set(0, 0);
@@ -219,7 +221,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH);
glClear(GL_DEPTH_BUFFER_BIT);
- gDepthDirty = TRUE;
gGL.color4f(1,1,1,1);
dynamicTexture->setBoundTarget(&bake_target);
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
index 901db87eed..1c39f1ae7d 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -58,6 +58,15 @@ LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels()
}
}
+bool LLGLTFPreviewTexture::MaterialLoadLevels::isFullyLoaded()
+{
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (levels[i] != FULLY_LOADED) { return false; }
+ }
+ return true;
+}
+
S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i)
{
llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
@@ -187,17 +196,26 @@ LLPointer<LLGLTFPreviewTexture> LLGLTFPreviewTexture::create(LLPointer<LLFetched
return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH);
}
-void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
+BOOL LLGLTFPreviewTexture::needsRender()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+ if (!mShouldRender && mBestLoad.isFullyLoaded()) { return false; }
MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get());
if (current_load < mBestLoad)
{
mShouldRender = true;
mBestLoad = current_load;
+ return true;
}
+ return false;
+}
+void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ llassert(mShouldRender);
if (!mShouldRender) { return; }
LLViewerDynamicTexture::preRender(clear_depth);
@@ -499,9 +517,12 @@ BOOL LLGLTFPreviewTexture::render()
screen.flush();
}
+ // *HACK: Hide mExposureMap from generateExposure
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
- gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap);
+ gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false);
gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap);
LLVertexBuffer::unbind();
gPipeline.generateGlow(&gPipeline.mPostMap);
@@ -509,6 +530,9 @@ BOOL LLGLTFPreviewTexture::render()
gPipeline.renderDoF(&screen, &gPipeline.mPostMap);
gPipeline.applyFXAA(&gPipeline.mPostMap, &screen);
+ // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame)
+ gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure);
+
// Final render
gDeferredPostNoDoFProgram.bind();
diff --git a/indra/newview/llgltfmaterialpreviewmgr.h b/indra/newview/llgltfmaterialpreviewmgr.h
index cc40a6f2e2..981c8b0592 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.h
+++ b/indra/newview/llgltfmaterialpreviewmgr.h
@@ -40,7 +40,7 @@ public:
// Width scales with size of material's textures
static LLPointer<LLGLTFPreviewTexture> create(LLPointer<LLFetchedGLTFMaterial> material);
- BOOL needsRender() override { return mNeedsRender; }
+ BOOL needsRender() override;
void preRender(BOOL clear_depth = TRUE) override;
BOOL render() override;
void postRender(BOOL success) override;
@@ -50,15 +50,12 @@ public:
S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
MaterialLoadLevels();
-
+ bool isFullyLoaded();
S32& operator[](size_t i);
-
const S32& operator[](size_t i) const;
-
// Less is better
// Returns false if lhs is not strictly less or equal for all levels
bool operator<(const MaterialLoadLevels& other) const;
-
// Less is better
// Returns false if lhs is not strictly greater or equal for all levels
bool operator>(const MaterialLoadLevels& other) const;
@@ -66,7 +63,6 @@ public:
private:
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
- bool mNeedsRender = true;
bool mShouldRender = true;
MaterialLoadLevels mBestLoad;
};
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 5415f9bd9a..d9001bc16a 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -538,6 +538,8 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
}
stopUsingPipette();
sLastPickerMode = mModeSelector->getValue().asInteger();
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
}
// virtual
@@ -1760,6 +1762,19 @@ void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask)
setDnDFilterPermMask(mask);
}
+void LLTextureCtrl::onVisibilityChange(BOOL new_visibility)
+{
+ if (!new_visibility)
+ {
+ // *NOTE: Vertex buffer for sphere preview is still cached
+ mGLTFPreview = nullptr;
+ }
+ else
+ {
+ llassert(!mGLTFPreview);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 05ea185b1b..f193b0c083 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -148,26 +148,28 @@ public:
// LLView interface
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
- EAcceptance *accept,
- std::string& tooltip_msg);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleUnicodeCharHere(llwchar uni_char);
-
- virtual void draw();
- virtual void setVisible( BOOL visible );
- virtual void setEnabled( BOOL enabled );
-
- void setValid(BOOL valid);
-
- // LLUICtrl interface
- virtual void clear();
-
- // Takes a UUID, wraps get/setImageAssetID
- virtual void setValue(const LLSD& value);
- virtual LLSD getValue() const;
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+ EAcceptance *accept,
+ std::string& tooltip_msg) override;
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleUnicodeCharHere(llwchar uni_char) override;
+
+ void draw() override;
+ void setVisible( BOOL visible ) override;
+ void setEnabled( BOOL enabled ) override;
+
+ void onVisibilityChange(BOOL new_visibility) override;
+
+ void setValid(BOOL valid);
+
+ // LLUICtrl interface
+ void clear() override;
+
+ // Takes a UUID, wraps get/setImageAssetID
+ void setValue(const LLSD& value) override;
+ LLSD getValue() const override;
// LLTextureCtrl interface
void showPicker(BOOL take_focus);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 4eb934114d..354cc79036 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -196,6 +196,7 @@ LLGLSLShader gDeferredPostGammaCorrectProgram;
LLGLSLShader gNoPostGammaCorrectProgram;
LLGLSLShader gLegacyPostGammaCorrectProgram;
LLGLSLShader gExposureProgram;
+LLGLSLShader gExposureProgramNoFade;
LLGLSLShader gLuminanceProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
@@ -980,6 +981,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredCoFProgram.unload();
gDeferredDoFCombineProgram.unload();
gExposureProgram.unload();
+ gExposureProgramNoFade.unload();
gLuminanceProgram.unload();
gDeferredPostGammaCorrectProgram.unload();
gNoPostGammaCorrectProgram.unload();
@@ -2127,6 +2129,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gExposureProgram.mFeatures.isDeferred = true;
gExposureProgram.mShaderFiles.clear();
gExposureProgram.clearPermutations();
+ gExposureProgram.addPermutation("USE_LAST_EXPOSURE", "1");
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2136,6 +2139,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gExposureProgramNoFade.mName = "Exposure (no fade)";
+ gExposureProgramNoFade.mFeatures.hasSrgb = true;
+ gExposureProgramNoFade.mFeatures.isDeferred = true;
+ gExposureProgramNoFade.mShaderFiles.clear();
+ gExposureProgramNoFade.clearPermutations();
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
+ gExposureProgramNoFade.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gExposureProgramNoFade.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
gLuminanceProgram.mName = "Luminance";
gLuminanceProgram.mShaderFiles.clear();
gLuminanceProgram.clearPermutations();
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 57fc66ce0d..2502be6bb1 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -249,6 +249,7 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gNoPostGammaCorrectProgram;
extern LLGLSLShader gLegacyPostGammaCorrectProgram;
extern LLGLSLShader gExposureProgram;
+extern LLGLSLShader gExposureProgramNoFade;
extern LLGLSLShader gLuminanceProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9d90002eb9..6ceaca731b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6772,11 +6772,12 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
}
}
-void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history) {
// exposure sample
{
LL_PROFILE_GPU_ZONE("exposure sample");
+ if (use_history)
{
// copy last frame's exposure into mLastExposure
mLastExposure.bindTarget();
@@ -6793,51 +6794,67 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- gExposureProgram.bind();
+ LLGLSLShader* shader;
+ if (use_history)
+ {
+ shader = &gExposureProgram;
+ }
+ else
+ {
+ shader = &gExposureProgramNoFade;
+ }
+
+ shader->bind();
- S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
if (channel > -1)
{
- mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
}
- channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
- if (channel > -1)
+ if (use_history)
{
- mLastExposure.bindTexture(0, channel);
+ channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
}
static LLStaticHashedString dt("dt");
static LLStaticHashedString noiseVec("noiseVec");
static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
- static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
- F32 exp_min = 1.f;
- F32 exp_max = 1.f;
-
- if (probe_ambiance > 0.f)
- {
- F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma())*2.f;
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 exp_min = 1.f;
+ F32 exp_max = 1.f;
- if (hdr_scale > 1.f)
- {
- exp_min = 1.f / hdr_scale;
- exp_max = hdr_scale;
- }
- }
- gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
- gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
- gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
+ if (probe_ambiance > 0.f)
+ {
+ F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f;
+
+ if (hdr_scale > 1.f)
+ {
+ exp_min = 1.f / hdr_scale;
+ exp_max = hdr_scale;
+ }
+ }
+ shader->uniform1f(dt, gFrameIntervalSeconds);
+ shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+ shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
- gExposureProgram.unbind();
+ if (use_history)
+ {
+ gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
+ }
+ shader->unbind();
dst->flush();
}
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index e8c6da1473..259dc3f9d0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -154,7 +154,7 @@ public:
void renderFinalize();
void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
- void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true);
void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
void generateGlow(LLRenderTarget* src);
void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);