diff options
| -rw-r--r-- | indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl | 140 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 33 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.h | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerregion.cpp | 2 | 
4 files changed, 82 insertions, 95 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 925398671c..6d3bff0562 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -114,8 +114,7 @@ bool shouldSampleProbe(int i, vec3 pos)  void preProbeSample(vec3 pos)  {      // TODO: make some sort of structure that reduces the number of distance checks - -    for (int i = 0; i < refmapCount; ++i) +    for (int i = 1; i < refmapCount; ++i)      {          // found an influencing probe          if (shouldSampleProbe(i, pos)) @@ -200,6 +199,12 @@ void preProbeSample(vec3 pos)              }          }      } + +    if (probeInfluences == 0) +    { // probe at index 0 is a special fallback probe +        probeIndex[0] = 0; +        probeInfluences = 1; +    }  }  // from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection @@ -316,7 +321,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i)  // c - center of probe  // r2 - radius of probe squared  // i - index of probe  -vec3 tapRefMap(vec3 pos, vec3 dir, out vec3 vi, out vec3 wi, float lod, vec3 c, float r2, int i) +vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)  {      //lod = max(lod, 1);      // parallax adjustment @@ -326,10 +331,26 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out vec3 vi, out vec3 wi, float lod, vec3 c,      if (refIndex[i].w < 0)      {          v = boxIntersect(pos, dir, i); +        w = 1.0;      }      else      { -        v = sphereIntersect(pos, dir, c, r2); +        float r = refSphere[i].w; // radius of sphere volume +        float rr = r * r; // radius squared + +        v = sphereIntersect(pos, dir, c, rr); + +        float p = float(abs(refIndex[i].w)); // priority +  +        float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down) +        vec3 delta = pos.xyz - refSphere[i].xyz; +        float d2 = max(dot(delta, delta), 0.001); +        float r2 = r1 * r1; + +        float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001); + +        w = 1.0 / d2; +        w *= atten;      }      vi = v; @@ -352,19 +373,32 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out vec3 vi, out vec3 wi, float lod, vec3 c,  // c - center of probe  // r2 - radius of probe squared  // i - index of probe  -vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i) +vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)  { -    //lod = max(lod, 1);      // parallax adjustment -      vec3 v;      if (refIndex[i].w < 0)      {          v = boxIntersect(pos, dir, i); +        w = 1.0;      }      else      { -        v = sphereIntersect(pos, dir, c, r2); +        float r = refSphere[i].w; // radius of sphere volume +        float p = float(abs(refIndex[i].w)); // priority +        float rr = r * r; // radius squred + +        v = sphereIntersect(pos, dir, c, rr); + +        float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down) +        vec3 delta = pos.xyz - refSphere[i].xyz; +        float d2 = dot(delta, delta); +        float r2 = r1 * r1; + +        w = 1.0 / d2; + +        float atten = 1.0 - max(d2 - r2, 0.0) / (rr - r2); +        w *= atten;      }      v -= c; @@ -387,26 +421,17 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)          {              continue;          } -        float r = refSphere[i].w; // radius of sphere volume -        float p = float(abs(refIndex[i].w)); // priority -         -        float rr = r*r; // radius squred -        float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down) -        vec3 delta = pos.xyz-refSphere[i].xyz; -        float d2 = dot(delta,delta); -        float r2 = r1*r1;  -         -        { -            vec3 vi, wi; -            float atten = 1.0 - max(d2 - r2, 0.0) / (rr - r2); -            float w; -            vec3 refcol; +        float w; +        vec3 vi, wi; +        vec3 refcol; +         +        {              if (errorCorrect && refIndex[i].w >= 0)              { // error correction is on and this probe is a sphere                //take a sample to get depth value, then error correct -                refcol = tapRefMap(pos, dir, vi, wi, abs(lod + 2), refSphere[i].xyz, rr, i); +                refcol = tapRefMap(pos, dir, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i);                  //adjust lookup by distance result                  float d = length(vi - wi); @@ -425,43 +450,15 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)              }              else              { -                w = 1.0 / d2; -                refcol = tapRefMap(pos, dir, vi, wi, lod, refSphere[i].xyz, rr, i); +                refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i);              } -            w *= atten; - -            //w *= p; // boost weight based on priority              col += refcol.rgb*w;              wsum += w;          }      } -    if (probeInfluences < 1) -    { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera  -        for (int idx = 0; idx < 8; ++idx) -        { -            if (refIndex[idx].w < 0) -            { // don't fallback to box probes, they are *very* specific -                continue; -            } -            int i = idx; -            vec3 delta = pos.xyz-refSphere[i].xyz; -            float d2 = dot(delta,delta); -             -            { -                vec3 vi, wi; -                vec3 refcol = tapRefMap(pos, dir, vi, wi, lod, refSphere[i].xyz, d2, i); - -                float w = 1.0/d2; -                w *= w; -                col += refcol.rgb*w; -                wsum += w; -            } -        } -    } -      if (wsum > 0.0)      {          col *= 1.0/wsum; @@ -487,52 +484,17 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir)          {              continue;          } -        float r = refSphere[i].w; // radius of sphere volume -        float p = float(abs(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; -        float d2 = dot(delta,delta); -        float r2 = r1*r1;           { -            vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, rr, i); -             -            float w = 1.0/d2; +            float w; +            vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i); -            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;          }      } -    if (probeInfluences <= 1) -    { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera  -        for (int idx = 0; idx < 8; ++idx) -        { -            if (refIndex[idx].w < 0) -            { // don't fallback to box probes, they are *very* specific -                continue; -            } -            int i = idx; -            vec3 delta = pos.xyz-refSphere[i].xyz; -            float d2 = dot(delta,delta); -             -            { -                vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, d2, i); -                 -                float w = 1.0/d2; -                w *= w; -                col += refcol*w; -                wsum += w; -            } -        } -    } -      if (wsum > 0.0)      {          col *= 1.0/wsum; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f1ee8f70b..19f0a8d089 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -41,10 +41,13 @@ extern BOOL gTeleportDisplay;  LLReflectionMapManager::LLReflectionMapManager()  { -    for (int i = 0; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) +    for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)      {          mCubeFree[i] = true;      } + +    // cube index 0 is reserved for the fallback probe +    mCubeFree[0] = false;  }  struct CompareReflectionMapDistance @@ -102,6 +105,15 @@ void LLReflectionMapManager::update()      } +    if (mDefaultProbe.isNull()) +    { +        mDefaultProbe = addProbe(); +        mDefaultProbe->mDistance = -4096.f; // hack to make sure the default probe is always first in sort order +        mDefaultProbe->mRadius = 4096.f; +    } + +    mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV); +          LLVector4a camera_pos;      camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); @@ -174,8 +186,11 @@ void LLReflectionMapManager::update()              closestDynamic = probe;          } -        d.setSub(camera_pos, probe->mOrigin); -        probe->mDistance = d.getLength3().getF32()-probe->mRadius; +        if (probe != mDefaultProbe) +        { +            d.setSub(camera_pos, probe->mOrigin); +            probe->mDistance = d.getLength3().getF32() - probe->mRadius; +        }      }      if (realtime && closestDynamic != nullptr) @@ -196,7 +211,8 @@ void LLReflectionMapManager::update()          if (probe->mCubeIndex == -1)          {              probe->mCubeArray = mTexture; -            probe->mCubeIndex = allocateCubeIndex(); + +            probe->mCubeIndex = probe == mDefaultProbe ? 0 : allocateCubeIndex();          }          probe->autoAdjustOrigin(); @@ -346,6 +362,8 @@ void LLReflectionMapManager::deleteProbe(U32 i)      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;      LLReflectionMap* probe = mProbes[i]; +    llassert(probe != mDefaultProbe); +      if (probe->mCubeIndex != -1)      { // mark the cube index used by this probe as being free          mCubeFree[probe->mCubeIndex] = true; @@ -429,7 +447,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)          {              LL_PROFILE_GPU_ZONE("probe mip");              mMipChain[i].bindTarget(); -              if (i == 0)              { @@ -607,6 +624,10 @@ void LLReflectionMapManager::shift(const LLVector4a& offset)  void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; +    if (mDefaultProbe == probe) +    { +        return; +    }      //remove from existing neighbors      { @@ -627,7 +648,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)          LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search");          for (auto& other : mProbes)          { -            if (other != probe) +            if (other != mDefaultProbe && other != probe)              {                  if (probe->intersects(other))                  { diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 4dcd822677..14b762998a 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -155,6 +155,8 @@ private:      LLReflectionMap* mUpdatingProbe = nullptr;      U32 mUpdatingFace = 0; +    LLPointer<LLReflectionMap> mDefaultProbe;  // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0) +      // number of reflection probes to use for rendering (based on saved setting RenderReflectionProbeCount)      U32 mReflectionProbeCount;  }; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 628d0ecc6a..3167d1161c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1235,6 +1235,7 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const  void LLViewerRegion::updateReflectionProbes()  { +#if 1      const F32 probe_spacing = 32.f;      const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);      const F32 hover_height = 2.f; @@ -1270,6 +1271,7 @@ void LLViewerRegion::updateReflectionProbes()              mReflectionMaps[idx]->mRadius = probe_radius;          }      } +#endif  }  void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)  | 
