Merge branch 'release/materials_featurette' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/lltexturectrl.cppmaster
commit
eb98cb3864
|
|
@ -0,0 +1,83 @@
|
|||
# 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:
|
||||
|
||||
- The material preview in the build floater is a preview of the base material ID only, and ignores other properties on the prim face like material overrides (https://github.com/secondlife/viewer/issues/865)
|
||||
- Alpha mask previews as alpha blend (https://github.com/secondlife/viewer/issues/866)
|
||||
- Double-sided previews as single-sided (https://github.com/secondlife/viewer/issues/867)
|
||||
- Material preview inherits some of its lighting from the current environment, and reflections from the default reflection probe (https://github.com/secondlife/viewer/issues/868)
|
||||
|
||||
## 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 https://github.com/secondlife/viewer-issues/issues/72 is fixed.
|
||||
|
||||
#### Symptoms
|
||||
|
||||
When the bug occurs, one or more of following types of objects could randomly disappear in the world, permanently until relog:
|
||||
|
||||
- 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 may not be available in your viewer or region if this feature is still behind a feature flag. It is safe to enable this feature manually by setting, "UIPreviewMaterial" to True in the advanced settings. The setting will persist for the current session.
|
||||
- Region prerequisites: Unknown, but a region with lots of objects in it seems to increase repro rate. The following locations have been known to easily reproduce the bug, as of 2024-02-16:
|
||||
- http://maps.secondlife.com/secondlife/LindenWorld%20B/161/75/47
|
||||
- [secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24](secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24)
|
||||
- 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 https://github.com/secondlife/viewer-issues/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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,9 @@ public:
|
|||
|
||||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
// *HACK
|
||||
void swapFBORefs(LLRenderTarget& other);
|
||||
|
||||
protected:
|
||||
U32 mResX;
|
||||
U32 mResY;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -222,7 +224,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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -593,6 +593,8 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
|
|||
// <FS:Ansariel> FIRE-30431: Keep radio button mode selection in texture selection
|
||||
//sLastPickerMode = mModeSelector->getValue().asInteger();
|
||||
sLastPickerMode = mModeSelector->getSelectedIndex();
|
||||
// *NOTE: Vertex buffer for sphere preview is still cached
|
||||
mGLTFPreview = nullptr;
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -1929,6 +1931,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 )
|
||||
|
|
|
|||
|
|
@ -156,26 +156,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);
|
||||
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;
|
||||
|
||||
virtual void draw();
|
||||
virtual void setVisible( BOOL visible );
|
||||
virtual void setEnabled( BOOL enabled );
|
||||
void draw() override;
|
||||
void setVisible( BOOL visible ) override;
|
||||
void setEnabled( BOOL enabled ) override;
|
||||
|
||||
void setValid(BOOL valid);
|
||||
void onVisibilityChange(BOOL new_visibility) override;
|
||||
|
||||
// LLUICtrl interface
|
||||
virtual void clear();
|
||||
void setValid(BOOL valid);
|
||||
|
||||
// Takes a UUID, wraps get/setImageAssetID
|
||||
virtual void setValue(const LLSD& value);
|
||||
virtual LLSD getValue() const;
|
||||
// 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);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ LLGLSLShader gDeferredPostGammaCorrectProgram;
|
|||
LLGLSLShader gNoPostGammaCorrectProgram;
|
||||
LLGLSLShader gLegacyPostGammaCorrectProgram;
|
||||
LLGLSLShader gExposureProgram;
|
||||
LLGLSLShader gExposureProgramNoFade;
|
||||
LLGLSLShader gLuminanceProgram;
|
||||
LLGLSLShader gFXAAProgram;
|
||||
LLGLSLShader gDeferredPostNoDoFProgram;
|
||||
|
|
@ -997,6 +998,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredCoFProgram.unload();
|
||||
gDeferredDoFCombineProgram.unload();
|
||||
gExposureProgram.unload();
|
||||
gExposureProgramNoFade.unload();
|
||||
gLuminanceProgram.unload();
|
||||
gDeferredPostGammaCorrectProgram.unload();
|
||||
gNoPostGammaCorrectProgram.unload();
|
||||
|
|
@ -2148,6 +2150,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];
|
||||
|
|
@ -2155,6 +2158,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
llassert(success);
|
||||
}
|
||||
|
||||
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";
|
||||
|
|
|
|||
|
|
@ -250,6 +250,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;
|
||||
|
|
|
|||
|
|
@ -6911,11 +6911,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();
|
||||
|
|
@ -6932,51 +6933,67 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
|
|||
|
||||
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
|
||||
|
||||
gExposureProgram.bind();
|
||||
|
||||
S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
|
||||
if (channel > -1)
|
||||
LLGLSLShader* shader;
|
||||
if (use_history)
|
||||
{
|
||||
mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
|
||||
shader = &gExposureProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gExposureProgramNoFade;
|
||||
}
|
||||
|
||||
channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
|
||||
shader->bind();
|
||||
|
||||
S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
|
||||
if (channel > -1)
|
||||
{
|
||||
mLastExposure.bindTexture(0, channel);
|
||||
src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
|
||||
}
|
||||
|
||||
if (use_history)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue