diff options
author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2024-03-06 17:56:16 -0800 |
---|---|---|
committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2024-03-06 17:56:16 -0800 |
commit | 1fc45a50ff15e6f31a4554da83256b7f59b1af15 (patch) | |
tree | b65f155530ebc130443582ca0fedda284833b02d | |
parent | 47cd3cb0ad03c91f118fd20fea8d8924759fd2b7 (diff) |
#681 Add probe blending for mirrors.
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) { |