summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-05-17 14:32:07 -0500
committerDave Parks <davep@lindenlab.com>2022-05-17 14:32:07 -0500
commit53c692c9597551c9a1ba8eee346432de51d9d22d (patch)
tree556441b5d177bb2489e3794e753b4787e4f357e7
parentb2141e94465998d13ab4b5d894b0edcdad0e8216 (diff)
SL-17416 Quick 'n dirty reflection probe override hack.
-rw-r--r--indra/newview/app_settings/settings.xml14
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl4
-rw-r--r--indra/newview/llreflectionmap.cpp5
-rw-r--r--indra/newview/llreflectionmap.h6
-rw-r--r--indra/newview/llreflectionmapmanager.cpp101
-rw-r--r--indra/newview/llreflectionmapmanager.h14
-rw-r--r--indra/newview/llspatialpartition.cpp69
-rw-r--r--indra/newview/llviewerobject.cpp9
-rw-r--r--indra/newview/llviewerobject.h8
-rw-r--r--indra/newview/llvovolume.cpp20
-rw-r--r--indra/newview/pipeline.cpp7
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)