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)  | 
