From ca5e89d741b3618ab1dc681ecb6f75e5884988d7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 8 May 2024 11:28:51 -0700 Subject: Even more mirror fixes. (#1429) #1271 Add support for mirrors that do not have avatars in them. It does this based on if the probe is set to dynamic or not. #1370 More optimization work to reduce GPU utilization. #1058 - Removed sim feature flag that was overriding mirrors enabled flags secondlife/viewer-private#128 - Locally cache the mirror probe #679 Add additional options to the build floater for mirror probes, including descriptions. --- indra/newview/featuretable.txt | 7 ++- indra/newview/featuretable_mac.txt | 11 ++-- indra/newview/llheroprobemanager.cpp | 73 +++++++++++++++------- indra/newview/llheroprobemanager.h | 2 +- indra/newview/llpanelvolume.cpp | 26 +++++--- indra/newview/llviewerregion.cpp | 8 --- indra/newview/llvovolume.cpp | 7 +++ .../newview/skins/default/xui/en/floater_tools.xml | 12 ++-- 8 files changed, 91 insertions(+), 55 deletions(-) (limited to 'indra') diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 3e1e235fcd..8950770172 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -75,6 +75,7 @@ RenderGLMultiThreadedTextures 1 0 RenderGLMultiThreadedMedia 1 1 RenderReflectionProbeResolution 1 128 RenderScreenSpaceReflections 1 1 +RenderMirrors 1 1 // @@ -251,8 +252,8 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 3 -RenderMirrors 1 0 -RenderHeroProbeResolution 1 1024 +RenderMirrors 1 1 +RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 @@ -287,7 +288,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 3 -RenderMirrors 1 0 +RenderMirrors 1 1 RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 2ffefadcc1..8c71235f37 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -74,6 +74,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 2 RenderScreenSpaceReflections 1 1 RenderReflectionProbeLevel 1 3 +RenderMirrors 1 1 // // Low Graphics Settings @@ -249,8 +250,8 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 1 -RenderMirrors 1 0 -RenderHeroProbeResolution 1 1024 +RenderMirrors 1 1 +RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 @@ -285,8 +286,8 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 2 -RenderMirrors 1 0 -RenderHeroProbeResolution 1 1024 +RenderMirrors 1 1 +RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 @@ -322,7 +323,7 @@ RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 3 RenderMirrors 1 1 -RenderHeroProbeResolution 1 2048 +RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index dd29b416fb..55539a49d8 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -113,22 +113,40 @@ void LLHeroProbeManager::update() LLVector4a probe_pos; LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; F32 near_clip = 0.1f; + bool probe_present = false; + LLQuaternion cameraOrientation = LLViewerCamera::instance().getQuaternion(); + LLVector3 cameraDirection = LLVector3::z_axis * cameraOrientation; + if (mHeroVOList.size() > 0) { // Find our nearest hero candidate. - float last_distance = 99999.f; - + float camera_center_distance = 99999.f; for (auto vo : mHeroVOList) { if (vo && !vo->isDead() && vo->mDrawable.notNull()) { float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec(); - if (distance < last_distance) + float center_distance = cameraDirection * (vo->getPositionAgent() - camera_pos); + + if (distance > LLViewerCamera::instance().getFar()) + continue; + + LLVector4a center; + center.load3(vo->getPositionAgent().mV); + LLVector4a size; + + size.load3(vo->getScale().mV); + + bool visible = LLViewerCamera::instance().AABBInFrustum(center, size); + + if (distance < last_distance && center_distance < camera_center_distance && visible) { - mNearestHero = vo; - last_distance = distance; - } + probe_present = true; + mNearestHero = vo; + last_distance = distance; + camera_center_distance = center_distance; + } } else { @@ -136,6 +154,10 @@ void LLHeroProbeManager::update() } } + // Don't even try to do anything if we didn't find a single mirror present. + if (!probe_present) + return; + if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); @@ -152,14 +174,12 @@ void LLHeroProbeManager::update() mCurrentClipPlane.setVec(hero_pos, face_normal); mMirrorPosition = hero_pos; mMirrorNormal = face_normal; - probe_pos.load3(point.mV); - // Collect the list of faces that need updating based upon the camera's rotation. - LLVector3 cam_direction = LLVector3(0, 0, 1) * LLViewerCamera::instance().getQuaternion(); - cam_direction.normalize(); + // Detect visible faces of a cube based on camera direction and distance + // Define the cube faces static LLVector3 cubeFaces[6] = { LLVector3(1, 0, 0), LLVector3(-1, 0, 0), @@ -169,17 +189,21 @@ void LLHeroProbeManager::update() LLVector3(0, 0, -1) }; + // Iterate through each face of the cube for (int i = 0; i < 6; i++) { - float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5)); - - int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); - - // Chances are this is a face that's non-visible to the camera when it's being reflected. - // Set it to 0. It will be skipped below. - if (updateRate == gPipeline.RenderHeroProbeConservativeUpdateMultiplier) + float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])) * 0.6 + 0.4; + + float updateRate; + if (cube_facing < 0.1f) + { updateRate = 0; - + } + else + { + updateRate = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); + } + mFaceUpdateList[i] = updateRate; } } @@ -199,6 +223,7 @@ void LLHeroProbeManager::update() static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); + if (mNearestHero != nullptr) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); // Probe 0 is always our mirror probe. @@ -208,13 +233,16 @@ void LLHeroProbeManager::update() gPipeline.mReflectionMapManager.mRadiancePass = true; mRenderingMirror = true; + + doOcclusion(); + for (U32 j = 0; j < mProbes.size(); j++) { for (U32 i = 0; i < 6; ++i) { if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0) { - updateProbeFace(mProbes[j], i, near_clip); + updateProbeFace(mProbes[j], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); mCurrentProbeUpdateFrame = 0; } } @@ -239,18 +267,17 @@ void LLHeroProbeManager::update() // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip) +void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mHeroProbeRT; - probe->update(mRenderTarget.getWidth(), face, true, near_clip); + probe->update(mRenderTarget.getWidth(), face, is_dynamic, near_clip); gPipeline.mRT = &gPipeline.mMainRT; S32 sourceIdx = mReflectionProbeCount; - // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. sourceIdx += 1; @@ -371,8 +398,6 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) static LLStaticHashedString sSourceIdx("sourceIdx"); { - - // generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) gHeroRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index d5e720e8e8..5df146f2f1 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -116,7 +116,7 @@ private: // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip); + void updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip); void generateRadiance(LLReflectionMap *probe); // list of active reflection maps diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 8d8263448d..91c33b461f 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -424,19 +424,21 @@ void LLPanelVolume::getState( ) volume_type = "Sphere"; } - std::string update_type; - if (volobjp->getReflectionProbeIsDynamic()) + + std::string update_type = "Static"; + + if (volobjp->getReflectionProbeIsDynamic() && !volobjp->getReflectionProbeIsMirror()) { update_type = "Dynamic"; } - else if (volobjp->getReflectionProbeIsMirror()) + else if (volobjp->getReflectionProbeIsMirror() && !volobjp->getReflectionProbeIsDynamic()) { update_type = "Mirror"; } - else - { - update_type = "Static"; + else if (volobjp->getReflectionProbeIsDynamic() && volobjp->getReflectionProbeIsMirror()) + { + update_type = "Dynamic Mirror"; } getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); @@ -1200,6 +1202,7 @@ void LLPanelVolume::onCopyLight() clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance(); clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip(); clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic(); + clipboard["reflection_probe"]["mirror"] = volobjp->getReflectionProbeIsMirror(); } mClipboardParams["light"] = clipboard; @@ -1257,6 +1260,7 @@ void LLPanelVolume::onPasteLight() volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal()); volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal()); volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean()); + volobjp->setReflectionProbeIsMirror(clipboard["reflection_probe"]["mirror"].asBoolean()); } else { @@ -1428,11 +1432,13 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) std::string update_type = self->getChild("Probe Update Type")->getValue().asString(); - volobjp->setReflectionProbeIsDynamic(update_type == "Dynamic"); - volobjp->setReflectionProbeIsMirror(update_type == "Mirror"); + bool is_mirror = update_type.find("Mirror") != std::string::npos; + + volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos); + volobjp->setReflectionProbeIsMirror(is_mirror); - self->getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); - self->getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror"); + self->getChildView("Probe Ambiance")->setEnabled(!is_mirror); + self->getChildView("Probe Near Clip")->setEnabled(!is_mirror); std::string shape_type = self->getChild("Probe Volume Type")->getValue().asString(); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 29dce088f5..61ab2791fb 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2469,14 +2469,6 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) gSavedSettings.setS32("max_texture_dimension_Y", 1024); } - bool mirrors_enabled = false; - if (features.has("MirrorsEnabled")) - { - mirrors_enabled = features["MirrorsEnabled"].asBoolean(); - } - - gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled); - if (features.has("PBRTerrainEnabled")) { bool enabled = features["PBRTerrainEnabled"]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 1b816b88fb..a956814147 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3420,8 +3420,15 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror) { if (param_block->getIsMirror() != is_mirror) { + LL_INFOS() << "Setting reflection probe mirror to " << is_mirror << LL_ENDL; param_block->setIsMirror(is_mirror); parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + + if (!is_mirror) + gPipeline.mHeroProbeManager.unregisterViewerObject(this); + else + gPipeline.mHeroProbeManager.registerViewerObject(this); + return true; } } diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 3ee4a354d4..e43143c8c3 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2549,7 +2549,7 @@ even though the user gets a free copy. follows="left|top" name="Probe Volume Type" tool_tip="Choose the probe influence volume" - width="108"> + width="140"> + tool_tip="Determines how the probe updates. Static updates the slowest and without avatars. Dynamic updates more frequently, with avatars visible in the probes. Mirror (Environment) turns this probe into a realtime planar projected probe that only reflects the environment, but does not calculate ambiance. Mirror (Everything) is similar to Mirror (Environment), but it reflects particles and avatars." + width="140"> + Date: Wed, 8 May 2024 13:40:58 -0700 Subject: Fix for mirrors not functioning properly under water. (#1436) * #1165 Fix for clipping and culling for mirrors under water. --- indra/llimage/tests/llimageworker_test.cpp | 2 +- indra/llprimitive/llgltfmaterial.h | 12 +++++++----- indra/llprimitive/tests/llgltfmaterial_test.cpp | 2 +- indra/newview/pipeline.cpp | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) (limited to 'indra') diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 0a97b739b0..ffcd7d257f 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -98,7 +98,7 @@ namespace tut done = res; *done = false; } - virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) + virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32) { *done = true; } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d14ae6970b..855cb58832 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -122,9 +122,10 @@ public: F32 mRoughnessFactor = 1.f; F32 mAlphaCutoff = 0.5f; - bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; + bool mDoubleSided = false; + // override specific flags for state that can't use off-by-epsilon or UUID hack bool mOverrideDoubleSided = false; bool mOverrideAlphaMode = false; @@ -139,6 +140,11 @@ public: // heightmaps cannot currently be described as finite enclosed // volumes. // See also LLPanelRegionTerrainInfo::validateMaterials + // These fields are local to viewer and are a part of local bitmap support + typedef std::map local_tex_map_t; + local_tex_map_t mTrackingIdToLocalTexture; + +public: // get a UUID based on a hash of this LLGLTFMaterial LLUUID getHash() const; @@ -240,10 +246,6 @@ public: virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); virtual void updateTextureTracking(); - // These fields are local to viewer and are a part of local bitmap support - typedef std::map local_tex_map_t; - local_tex_map_t mTrackingIdToLocalTexture; - protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 88b6fae3a7..b56c9ab4f5 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -143,7 +143,7 @@ namespace tut #if LL_WINDOWS // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) // This test result will vary between compilers, so only test a single platform - ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216); + ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 224); #endif #endif ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 341c9706f8..8b1e46343b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2269,7 +2269,8 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); // static bool LLPipeline::isWaterClip() { - return (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs; + // We always pretend that we're not clipping water when rendering mirrors. + return (gPipeline.mHeroProbeManager.isMirrorPass()) ? false : (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs; } void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) -- cgit v1.2.3 From 9deeec22b7348f56b1d32ab6aff73c59e002ff21 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 8 May 2024 15:26:00 -0400 Subject: Bump up coroutine stack size: saw C00000FD test termination. (cherry picked from commit dc0b3aed4782e4e4835fd6b9d59d1d70b78be4a7) --- indra/llcommon/llcoros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index c13900f74a..8612f9353f 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -123,7 +123,7 @@ LLCoros::LLCoros(): // Previously we used // boost::context::guarded_stack_allocator::default_stacksize(); // empirically this is insufficient. - mStackSize(900*1024), + mStackSize(1024*1024), // mCurrent does NOT own the current CoroData instance -- it simply // points to it. So initialize it with a no-op deleter. mCurrent{ [](CoroData*){} } -- cgit v1.2.3