diff options
4 files changed, 122 insertions, 65 deletions
| diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 8b1d41776f..24539c3c3a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -80,7 +80,7 @@ bool isAbove(vec3 pos, vec4 plane)      return (dot(plane.xyz, pos) + plane.w) > 0;  } -int max_priority = 0; +bool sample_automatic = true;  // return true if probe at index i influences position pos  bool shouldSampleProbe(int i, vec3 pos) @@ -95,24 +95,24 @@ bool shouldSampleProbe(int i, vec3 pos)              return false;          } -        max_priority = max(max_priority, -refIndex[i].w); +        sample_automatic = false;      }      else      { -        if (refSphere[i].w > 0.0) // zero is special indicator to always sample this probe +        if (refIndex[i].w == 0 && !sample_automatic)          { -            vec3 delta = pos.xyz - refSphere[i].xyz; -            float d = dot(delta, delta); -            float r2 = refSphere[i].w; -            r2 *= r2; - -            if (d > r2) -            { //outside bounding sphere -                return false; -            } +            return false;          } -        max_priority = max(max_priority, refIndex[i].w); +        vec3 delta = pos.xyz - refSphere[i].xyz; +        float d = dot(delta, delta); +        float r2 = refSphere[i].w; +        r2 *= r2; + +        if (d > r2) +        { // outside bounding sphere +            return false; +        }      }      return true; @@ -120,7 +120,6 @@ bool shouldSampleProbe(int i, vec3 pos)  // call before sampleRef  // populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT -// overall algorithm --   void preProbeSample(vec3 pos)  {      // TODO: make some sort of structure that reduces the number of distance checks @@ -210,7 +209,7 @@ void preProbeSample(vec3 pos)          }      } -    if (max_priority <= 1) +    if (sample_automatic)      { // probe at index 0 is a special probe for smoothing out automatic probes          probeIndex[probeInfluences++] = 0;      } @@ -342,7 +341,7 @@ return texCUBE(envMap, ReflDirectionWS);  // d - distance to nearest wall in clip space  vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)  { -    // Intersection with OBB convertto unit box space +    // Intersection with OBB convert to unit box space      // Transform in local unit parallax cube space (scaled and rotated)      mat4 clipToLocal = refBox[i]; @@ -431,18 +430,24 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)  //  origin - center of sphere probe  //  r - radius of probe influence volume  // min_da - minimum angular attenuation coefficient -float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da) +// i - index of probe in refSphere +// dw - distance weight +float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da, int i, 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 r2 = r1; //r1 * r1;      //float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);      float atten = 1.0 - max(d2 - r2, 0.0) / max((r - r2), 0.001); +    float w = 1.0 / d2; +     +    dw = w * atten * max(r, 1.0)*4;      atten *= max(dot(normalize(-delta), dir), min_da); -    float w = 1.0 / d2; +      w *= atten;      return w; @@ -451,13 +456,15 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)  // Tap a reflection probe  // pos - position of pixel  // dir - pixel normal +//  w - weight of sample (distance and angular attenuation) +//  dw - weight of sample (distance only)  // vi - return value of intersection point with influence volume  // wi - return value of approximate world space position of sampled pixel  // lod - which mip to bias towards (lower is higher res, sharper reflections)  // c - center of probe  // r2 - radius of probe squared  // i - index of probe  -vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i) +vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)  {      //lod = max(lod, 1);      // parallax adjustment @@ -473,14 +480,15 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float      }      else      { -        float r = refSphere[i].w; // radius of sphere volume -        float rr = r * r; // radius squared +        float r = refSphere[i].w; + +        float rr = r * r;          v = sphereIntersect(pos, dir, c,  -        refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres +        refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres                  rr); -        w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25, i, dw);      }      vi = v; @@ -500,10 +508,10 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float  // Tap an irradiance map  // pos - position of pixel  // dir - pixel normal -// c - center of probe -// r2 - radius of probe squared +// w - weight of sample (distance and angular attenuation) +// dw - weight of sample (distance only)  // i - index of probe  -vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i) +vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i)  {      // parallax adjustment      vec3 v; @@ -516,14 +524,15 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)      else      {          float r = refSphere[i].w; // radius of sphere volume -        float p = float(abs(refIndex[i].w)); // priority -        float rr = r * r; // radius squred + +        // pad sphere for manual probe extending into automatic probe space +        float rr = r * r;          v = sphereIntersect(pos, dir, c,  -        refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres +        refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres                  rr); -        w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001, i, dw);      }      v -= c; @@ -535,19 +544,30 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)  vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)  { -    float wsum = 0.0; -    vec3 col = vec3(0,0,0); -    float vd2 = dot(pos,pos); // view distance squared +    float wsum[2]; +    wsum[0] = 0; +    wsum[1] = 0; + +    float dwsum[2]; +    dwsum[0] = 0; +    dwsum[1] = 0; + +    vec3 col[2]; +    col[0] = vec3(0); +    col[1] = vec3(0);      for (int idx = 0; idx < probeInfluences; ++idx)      {          int i = probeIndex[idx]; -        if (abs(refIndex[i].w) < max_priority) +        int p = clamp(abs(refIndex[i].w), 0, 1); + +        if (p == 0 && !sample_automatic)          {              continue;          } -        float w; +        float w = 0; +        float dw = 0;          vec3 vi, wi;          vec3 refcol; @@ -556,7 +576,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)              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, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i); +                refcol = tapRefMap(pos, dir, w, dw, vi, wi, abs(lod + 2), refSphere[i].xyz, i);                  //adjust lookup by distance result                  float d = length(vi - wi); @@ -571,61 +591,96 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)                  // weight by vector correctness                  vec3 pi = normalize(wi - pos);                  w *= max(dot(pi, dir), 0.1); -                //w = pow(w, 32.0);              }              else              { -                refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i); +                refcol = tapRefMap(pos, dir, w, dw, vi, wi, lod, refSphere[i].xyz, i);              } -            col += refcol.rgb*w; - -            wsum += w; +            col[p] += refcol.rgb*w; +            wsum[p] += w; +            dwsum[p] += dw;          }      } -    if (wsum > 0.0) +    // mix automatic and manual probes +    if (sample_automatic && wsum[0] > 0.0) +    { // some automatic probes were sampled +        col[0] *= 1.0/wsum[0]; +        if (wsum[1] > 0.0) +        { //some manual probes were sampled, mix between the two +            col[1] *= 1.0/wsum[1]; +            col[1] = mix(col[0], col[1], min(dwsum[1], 1.0)); +            col[0] = vec3(0); +        } +    } +    else if (wsum[1] > 0.0)      { -        col *= 1.0/wsum; +        // manual probes were sampled but no automatic probes were +        col[1] *= 1.0/wsum[1]; +        col[0] = vec3(0);      } -    return col; +    return col[1]+col[0];  }  vec3 sampleProbeAmbient(vec3 pos, vec3 dir)  {      // modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further      // as irradiance map mixing is tuned independently of radiance map mixing -    float wsum = 0.0; -    vec3 col = vec3(0,0,0); -    float vd2 = dot(pos,pos); // view distance squared +    float wsum[2]; +    wsum[0] = 0; +    wsum[1] = 0; -    float minweight = 1.0; +    float dwsum[2]; +    dwsum[0] = 0; +    dwsum[1] = 0; + +    vec3 col[2]; +    col[0] = vec3(0); +    col[1] = vec3(0);      for (int idx = 0; idx < probeInfluences; ++idx)      {          int i = probeIndex[idx]; -        if (abs(refIndex[i].w) < max_priority) +        int p = clamp(abs(refIndex[i].w), 0, 1); + +        if (p == 0 && !sample_automatic)          {              continue;          }          { -            float w; -            vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i); +            float w = 0; +            float dw = 0; -            col += refcol*w; -             -            wsum += w; +            vec3 refcol = tapIrradianceMap(pos, dir, w, dw, refSphere[i].xyz, i); + +            col[p] += refcol*w; +            wsum[p] += w; +            dwsum[p] += dw;          }      } -    if (wsum > 0.0) +    // mix automatic and manual probes +    if (sample_automatic && wsum[0] > 0.0) +    { // some automatic probes were sampled +        col[0] *= 1.0/wsum[0]; +        if (wsum[1] > 0.0) +        { //some manual probes were sampled, mix between the two +            col[1] *= 1.0/wsum[1]; +            col[1] = mix(col[0], col[1], min(dwsum[1], 1.0)); +            col[0] = vec3(0); +        } +    } +    else if (wsum[1] > 0.0)      { -        col *= 1.0/wsum; +        // manual probes were sampled but no automatic probes were +        col[1] *= 1.0/wsum[1]; +        col[0] = vec3(0);      } - -    return col; +     +    return col[1]+col[0];  }  void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, @@ -658,7 +713,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)  {      vec3 origin = vec3(0,0,0); -    bool manual_probe = abs(refIndex[i].w) > 2; +    bool manual_probe = abs(refIndex[i].w) > 0;      if (manual_probe)      { @@ -705,7 +760,6 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,  void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)  { -    // TODO - don't hard code lods      float reflection_lods = max_probe_lod;      preProbeSample(pos); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 3d721cd048..631d2c04d0 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -232,8 +232,8 @@ void main()      irradiance       = vec3(0); -    vec3 diffuseColor; -    vec3 specularColor; +    vec3 diffuseColor = vec3(0); +    vec3 specularColor = vec3(0);      calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);      vec3 v = -normalize(pos.xyz); diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index ce749a96c7..394596feea 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -66,7 +66,7 @@ void LLReflectionMap::autoAdjustOrigin()          if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)          { -            mPriority = 1; +            mPriority = 0;              // cast a ray towards 8 corners of bounding box              // nudge origin towards center of empty space @@ -150,7 +150,7 @@ void LLReflectionMap::autoAdjustOrigin()      }      else if (mViewerObject)      { -        mPriority = 64; +        mPriority = 1;          mOrigin.load3(mViewerObject->getPositionAgent().mV);          mRadius = mViewerObject->getScale().mV[0]*0.5f;      } diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index cf0bc2ff27..04bc8d824c 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -97,6 +97,9 @@ public:      LLViewerObject* mViewerObject = nullptr;      // what priority should this probe have (higher is higher priority) -    U32 mPriority = 1; +    // currently only 0 or 1 +    // 0 - automatic probe +    // 1 - manual probe +    U32 mPriority = 0;  }; | 
