summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl71
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl10
-rw-r--r--indra/newview/llheroprobemanager.cpp37
-rw-r--r--indra/newview/llreflectionmapmanager.cpp1
4 files changed, 100 insertions, 19 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 4f6e01764a..14d9cf798f 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -686,17 +686,82 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
#if defined(HERO_PROBES)
uniform vec4 clipPlane;
-uniform samplerCubeArray heroProbes;
+
+uniform samplerCubeArray heroProbes;
+
+layout (std140) uniform HeroProbeData
+{
+ mat4 heroBox[1];
+ vec4 heroSphere[1];
+ uint heroShape[1];
+ int heroMipCount;
+ int heroProbeCount;
+};
+
+vec3 boxIntersectHero(vec3 origin, vec3 dir, int i, out float d, float scale)
+{
+ // Intersection with OBB convert to unit box space
+ // Transform in local unit parallax cube space (scaled and rotated)
+ mat4 clipToLocal = heroBox[i];
+
+ vec3 RayLS = mat3(clipToLocal) * dir;
+ vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
+
+ d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z));
+
+ vec3 Unitary = vec3(scale);
+ vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+ vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+ vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+ float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+ // Use Distance in CS directly to recover intersection
+ vec3 IntersectPositionCS = origin + dir * Distance;
+
+ return IntersectPositionCS;
+}
+
+float sphereWeightHero(vec3 pos, vec3 dir, vec3 origin, float r, out float dw)
+{
+ float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - origin;
+ float d2 = max(length(delta), 0.001);
+
+ float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);
+ float w = 1.0 / d2;
+
+ dw = w * atten * max(r, 1.0)*4;
+
+ w *= atten;
+
+ return w;
+}
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
{
float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;
- if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8)
+ float w = 0;
+ float dw = 0;
+ if (heroShape[0] < 1)
+ {
+ float d = 0;
+ boxIntersectHero(pos, norm, 0, d, 1.0);
+
+ w = max(d, 0.001);
+ }
+ else
+ {
+ float r = heroSphere[0].w;
+ //v = sphereIntersect(pos, norm, heroSphere[0].xyz, 4096.0*4096.0);
+
+ w = sphereWeightHero(pos, norm, heroSphere[0].xyz, r, dw);
+ }
+
{
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0)
{
- glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz;
+ glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz * w;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index cc6e16c64f..2f90249169 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -32,16 +32,6 @@ uniform sampler2D specularRect;
uniform sampler2D normalMap;
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
-uniform samplerCubeArray heroProbes;
-
-#if defined(HERO_PROBES)
-layout (std140) uniform HeroProbeData
-{
- vec4 heroPosition[1];
- int heroProbeCount;
-};
-#endif
-
const float M_PI = 3.14159265;
#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index a00b6d6b5d..ee993c6ba1 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -417,7 +417,7 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe)
void LLHeroProbeManager::updateUniforms()
{
- if (!LLPipeline::sReflectionProbesEnabled)
+ if (!gPipeline.RenderMirrors)
{
return;
}
@@ -426,8 +426,11 @@ void LLHeroProbeManager::updateUniforms()
struct HeroProbeData
{
- LLVector4 heroPosition[1];
- GLint heroProbeCount = 1;
+ LLMatrix4 heroBox[1];
+ LLVector4 heroSphere[1];
+ GLint heroShape[1];
+ GLint heroMipCount;
+ GLint heroProbeCount;
};
HeroProbeData hpd;
@@ -437,8 +440,32 @@ void LLHeroProbeManager::updateUniforms()
LLVector4a oa; // scratch space for transformed origin
oa.set(0, 0, 0, 0);
hpd.heroProbeCount = 1;
- modelview.affineTransform(mProbes[0]->mOrigin, oa);
- hpd.heroPosition[0].set(oa.getF32ptr());
+
+ if (mNearestHero != nullptr)
+ {
+ mProbes[0]->mViewerObject = mNearestHero;
+ if (mNearestHero->getReflectionProbeIsBox())
+ {
+ LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+ mProbes[0]->mRadius = s.magVec();
+ }
+ else
+ {
+ mProbes[0]->mRadius = mNearestHero->getScale().mV[0] * 0.5f;
+ }
+
+ modelview.affineTransform(mProbes[0]->mOrigin, oa);
+ hpd.heroShape[0] = 0;
+ if (!mProbes[0]->getBox(hpd.heroBox[0]))
+ {
+ hpd.heroShape[0] = 1;
+ }
+
+ hpd.heroSphere[0].set(oa.getF32ptr());
+ hpd.heroSphere[0].mV[3] = mProbes[0]->mRadius;
+ }
+
+ hpd.heroMipCount = mMipChain.size();
//copy rpd into uniform buffer object
if (mUBO == 0)
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 8506886409..3144260905 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -1016,7 +1016,6 @@ void LLReflectionMapManager::updateUniforms()
{
refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
}
-
}
modelview.affineTransform(refmap->mOrigin, oa);
rpd.refSphere[count].set(oa.getF32ptr());