summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-06-02 18:42:38 -0500
committerDave Parks <davep@lindenlab.com>2022-06-02 18:42:38 -0500
commit220afbcda0961df86ad08bbd51d96b8c868b2e62 (patch)
tree066d6508daa552a220c931931f13796754b6c261 /indra
parent3b3d3d88d1755ac08c7d22721fa3fe1657f7c5fd (diff)
SL-17285 Add proper reflection probe support to LLVOVolume, LLPrimitive, and LLPanelVolume
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/llprimitive.cpp95
-rw-r--r--indra/llprimitive/llprimitive.h44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl21
-rw-r--r--indra/newview/llpanelvolume.cpp100
-rw-r--r--indra/newview/llpanelvolume.h3
-rw-r--r--indra/newview/llreflectionmap.cpp51
-rw-r--r--indra/newview/llreflectionmap.h10
-rw-r--r--indra/newview/llreflectionmapmanager.cpp25
-rw-r--r--indra/newview/lltexturefetch.cpp1
-rw-r--r--indra/newview/llviewerdisplay.cpp1
-rw-r--r--indra/newview/llviewerobject.cpp5
-rw-r--r--indra/newview/llviewerwindow.cpp3
-rw-r--r--indra/newview/llviewerwindow.h4
-rw-r--r--indra/newview/llvovolume.cpp157
-rw-r--r--indra/newview/llvovolume.h14
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml58
16 files changed, 519 insertions, 73 deletions
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index c46e5fb3c5..87a78eb447 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -81,6 +81,14 @@ const F32 LIGHT_MIN_CUTOFF = 0.0f;
const F32 LIGHT_DEFAULT_CUTOFF = 0.0f;
const F32 LIGHT_MAX_CUTOFF = 180.f;
+// reflection probes
+const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f;
+const F32 REFLECTION_PROBE_MAX_AMBIANCE = 1.f;
+const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f;
+const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f;
+const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f;
+const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f;
+
// "Tension" => [0,10], increments of 0.1
const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f;
const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f;
@@ -1811,6 +1819,93 @@ bool LLLightParams::fromLLSD(LLSD& sd)
//============================================================================
+LLReflectionProbeParams::LLReflectionProbeParams()
+{
+ mType = PARAMS_REFLECTION_PROBE;
+}
+
+BOOL LLReflectionProbeParams::pack(LLDataPacker& dp) const
+{
+ dp.packF32(mAmbiance, "ambiance");
+ dp.packF32(mClipDistance, "clip_distance");
+ dp.packU8(mVolumeType, "volume_type");
+ return TRUE;
+}
+
+BOOL LLReflectionProbeParams::unpack(LLDataPacker& dp)
+{
+ F32 ambiance;
+ F32 clip_distance;
+ U8 volume_type;
+
+ dp.unpackF32(ambiance, "ambiance");
+ setAmbiance(ambiance);
+
+ dp.unpackF32(clip_distance, "clip_distance");
+ setClipDistance(clip_distance);
+
+ dp.unpackU8(volume_type, "volume_type");
+ setVolumeType((EInfluenceVolumeType)volume_type);
+
+ return TRUE;
+}
+
+bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
+{
+ if (data.mType != PARAMS_REFLECTION_PROBE)
+ {
+ return false;
+ }
+ const LLReflectionProbeParams* param = (const LLReflectionProbeParams*)&data;
+ if (param->mAmbiance != mAmbiance)
+ {
+ return false;
+ }
+ if (param->mClipDistance != mClipDistance)
+ {
+ return false;
+ }
+ if (param->mVolumeType != mVolumeType)
+ {
+ return false;
+ }
+ return true;
+}
+
+void LLReflectionProbeParams::copy(const LLNetworkData& data)
+{
+ const LLReflectionProbeParams* param = (LLReflectionProbeParams*)&data;
+ mType = param->mType;
+ mAmbiance = param->mAmbiance;
+ mClipDistance = param->mClipDistance;
+ mVolumeType = param->mVolumeType;
+}
+
+LLSD LLReflectionProbeParams::asLLSD() const
+{
+ LLSD sd;
+ sd["ambiance"] = getAmbiance();
+ sd["clip_distance"] = getClipDistance();
+ sd["volume_type"] = getVolumeType();
+ return sd;
+}
+
+bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
+{
+ if (!sd.has("ambiance") ||
+ !sd.has("clip_distance") ||
+ !sd.has("volume_type"))
+ {
+ return false;
+ }
+
+ setAmbiance((F32)sd["ambiance"].asReal());
+ setClipDistance((F32)sd["clip_distance"].asReal());
+ setVolumeType((EInfluenceVolumeType)sd["volume_type"].asInteger());
+
+ return true;
+}
+//============================================================================
LLFlexibleObjectData::LLFlexibleObjectData()
{
mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index e23ddd2916..2215133e16 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -108,6 +108,7 @@ public:
PARAMS_MESH = 0x60,
PARAMS_EXTENDED_MESH = 0x70,
PARAMS_RENDER_MATERIAL = 0x80,
+ PARAMS_REFLECTION_PROBE = 0x90,
};
public:
@@ -171,6 +172,49 @@ public:
F32 getCutoff() const { return mCutoff; }
};
+extern const F32 REFLECTION_PROBE_MIN_AMBIANCE;
+extern const F32 REFLECTION_PROBE_MAX_AMBIANCE;
+extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE;
+extern const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE;
+extern const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE;
+extern const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
+
+class LLReflectionProbeParams : public LLNetworkData
+{
+public:
+ enum EInfluenceVolumeType : U8
+ {
+ VOLUME_TYPE_SPHERE = 0, // use a sphere influence volume
+ VOLUME_TYPE_BOX = 1, // use a box influence volume
+ DEFAULT_VOLUME_TYPE = VOLUME_TYPE_SPHERE
+ };
+
+protected:
+ F32 mAmbiance = REFLECTION_PROBE_DEFAULT_AMBIANCE;
+ F32 mClipDistance = REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE;
+ EInfluenceVolumeType mVolumeType = DEFAULT_VOLUME_TYPE;
+
+public:
+ LLReflectionProbeParams();
+ /*virtual*/ BOOL pack(LLDataPacker& dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker& dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+ // LLSD implementations here are provided by Eddy Stryker.
+ // NOTE: there are currently unused in protocols
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(LLSD& sd);
+
+ void setAmbiance(F32 ambiance) { mAmbiance = llclamp(ambiance, REFLECTION_PROBE_MIN_AMBIANCE, REFLECTION_PROBE_MAX_AMBIANCE); }
+ void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
+ void setVolumeType(EInfluenceVolumeType type) { mVolumeType = llclamp(type, VOLUME_TYPE_SPHERE, VOLUME_TYPE_BOX); }
+
+ F32 getAmbiance() const { return mAmbiance; }
+ F32 getClipDistance() const { return mClipDistance; }
+ EInfluenceVolumeType getVolumeType() const { return mVolumeType; }
+};
+
//-------------------------------------------------
// This structure is also used in the part of the
// code that creates new flexible objects.
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 8c1323ba1a..eb9d3f485b 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -1,5 +1,5 @@
/**
- * @file class2/deferred/reflectionProbeF.glsl
+ * @file class3/deferred/reflectionProbeF.glsl
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -42,6 +42,8 @@ layout (std140, binding = 1) uniform ReflectionProbes
mat4 refBox[REFMAP_COUNT];
// list of bounding spheres for reflection probes sorted by distance to camera (closest first)
vec4 refSphere[REFMAP_COUNT];
+ // extra parameters (currently only .x used for probe ambiance)
+ vec4 refParams[REFMAP_COUNT];
// index of cube map in reflectionProbes for a corresponding reflection probe
// e.g. cube map channel of refSphere[2] is stored in refIndex[2]
// refIndex.x - cubemap channel in reflectionProbes
@@ -55,9 +57,6 @@ layout (std140, binding = 1) uniform ReflectionProbes
// number of reflection probes present in refSphere
int refmapCount;
-
- // intensity of ambient light from reflection probes
- float reflectionAmbiance;
};
// Inputs
@@ -335,7 +334,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
}
}
-vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
{
float wsum = 0.0;
vec3 col = vec3(0,0,0);
@@ -360,7 +359,7 @@ vec3 sampleProbes(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;
+ col += refcol*w*max(minweight, refParams[i].x);
wsum += w;
}
@@ -383,7 +382,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
float w = 1.0/d2;
w *= w;
- col += refcol*w;
+ col += refcol*w*max(minweight, refParams[i].x);
wsum += w;
}
}
@@ -399,7 +398,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod)
{
- vec3 col = sampleProbes(pos, dir, lod);
+ vec3 col = sampleProbes(pos, dir, lod, 0.f);
//desaturate
vec3 hcol = col *0.5;
@@ -413,7 +412,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod)
col *= 0.333333;
- return col*reflectionAmbiance;
+ return col;
}
@@ -445,12 +444,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
if (glossiness > 0.0)
{
float lod = (1.0-glossiness)*reflection_lods;
- glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod, 1.f);
}
if (envIntensity > 0.0)
{
- legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, 1.f);
}
}
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 89c558e4f8..e7bbe266e5 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -145,6 +145,16 @@ BOOL LLPanelVolume::postBuild()
getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
}
+ // REFLECTION PROBE Parameters
+ {
+ childSetCommitCallback("Reflection Probe Checkbox Ctrl", onCommitIsReflectionProbe, this);
+ childSetCommitCallback("Probe Shape Type Combo Ctrl", onCommitProbe, this);
+ childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
+ childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
+
+
+ }
+
// PHYSICS Parameters
{
// PhysicsShapeType combobox
@@ -360,6 +370,40 @@ void LLPanelVolume::getState( )
getChildView("Light Ambiance")->setEnabled(false);
}
+ // Reflection Probe
+ BOOL is_probe = volobjp && volobjp->getIsReflectionProbe();
+ getChild<LLUICtrl>("Reflection Probe Checkbox Ctrl")->setValue(is_probe);
+ getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
+
+ bool probe_enabled = is_probe && editable && single_volume;
+
+ getChildView("Probe Volume Type Ctrl")->setEnabled(probe_enabled);
+ getChildView("Probe Ambiance")->setEnabled(probe_enabled);
+ getChildView("Probe Near Clip")->setEnabled(probe_enabled);
+
+ if (!probe_enabled)
+ {
+ getChild<LLComboBox>("Probe Volume Type Ctrl", true)->clear();
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
+ }
+ else
+ {
+ std::string volume_type;
+ if (volobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX)
+ {
+ volume_type = "Box";
+ }
+ else
+ {
+ volume_type = "Sphere";
+ }
+
+ getChild<LLComboBox>("Probe Volume Type Ctrl", true)->setValue(volume_type);
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
+ }
+
// Animated Mesh
BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
@@ -647,6 +691,10 @@ void LLPanelVolume::clearCtrls()
getChildView("Light Radius")->setEnabled(false);
getChildView("Light Falloff")->setEnabled(false);
+ getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(false);;
+ getChildView("Probe Volume Type Ctrl")->setEnabled(false);
+ getChildView("Probe Ambiance")->setEnabled(false);
+ getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
getChildView("FlexNumSections")->setEnabled(false);
@@ -684,6 +732,20 @@ void LLPanelVolume::sendIsLight()
LL_INFOS() << "update light sent" << LL_ENDL;
}
+void LLPanelVolume::sendIsReflectionProbe()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ BOOL value = getChild<LLUICtrl>("Reflection Probe Checkbox Ctrl")->getValue();
+ volobjp->setIsReflectionProbe(value);
+ LL_INFOS() << "update reflection probe sent" << LL_ENDL;
+}
+
void LLPanelVolume::sendIsFlexible()
{
LLViewerObject* objectp = mObject;
@@ -927,6 +989,35 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
}
+//static
+void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+
+ volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
+ volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
+
+ std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type Ctrl")->getValue().asString();
+ LLReflectionProbeParams::EInfluenceVolumeType volume_type = LLReflectionProbeParams::DEFAULT_VOLUME_TYPE;
+
+ if (shape_type == "Sphere")
+ {
+ volume_type = LLReflectionProbeParams::VOLUME_TYPE_SPHERE;
+ }
+ else if (shape_type == "Box")
+ {
+ volume_type = LLReflectionProbeParams::VOLUME_TYPE_BOX;
+ }
+ volobjp->setReflectionProbeVolumeType(volume_type);
+}
+
// static
void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
{
@@ -950,6 +1041,15 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
//----------------------------------------------------------------------------
// static
+void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ self->sendIsReflectionProbe();
+}
+
+//----------------------------------------------------------------------------
+
+// static
void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
{
LLPanelVolume* self = (LLPanelVolume*) userdata;
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 6e49ccb742..16d9ac292d 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -56,12 +56,15 @@ public:
void refresh();
void sendIsLight();
+ void sendIsReflectionProbe();
void sendIsFlexible();
static bool precommitValidate(const LLSD& data);
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
+ static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata);
+ static void onCommitProbe(LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 54a627efd4..f8a2020ccb 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -35,7 +35,6 @@ extern F32SecondsImplicit gFrameTimeSeconds;
LLReflectionMap::LLReflectionMap()
{
- mLastUpdateTime = gFrameTimeSeconds;
}
void LLReflectionMap::update(U32 resolution, U32 face)
@@ -52,7 +51,7 @@ void LLReflectionMap::update(U32 resolution, U32 face)
{
resolution /= 2;
}
- gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face);
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip());
}
bool LLReflectionMap::shouldUpdate()
@@ -215,6 +214,35 @@ bool LLReflectionMap::intersects(LLReflectionMap* other)
return dist < r2;
}
+extern LLControlGroup gSavedSettings;
+
+F32 LLReflectionMap::getAmbiance()
+{
+ static LLCachedControl<F32> minimum_ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f);
+
+ F32 ret = 0.f;
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ }
+
+ return llmax(ret, minimum_ambiance());
+}
+
+F32 LLReflectionMap::getNearClip()
+{
+ const F32 MINIMUM_NEAR_CLIP = 0.1f;
+
+ F32 ret = 0.f;
+
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip();
+ }
+
+ return llmax(ret, MINIMUM_NEAR_CLIP);
+}
+
bool LLReflectionMap::getBox(LLMatrix4& box)
{
if (mViewerObject)
@@ -224,25 +252,8 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
{
LLVOVolume* vobjp = (LLVOVolume*)mViewerObject;
- U8 profile = volume->getProfileType();
- U8 path = volume->getPathType();
-
- if (profile == LL_PCODE_PROFILE_SQUARE &&
- path == LL_PCODE_PATH_LINE)
+ if (vobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX)
{
- // nope
- /*box = vobjp->getRelativeXform();
- box *= vobjp->mDrawable->getRenderMatrix();
- LLMatrix4 modelview(gGLModelView);
- box *= modelview;
- box.invert();*/
-
- // nope
- /*box = LLMatrix4(gGLModelView);
- box *= vobjp->mDrawable->getRenderMatrix();
- box *= vobjp->getRelativeXform();
- box.invert();*/
-
glh::matrix4f mv(gGLModelView);
glh::matrix4f scale;
LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index 4f0f124118..a358bf5fdf 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -55,9 +55,15 @@ public:
// return true if given Reflection Map's influence volume intersect's with this one's
bool intersects(LLReflectionMap* other);
+ // Get the ambiance value to use for this probe
+ F32 getAmbiance();
+
+ // Get the near clip plane distance to use for this probe
+ F32 getNearClip();
+
// get the encoded bounding box of this probe's influence volume
- // will only return a box if this probe has a volume with a square
- // profile and a linear path
+ // will only return a box if this probe is associated with a VOVolume
+ // with its reflection probe influence volume to to VOLUME_TYPE_BOX
// return false if no bounding box (treat as sphere influence volume)
bool getBox(LLMatrix4& box);
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 34055653d4..60396b6c60 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -127,18 +127,12 @@ void LLReflectionMapManager::update()
camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
// process kill list
- for (int i = 0; i < mProbes.size(); )
+ for (auto& probe : mKillList)
{
- auto& iter = std::find(mKillList.begin(), mKillList.end(), mProbes[i]);
- if (iter != mKillList.end())
+ auto& iter = std::find(mProbes.begin(), mProbes.end(), probe);
+ if (iter != mProbes.end())
{
- deleteProbe(i);
- mProbes.erase(mProbes.begin() + i);
- mKillList.erase(iter);
- }
- else
- {
- ++i;
+ deleteProbe(iter - mProbes.begin());
}
}
@@ -275,7 +269,7 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr
{
OctreeNode* node = group->getOctreeNode();
F32 size = node->getSize().getF32ptr()[0];
- if (size >= 7.f && size <= 17.f)
+ if (size >= 15.f && size <= 17.f)
{
return addProbe(group);
}
@@ -514,15 +508,15 @@ void LLReflectionMapManager::updateUniforms()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// structure for packing uniform buffer object
- // see class2/deferred/softenLightF.glsl
+ // see class3/deferred/reflectionProbeF.glsl
struct ReflectionProbeData
{
LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed
LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space
+ LLVector4 refParams[LL_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance)
GLint refIndex[LL_REFLECTION_PROBE_COUNT][4];
GLint refNeighbor[4096];
GLint refmapCount;
- GLfloat reflectionAmbiance;
};
mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT);
@@ -530,9 +524,6 @@ void LLReflectionMapManager::updateUniforms()
ReflectionProbeData rpd;
- static LLCachedControl<F32> ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f);
- rpd.reflectionAmbiance = ambiance;
-
// load modelview matrix into matrix 4a
LLMatrix4a modelview;
modelview.loadu(gGLModelView);
@@ -573,6 +564,8 @@ void LLReflectionMapManager::updateUniforms()
rpd.refIndex[count][3] = -rpd.refIndex[count][3];
}
+ rpd.refParams[count].set(refmap->getAmbiance(), 0.f, 0.f, 0.f);
+
S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
{
//LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors");
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 0edaf40c66..35e4bb03ac 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -3400,6 +3400,7 @@ void LLTextureFetch::sendRequestListToSimulators()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
S32 packet = req->mLastPacket + 1;
+ LL_INFOS() << req->mID << ": " << req->mImagePriority << LL_ENDL;
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 1b8e53e667..6d98d9b10e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1082,7 +1082,6 @@ void display_cube_face()
gPipeline.mBackfaceCull = TRUE;
- LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);
gViewerWindow->setup3DViewport();
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 6ecf9dd0c4..732beab448 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -6029,6 +6029,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLRenderMaterialParams();
break;
}
+ case LLNetworkData::PARAMS_REFLECTION_PROBE:
+ {
+ new_block = new LLReflectionProbeParams();
+ break;
+ }
default:
{
LL_INFOS() << "Unknown param type." << LL_ENDL;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index a6597e3233..6a60671040 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -5270,7 +5270,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
void display_cube_face();
-BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face)
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip)
{
// NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
@@ -5299,6 +5299,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea
camera->setView(F_PI_BY_TWO);
camera->yaw(0.0);
camera->setOrigin(origin);
+ camera->setNear(near_clip);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ac7f8b2e39..c9cf7da8c7 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -368,7 +368,9 @@ public:
// origin - vantage point to take the snapshot from
// cubearray - cubemap array for storing the results
// index - cube index in the array to use (cube index, not face-layer)
- BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face);
+ // face - which cube face to update
+ // near_clip - near clip setting to use
+ BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip);
// special implementation of simpleSnapshot for reflection maps
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 784c0350fc..6aef9ee7c0 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -985,7 +985,12 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
// Add it to the pipeline mLightSet
gPipeline.setLight(mDrawable, TRUE);
}
-
+
+ if (getIsReflectionProbe())
+ {
+ updateReflectionProbePtr();
+ }
+
updateRadius();
bool force_update = true; // avoid non-alpha mDistance update being optimized away
mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
@@ -3496,6 +3501,121 @@ F32 LLVOVolume::getLightCutoff() const
}
}
+void LLVOVolume::setIsReflectionProbe(BOOL is_probe)
+{
+ BOOL was_probe = getIsReflectionProbe();
+ if (is_probe != was_probe)
+ {
+ if (is_probe)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, FALSE, true);
+ }
+ }
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getAmbiance() != ambiance)
+ {
+ param_block->setAmbiance(ambiance);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getClipDistance() != near_clip)
+ {
+ param_block->setClipDistance(near_clip);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getVolumeType() != volume_type)
+ {
+ param_block->setVolumeType(volume_type);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+
+BOOL LLVOVolume::getIsReflectionProbe() const
+{
+ // HACK - make this object a Reflection Probe if a certain UUID is detected
+ static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", "");
+ LLUUID probe_id(reflection_probe_id);
+
+ for (U8 i = 0; i < getNumTEs(); ++i)
+ {
+ if (getTE(i)->getID() == probe_id)
+ {
+ return true;
+ }
+ }
+ // END HACK
+
+ return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+}
+
+F32 LLVOVolume::getReflectionProbeAmbiance() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getAmbiance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeNearClip() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getClipDistance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+LLReflectionProbeParams::EInfluenceVolumeType LLVOVolume::getReflectionProbeVolumeType() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getVolumeType();
+ }
+ else
+ {
+ return LLReflectionProbeParams::DEFAULT_VOLUME_TYPE;
+ }
+}
+
U32 LLVOVolume::getVolumeInterfaceID() const
{
if (mVolumeImpl)
@@ -4381,6 +4501,23 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
gPipeline.setLight(mDrawable, is_light);
}
}
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::updateReflectionProbePtr()
+{
+ if (getIsReflectionProbe())
+ {
+ if (mReflectionProbe.isNull())
+ {
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
+ }
+ }
+ else if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe = nullptr;
+ }
}
void LLVOVolume::setSelected(BOOL sel)
@@ -5690,24 +5827,6 @@ 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/llvovolume.h b/indra/newview/llvovolume.h
index 4cb7a5481c..93a10781c2 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -178,6 +178,9 @@ public:
/*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
/*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+ // update mReflectionProbe based on isReflectionProbe()
+ void updateReflectionProbePtr();
+
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
@@ -281,6 +284,17 @@ public:
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
+ // Reflection Probes
+ void setIsReflectionProbe(BOOL is_probe);
+ void setReflectionProbeAmbiance(F32 ambiance);
+ void setReflectionProbeNearClip(F32 near_clip);
+ void setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type);
+
+ BOOL getIsReflectionProbe() const;
+ F32 getReflectionProbeAmbiance() const;
+ F32 getReflectionProbeNearClip() const;
+ LLReflectionProbeParams::EInfluenceVolumeType getReflectionProbeVolumeType() const;
+
// Flexible Objects
U32 getVolumeInterfaceID() const;
virtual BOOL isFlexible() const;
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 44bdcd86f9..ae4eb64264 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2353,7 +2353,7 @@ even though the user gets a free copy.
layout="topleft"
left="10"
name="Light Intensity"
- top_pad="3"
+ top_delta="32"
width="128" />
<spinner bottom_delta="0"
decimal_digits="3"
@@ -2420,7 +2420,61 @@ even though the user gets a free copy.
mouse_opaque="true"
name="Light Ambiance"
width="120" />
- <text
+ <check_box
+ height="16"
+ label="Reflection Probe"
+ layout="topleft"
+ left="10"
+ name="Reflection Probe Checkbox Ctrl"
+ tool_tip="Adjusts how objects within this volume receive reflections when PBR is enabled"
+ top_pad="15"
+ width="60" />
+ <combo_box
+ height="19"
+ top_delta="0"
+ left="144"
+ follows="left|top"
+ name="Probe Volume Type Ctrl"
+ tool_tip="Choose the probe influence volume"
+ width="108">
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Box"
+ name="Box"
+ value="Box"/>
+ </combo_box>
+ <spinner bottom_delta="19"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Ambiance"
+ label_width="55"
+ left="10"
+ max_val="1"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Ambiance"
+ width="120" />
+ <spinner bottom_delta="0"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Near Clip"
+ label_width="55"
+ left="144"
+ max_val="1024"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Near Clip"
+ width="120" />
+ <text
type="string"
length="1"
follows="left|top"