summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2024-03-06 17:56:16 -0800
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2024-03-06 17:56:16 -0800
commit1fc45a50ff15e6f31a4554da83256b7f59b1af15 (patch)
treeb65f155530ebc130443582ca0fedda284833b02d
parent47cd3cb0ad03c91f118fd20fea8d8924759fd2b7 (diff)
#681 Add probe blending for mirrors.
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl43
-rw-r--r--indra/newview/llheroprobemanager.cpp62
-rw-r--r--indra/newview/llheroprobemanager.h18
-rw-r--r--indra/newview/llreflectionmapmanager.cpp18
6 files changed, 69 insertions, 79 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
index c83a6be85d..57c0a6024f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -133,6 +133,7 @@ uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlpha
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
in vec4[2] vary_coords;
#endif
+in vec3 vary_position;
in vec3 vary_normal;
in vec3 vary_tangent;
flat in float vary_sign;
@@ -140,11 +141,14 @@ in vec4 vary_texcoord0;
in vec4 vary_texcoord1;
vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 position);
float terrain_mix(TerrainMix tm, vec4 tms4);
void main()
{
+ // Make sure we clip the terrain if we're in a mirror.
+ mirrorClip(vary_position);
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
TerrainCoord terrain_texcoord = vary_coords;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
index dbb9404219..489fc26e3f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
@@ -25,6 +25,7 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
in vec3 position;
@@ -42,6 +43,7 @@ out vec3 vary_tangent;
flat out float vary_sign;
out vec4 vary_texcoord0;
out vec4 vary_texcoord1;
+out vec3 vary_position;
// *HACK: tangent_space_transform should use texture_normal_transform, or maybe
// we shouldn't use tangent_space_transform at all. See the call to
@@ -55,6 +57,7 @@ void main()
{
//transform vertex
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
vec3 n = normal_matrix * normal;
vary_vertex_normal = normal;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 257299258e..4f2475b101 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -48,6 +48,7 @@ layout (std140) uniform ReflectionProbes
/// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
// box[3][0..2] - plane thickness
mat4 refBox[MAX_REFMAP_COUNT];
+ mat4 heroBox;
// list of bounding spheres for reflection probes sorted by distance to camera (closest first)
vec4 refSphere[MAX_REFMAP_COUNT];
// extra parameters
@@ -56,6 +57,7 @@ layout (std140) uniform ReflectionProbes
// z - fade in
// w - znear
vec4 refParams[MAX_REFMAP_COUNT];
+ vec4 heroSphere;
// 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
@@ -71,6 +73,10 @@ layout (std140) uniform ReflectionProbes
// number of reflection probes present in refSphere
int refmapCount;
+
+ int heroShape;
+ int heroMipCount;
+ int heroProbeCount;
};
// Inputs
@@ -682,48 +688,37 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
return col[1]+col[0];
}
-
#if defined(HERO_PROBES)
uniform vec4 clipPlane;
-
uniform samplerCubeArray heroProbes;
-layout (std140) uniform HeroProbeData
-{
- mat4 heroBox[1];
- vec4 heroSphere[1];
- uint heroShape[1];
- int heroMipCount;
- int heroProbeCount;
-};
-
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
{
float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;
float w = 0;
float dw = 0;
- if (heroShape[0] < 1)
+ float falloffMult = 10;
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+ if (heroShape < 1)
{
float d = 0;
- boxIntersect(pos, norm, heroBox[0], d, 1.0);
+ boxIntersect(pos, norm, heroBox, d, 1.0);
- w = max(d, 0.001);
+ w = max(d, 0);
}
else
{
- float r = heroSphere[0].w;
+ float r = heroSphere.w;
- w = sphereWeight(pos, norm, heroSphere[0].xyz, r, vec4(1), dw);
- }
-
- {
- vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0)
- {
- glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w);
- }
+ w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw);
}
+
+ clipDist = clipDist * 0.95 + 0.05;
+ clipDist = clamp(clipDist * falloffMult, 0, 1);
+ w = clamp(w * falloffMult * clipDist, 0, 1);
+
+ glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w);
}
#else
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index ee993c6ba1..8f1c1848cc 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -151,6 +151,7 @@ void LLHeroProbeManager::update()
// 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();
static LLVector3 cubeFaces[6] = {
LLVector3(1, 0, 0),
@@ -163,7 +164,7 @@ void LLHeroProbeManager::update()
for (int i = 0; i < 6; i++)
{
- float shouldUpdate = cam_direction * cubeFaces[i] * 0.5 + 0.5;
+ float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5));
int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier);
@@ -215,6 +216,9 @@ void LLHeroProbeManager::update()
mRenderingMirror = false;
gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass;
+
+ mProbes[0]->mViewerObject = mNearestHero;
+ mProbes[0]->autoAdjustOrigin();
}
mCurrentProbeUpdateFrame++;
@@ -424,26 +428,14 @@ void LLHeroProbeManager::updateUniforms()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- struct HeroProbeData
- {
- LLMatrix4 heroBox[1];
- LLVector4 heroSphere[1];
- GLint heroShape[1];
- GLint heroMipCount;
- GLint heroProbeCount;
- };
-
- HeroProbeData hpd;
-
LLMatrix4a modelview;
modelview.loadu(gGLModelView);
LLVector4a oa; // scratch space for transformed origin
oa.set(0, 0, 0, 0);
- hpd.heroProbeCount = 1;
+ mHeroData.heroProbeCount = 1;
if (mNearestHero != nullptr)
{
- mProbes[0]->mViewerObject = mNearestHero;
if (mNearestHero->getReflectionProbeIsBox())
{
LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
@@ -455,44 +447,17 @@ void LLHeroProbeManager::updateUniforms()
}
modelview.affineTransform(mProbes[0]->mOrigin, oa);
- hpd.heroShape[0] = 0;
- if (!mProbes[0]->getBox(hpd.heroBox[0]))
+ mHeroData.heroShape = 0;
+ if (!mProbes[0]->getBox(mHeroData.heroBox))
{
- hpd.heroShape[0] = 1;
+ mHeroData.heroShape = 1;
}
- hpd.heroSphere[0].set(oa.getF32ptr());
- hpd.heroSphere[0].mV[3] = mProbes[0]->mRadius;
+ mHeroData.heroSphere.set(oa.getF32ptr());
+ mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius;
}
- hpd.heroMipCount = mMipChain.size();
-
- //copy rpd into uniform buffer object
- if (mUBO == 0)
- {
- glGenBuffers(1, &mUBO);
- }
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer");
- glBindBuffer(GL_UNIFORM_BUFFER, mUBO);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
- }
-}
-
-void LLHeroProbeManager::setUniforms()
-{
- if (!LLPipeline::sReflectionProbesEnabled)
- {
- return;
- }
-
- if (mUBO == 0)
- {
- updateUniforms();
- }
- glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO);
+ mHeroData.heroMipCount = mMipChain.size();
}
void LLHeroProbeManager::renderDebug()
@@ -581,9 +546,6 @@ void LLHeroProbeManager::cleanup()
mDefaultProbe = nullptr;
mUpdatingProbe = nullptr;
-
- glDeleteBuffers(1, &mUBO);
- mUBO = 0;
mHeroVOList.clear();
mNearestHero = nullptr;
diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h
index e430cae203..04027cd57e 100644
--- a/indra/newview/llheroprobemanager.h
+++ b/indra/newview/llheroprobemanager.h
@@ -38,6 +38,15 @@ class LLViewerObject;
// number of reflection probes to keep in vram
#define LL_MAX_HERO_PROBE_COUNT 2
+struct HeroProbeData
+{
+ LLMatrix4 heroBox;
+ LLVector4 heroSphere;
+ GLint heroShape;
+ GLint heroMipCount;
+ GLint heroProbeCount;
+};
+
class alignas(16) LLHeroProbeManager
{
LL_ALIGN_NEW
@@ -74,16 +83,17 @@ public:
bool isMirrorPass() const { return mRenderingMirror; }
LLVector3 mMirrorPosition;
- LLVector3 mMirrorNormal;
+ LLVector3 mMirrorNormal;
+ HeroProbeData mHeroData;
private:
friend class LLPipeline;
+ friend class LLReflectionMapManager;
// update UBO used for rendering (call only once per render pipe flush)
void updateUniforms();
// bind UBO used for rendering
- void setUniforms();
// render target for cube snapshots
// used to generate mipmaps without doing a copy-to-texture
@@ -109,9 +119,6 @@ private:
// list of active reflection maps
std::vector<LLPointer<LLReflectionMap>> mProbes;
- // handle to UBO
- U32 mUBO = 0;
-
// list of maps being used for rendering
std::vector<LLReflectionMap*> mReflectionMaps;
@@ -141,5 +148,6 @@ private:
std::vector<LLVOVolume*> mHeroVOList;
LLVOVolume* mNearestHero;
+
};
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 3144260905..ce389a5cad 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -906,6 +906,8 @@ void LLReflectionMapManager::updateUniforms()
// the box probe
LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT];
+ LLMatrix4 heroBox;
+
// for sphere probes, origin (xyz) and radius (w) of refmaps in clip space
LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT];
@@ -916,6 +918,8 @@ void LLReflectionMapManager::updateUniforms()
// w - znear
LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT];
+ LLVector4 heroSphere;
+
// indices used by probe:
// [i][0] - cubemap array index for this probe
// [i][1] - index into "refNeighbor" for probes that intersect this probe
@@ -929,6 +933,10 @@ void LLReflectionMapManager::updateUniforms()
GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth
// numbrer of active refmaps
GLint refmapCount;
+
+ GLint heroShape;
+ GLint heroMipCount;
+ GLint heroProbeCount;
};
mReflectionMaps.resize(mReflectionProbeCount);
@@ -1118,6 +1126,16 @@ void LLReflectionMapManager::updateUniforms()
rpd.refmapCount = count;
+ gPipeline.mHeroProbeManager.updateUniforms();
+
+ // Get the hero data.
+
+ rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox;
+ rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere;
+ rpd.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape;
+ rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount;
+ rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount;
+
//copy rpd into uniform buffer object
if (mUBO == 0)
{