diff options
7 files changed, 108 insertions, 77 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 4f6e01764a..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 @@ -366,11 +372,11 @@ return texCUBE(envMap, ReflDirectionWS);  // i - probe index in refBox/refSphere  // d - distance to nearest wall in clip space  // scale - scale of box, default 1.0 -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 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 = refBox[i]; +    mat4 clipToLocal = i;      vec3 RayLS = mat3(clipToLocal) * dir;      vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -389,7 +395,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)      return IntersectPositionCS;  } -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d)  {      return boxIntersect(origin, dir, i, d, 1.0);  } @@ -444,9 +450,9 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)  } -void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) +void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col)  { -    mat4 clipToLocal = refBox[i]; +    mat4 clipToLocal = i;      // transform into unit cube space      origin = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -463,7 +469,7 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)  //  r - radius of probe influence volume  // i - index of probe in refSphere  // dw - distance weight -float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw) +float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw)  {      float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)       vec3 delta = pos.xyz - origin; @@ -472,7 +478,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw      float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);      float w = 1.0 / d2; -    w *= refParams[i].z; +    w *= i.z;      dw = w * atten * max(r, 1.0)*4; @@ -498,7 +504,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,      if (refIndex[i].w < 0)      {  // box probe          float d = 0; -        v = boxIntersect(pos, dir, i, d); +        v = boxIntersect(pos, dir, refBox[i], d);          w = max(d, 0.001);      } @@ -512,7 +518,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 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                  rr); -        w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);      }      v -= c; @@ -538,7 +544,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int      if (refIndex[i].w < 0)      {          float d = 0.0; -        v = boxIntersect(pos, dir, i, d, 3.0); +        v = boxIntersect(pos, dir, refBox[i], d, 3.0);          w = max(d, 0.001);      }      else @@ -552,7 +558,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int          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, i, dw); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);      }      v -= c; @@ -682,23 +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; +uniform samplerCubeArray   heroProbes;  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; +    float falloffMult = 10; +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); +    if (heroShape < 1)      { -        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; -        } +        float d = 0; +        boxIntersect(pos, norm, heroBox, d, 1.0); +         +        w = max(d, 0);      } +    else +    { +        float r = heroSphere.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 @@ -779,7 +799,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)      {          if (refIndex[i].w < 0)          { -            boxIntersectDebug(origin, pos, i, col); +            boxIntersectDebug(origin, pos, refBox[i], col);          }          else          { 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..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++; @@ -417,55 +421,43 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe)  void LLHeroProbeManager::updateUniforms()  { -    if (!LLPipeline::sReflectionProbesEnabled) +    if (!gPipeline.RenderMirrors)      {          return;      }      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; -    struct HeroProbeData -    { -        LLVector4 heroPosition[1]; -        GLint heroProbeCount = 1; -    }; -     -    HeroProbeData hpd; -          LLMatrix4a modelview;      modelview.loadu(gGLModelView);      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()); - -    //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) +    mHeroData.heroProbeCount = 1; +     +    if (mNearestHero != nullptr)      { -        return; -    } - -    if (mUBO == 0) -    {  -        updateUniforms(); +        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); +        mHeroData.heroShape = 0; +        if (!mProbes[0]->getBox(mHeroData.heroBox)) +        { +            mHeroData.heroShape = 1; +        } +         +        mHeroData.heroSphere.set(oa.getF32ptr()); +        mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius;      } -    glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); +     +    mHeroData.heroMipCount = mMipChain.size();  }  void LLHeroProbeManager::renderDebug() @@ -554,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 8506886409..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); @@ -1016,7 +1024,6 @@ void LLReflectionMapManager::updateUniforms()                  {                      refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;                  } -              }              modelview.affineTransform(refmap->mOrigin, oa);              rpd.refSphere[count].set(oa.getF32ptr()); @@ -1119,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)      {  | 
