diff options
author | Dave Parks <davep@lindenlab.com> | 2022-05-17 14:32:07 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2022-05-17 14:32:07 -0500 |
commit | 53c692c9597551c9a1ba8eee346432de51d9d22d (patch) | |
tree | 556441b5d177bb2489e3794e753b4787e4f357e7 | |
parent | b2141e94465998d13ab4b5d894b0edcdad0e8216 (diff) |
SL-17416 Quick 'n dirty reflection probe override hack.
-rw-r--r-- | indra/newview/app_settings/settings.xml | 14 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl | 4 | ||||
-rw-r--r-- | indra/newview/llreflectionmap.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llreflectionmap.h | 6 | ||||
-rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 101 | ||||
-rw-r--r-- | indra/newview/llreflectionmapmanager.h | 14 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 69 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 8 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 20 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 7 |
11 files changed, 183 insertions, 74 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9f39ea9c8c..aa2f1e9192 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10280,7 +10280,19 @@ <key>Value</key> <real>64</real> </map> - <key>RenderReflectionRes</key> + <key>RenderReflectionProbeTextureHackID</key> + <map> + <key>Comment</key> + <string>HACK -- Any object with a diffuse texture with this ID will be treated as a user override reflection probe. (default is "Violet Info Hub" photo from Library)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>6b186931-05da-eafa-a3ed-a012a33bbfb6</string> + </map> + + <key>RenderReflectionRes</key> <map> <key>Comment</key> <string>Reflection map resolution.</string> diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 3a1287e910..3607c325a4 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -55,6 +55,7 @@ layout (std140, binding = 1) uniform ReflectionProbes // refIndex.x - cubemap channel in reflectionProbes // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index) // refIndex.z - number of neighbors + // refIndex.w - priority ivec4 refIndex[REFMAP_COUNT]; // neighbor list data (refSphere indices, not cubemap array layer) @@ -296,6 +297,7 @@ vec3 sampleRefMap(vec3 pos, vec3 dir, float lod) { int i = probeIndex[idx]; float r = refSphere[i].w; // radius of sphere volume + float p = float(refIndex[i].w); // priority float rr = r*r; // radius squred float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down) vec3 delta = pos.xyz-refSphere[i].xyz; @@ -310,7 +312,7 @@ vec3 sampleRefMap(vec3 pos, vec3 dir, float lod) float atten = 1.0-max(d2-r2, 0.0)/(rr-r2); w *= atten; - + w *= p; // boost weight based on priority col += refcol*w; wsum += w; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 0cf2f22822..c146a888cf 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -194,6 +194,11 @@ void LLReflectionMap::autoAdjustOrigin() } } } + else if (mViewerObject) + { + mOrigin.load3(mViewerObject->getPositionAgent().mV); + mRadius = mViewerObject->getScale().mV[0]; + } } bool LLReflectionMap::intersects(LLReflectionMap* other) diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index ed1c2680b6..305f33af4b 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -30,6 +30,7 @@ #include "llmemory.h" class LLSpatialGroup; +class LLViewerObject; class alignas(16) LLReflectionMap : public LLRefCount { @@ -80,7 +81,12 @@ public: // set of any LLReflectionMaps that intersect this map (maintained by LLReflectionMapManager std::vector<LLReflectionMap*> mNeighbors; + // spatial group this probe is tracking (if any) LLSpatialGroup* mGroup = nullptr; + + // viewer object this probe is tracking (if any) + LLViewerObject* mViewerObject = nullptr; + bool mDirty = true; }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index a6b704d57d..53c4857b0f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -274,6 +274,28 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr return nullptr; } +LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj) +{ + llassert(vobj != nullptr); + + LLReflectionMap* probe = new LLReflectionMap(); + probe->mViewerObject = vobj; + probe->mOrigin.load3(vobj->getPositionAgent().mV); + probe->mDirty = true; + + if (gCubeSnapshot) + { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update + mCreateList.push_back(probe); + } + else + { + mProbes.push_back(probe); + } + + return probe; +} + + S32 LLReflectionMapManager::allocateCubeIndex() { for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i) @@ -513,6 +535,7 @@ void LLReflectionMapManager::setUniforms() rpd.refIndex[count][0] = refmap->mCubeIndex; llassert(nc % 4 == 0); rpd.refIndex[count][1] = nc / 4; + rpd.refIndex[count][3] = refmap->mViewerObject ? 10 : 1; S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { @@ -574,3 +597,81 @@ void LLReflectionMapManager::setUniforms() glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); } + + +void renderReflectionProbe(LLReflectionMap* probe) +{ + + F32* po = probe->mOrigin.getF32ptr(); + + //draw orange line from probe to neighbors + gGL.flush(); + gGL.diffuseColor4f(1, 0.5f, 0, 1); + gGL.begin(gGL.LINES); + for (auto& neighbor : probe->mNeighbors) + { + gGL.vertex3fv(po); + gGL.vertex3fv(neighbor->mOrigin.getF32ptr()); + } + gGL.end(); + gGL.flush(); + +#if 0 + LLSpatialGroup* group = probe->mGroup; + if (group) + { // draw lines from corners of object aabb to reflection probe + + const LLVector4a* bounds = group->getBounds(); + LLVector4a o = bounds[0]; + + gGL.flush(); + gGL.diffuseColor4f(0, 0, 1, 1); + F32* c = o.getF32ptr(); + + const F32* bc = bounds[0].getF32ptr(); + const F32* bs = bounds[1].getF32ptr(); + + // daaw blue lines from corners to center of node + gGL.begin(gGL.LINES); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]); + + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]); + gGL.vertex3fv(c); + gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]); + gGL.end(); + + //draw yellow line from center of node to reflection probe origin + gGL.flush(); + gGL.diffuseColor4f(1, 1, 0, 1); + gGL.begin(gGL.LINES); + gGL.vertex3fv(c); + gGL.vertex3fv(po); + gGL.end(); + gGL.flush(); + } +#endif +} + +void LLReflectionMapManager::renderDebug() +{ + gDebugProgram.bind(); + + for (auto& probe : mProbes) + { + renderReflectionProbe(probe); + } + + gDebugProgram.unbind(); +} diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 24ac40b264..f7feabbf66 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -31,6 +31,7 @@ #include "llcubemaparray.h" class LLSpatialGroup; +class LLViewerObject; // number of reflection probes to keep in vram #define LL_REFLECTION_PROBE_COUNT 256 @@ -38,6 +39,9 @@ class LLSpatialGroup; // reflection probe resolution #define LL_REFLECTION_PROBE_RESOLUTION 256 +// reflection probe mininum scale +#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; + class alignas(16) LLReflectionMapManager { LL_ALIGN_NEW @@ -63,12 +67,21 @@ public: // If spatial group should receive a Reflection Probe, will create one for the specified spatial group LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group); + // presently hacked into LLViewerObject::setTE + // Used by LLViewerObjects that are Reflection Probes + // Guaranteed to not return null + LLReflectionMap* registerViewerObject(LLViewerObject* vobj); + // force an update of all probes void rebuild(); // called on region crossing to "shift" probes into new coordinate frame void shift(const LLVector4a& offset); + // debug display, called from llspatialpartition if reflection + // probe debug display is active + void renderDebug(); + private: friend class LLPipeline; @@ -82,6 +95,7 @@ private: // update the neighbors of the given probe void updateNeighbors(LLReflectionMap* probe); + // update UBO used for rendering void setUniforms(); // render target for cube snapshots diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 642b1c964f..b6bd07085b 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1766,65 +1766,6 @@ void renderOctree(LLSpatialGroup* group) // drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); } -void renderReflectionProbes(LLSpatialGroup* group) -{ - if (group->mReflectionProbe) - { // draw lines from corners of object aabb to reflection probe - - const LLVector4a* bounds = group->getBounds(); - LLVector4a o = bounds[0]; - - gGL.flush(); - gGL.diffuseColor4f(0, 0, 1, 1); - F32* c = o.getF32ptr(); - - const F32* bc = bounds[0].getF32ptr(); - const F32* bs = bounds[1].getF32ptr(); - - // daaw blue lines from corners to center of node - gGL.begin(gGL.LINES); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]); - - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]); - gGL.vertex3fv(c); - gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]); - gGL.end(); - - F32* po = group->mReflectionProbe->mOrigin.getF32ptr(); - //draw yellow line from center of node to reflection probe origin - gGL.flush(); - gGL.diffuseColor4f(1, 1, 0, 1); - gGL.begin(gGL.LINES); - gGL.vertex3fv(c); - gGL.vertex3fv(po); - gGL.end(); - gGL.flush(); - - //draw orange line from probe to neighbors - gGL.flush(); - gGL.diffuseColor4f(1, 0.5f, 0, 1); - gGL.begin(gGL.LINES); - for (auto& probe : group->mReflectionProbe->mNeighbors) - { - gGL.vertex3fv(po); - gGL.vertex3fv(probe->mOrigin.getF32ptr()); - } - gGL.end(); - gGL.flush(); - } -} std::set<LLSpatialGroup*> visible_selected_groups; void renderVisibility(LLSpatialGroup* group, LLCamera* camera) @@ -3371,12 +3312,6 @@ public: stop_glerror(); } - //draw reflection probes and links between them - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES)) - { - renderReflectionProbes(group); - } - //render visibility wireframe if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { @@ -3791,8 +3726,7 @@ void LLSpatialPartition::renderDebug() //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | - LLPipeline::RENDER_DEBUG_TEXEL_DENSITY | - LLPipeline::RENDER_DEBUG_REFLECTION_PROBES)) + LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) { return; } @@ -3826,7 +3760,6 @@ void LLSpatialPartition::renderDebug() LLOctreeRenderNonOccluded render_debug(camera); render_debug.traverse(mOctree); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 16b294b8e9..6ecf9dd0c4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -343,6 +343,13 @@ LLViewerObject::~LLViewerObject() { deleteTEImages(); + // unhook from reflection probe manager + if (mReflectionProbe.notNull()) + { + mReflectionProbe->mViewerObject = nullptr; + mReflectionProbe = nullptr; + } + if(mInventory) { mInventory->clear(); // will deref and delete entries @@ -4862,7 +4869,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) LLPrimitive::setTE(te, texture_entry); - const LLUUID& image_id = getTE(te)->getID(); + const LLUUID& image_id = getTE(te)->getID(); LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bef8e3e7e3..5b6d24887c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -43,6 +43,7 @@ #include "llvertexbuffer.h" #include "llbbox.h" #include "llrigginginfo.h" +#include "llreflectionmap.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -845,7 +846,7 @@ protected: F32 mLinksetCost; F32 mPhysicsCost; F32 mLinksetPhysicsCost; - + bool mCostStale; mutable bool mPhysicsShapeUnknown; @@ -904,6 +905,11 @@ private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; BOOL mLastUpdateCached; + +public: + // reflection probe state + bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager + LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed }; /////////////////// diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ef6ee4b910..784c0350fc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2157,7 +2157,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes) return ; } -//virtual +//virtual void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) { BOOL changed = (mTEImages[index] != imagep); @@ -5690,6 +5690,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = false; #endif + // HACK - make this object a Reflection Probe if a certain UUID is detected + static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); + if (facep->getTextureEntry()->getID() == LLUUID(reflection_probe_id)) + { + if (!vobj->mIsReflectionProbe) + { + vobj->mIsReflectionProbe = true; + vobj->mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(vobj); + } + } + else + { + // not a refleciton probe any more + vobj->mIsReflectionProbe = false; + vobj->mReflectionProbe = nullptr; + } + // END HACK + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5eb9817fc4..4cf8157623 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -5150,7 +5150,6 @@ void LLPipeline::renderDebug() glPointSize(1.f); } - // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5204,6 +5203,12 @@ void LLPipeline::renderDebug() visible_selected_groups.clear(); + //draw reflection probes and links between them + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only) + { + mReflectionMapManager.renderDebug(); + } + gUIProgram.bind(); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) |