diff options
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 1 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.h | 1 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl | 99 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl | 38 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl | 5 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl | 120 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 68 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.h | 6 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.h | 1 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 14 | 
11 files changed, 334 insertions, 31 deletions
| diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e2e1ff9714..10939db5e4 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1171,6 +1171,7 @@ void LLShaderMgr::initAttribsAndUniforms()      mReservedUniforms.push_back("bumpMap2");  	mReservedUniforms.push_back("environmentMap");      mReservedUniforms.push_back("reflectionProbes"); +    mReservedUniforms.push_back("irradianceProbes");  	mReservedUniforms.push_back("cloud_noise_texture");      mReservedUniforms.push_back("cloud_noise_texture_next");  	mReservedUniforms.push_back("fullbright"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index d3bb2b9db4..5b19dd53d1 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -81,6 +81,7 @@ public:          BUMP_MAP2,                          //  "bumpMap2"          ENVIRONMENT_MAP,                    //  "environmentMap"          REFLECTION_PROBES,                     //  "reflectionProbes" +        IRRADIANCE_PROBES,                     //  "irradianceProbes"          CLOUD_NOISE_MAP,                    //  "cloud_noise_texture"          CLOUD_NOISE_MAP_NEXT,               //  "cloud_noise_texture_next"          FULLBRIGHT,                         //  "fullbright" diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl new file mode 100644 index 0000000000..2028509775 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl @@ -0,0 +1,99 @@ +/**  + * @file irradianceGenF.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  + +/*[EXTRA_CODE_HERE]*/ + + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform samplerCubeArray   reflectionProbes; +uniform int sourceIdx; + +VARYING vec3 vary_dir; + +// ============================================================================================================= +// Parts of this file are (c) 2018 Sascha Willems +// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/irradiancecube.frag +/* +MIT License + +Copyright (c) 2018 Sascha Willems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +// ============================================================================================================= + + + +#define PI 3.1415926535897932384626433832795 + +float deltaPhi = PI/16.0; +float deltaTheta = deltaPhi*0.25; + +void main() +{ +	vec3 N = normalize(vary_dir); +	vec3 up = vec3(0.0, 1.0, 0.0); +	vec3 right = normalize(cross(up, N)); +	up = cross(N, right); + +	const float TWO_PI = PI * 2.0; +	const float HALF_PI = PI * 0.5; + +	vec3 color = vec3(0.0); +	uint sampleCount = 0u; +	for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) { +		for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) { +			vec3 tempVec = cos(phi) * right + sin(phi) * up; +			vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec; +			color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), 3).rgb * cos(theta) * sin(theta); +			sampleCount++; +		} +	} +	frag_color = vec4(PI * color / float(sampleCount), 1.0); +} +// ============================================================================================================= + diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl new file mode 100644 index 0000000000..5190abf17c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl @@ -0,0 +1,38 @@ +/**  + * @file irradianceGenV.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec3 vary_dir; + +void main() +{ +	gl_Position = vec4(position, 1.0); + +	vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 27008b8a1c..3fc227eae7 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -26,8 +26,6 @@  /*[EXTRA_CODE_HERE]*/ -#define REFMAP_COUNT 256 -  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else @@ -35,6 +33,7 @@ out vec4 frag_color;  #endif  uniform samplerCubeArray   reflectionProbes; +uniform int sourceIdx;  VARYING vec3 vary_dir; @@ -150,7 +149,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness)  			float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);  			// Biased (+1.0) mip level for better result  			float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); -			color += textureLod(reflectionProbes, vec4(L,REFMAP_COUNT), mipLevel).rgb * dotNL; +			color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL;  			totalWeight += dotNL;  		} diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 40378b49ea..83348077d7 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -31,6 +31,7 @@  #define REF_SAMPLE_COUNT 64 //maximum number of samples to consider  uniform samplerCubeArray   reflectionProbes; +uniform samplerCubeArray   irradianceProbes;  layout (std140, binding = 1) uniform ReflectionProbes  { @@ -308,7 +309,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i) -// Tap a sphere based reflection probe +// Tap a reflection probe  // pos - position of pixel  // dir - pixel normal  // lod - which mip to bias towards (lower is higher res, sharper reflections) @@ -334,10 +335,36 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)      v -= c;      v = env_mat * v;      { -        //float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res -        //return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb;          return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod).rgb; -        //return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb; +    } +} + +// Tap an irradiance map +// pos - position of pixel +// dir - pixel normal +// c - center of probe +// r2 - radius of probe squared +// i - index of probe  +// vi - point at which reflection vector struck the influence volume, in clip space +vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i) +{ +    //lod = max(lod, 1); +    // parallax adjustment + +    vec3 v; +    if (refIndex[i].w < 0) +    { +        v = boxIntersect(pos, dir, i); +    } +    else +    { +        v = sphereIntersect(pos, dir, c, r2); +    } + +    v -= c; +    v = env_mat * v; +    { +        return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;      }  } @@ -371,7 +398,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)              float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);              w *= atten;              //w *= p; // boost weight based on priority -            col += refcol*w*max(minweight, refParams[i].x); +            col += refcol*w;              wsum += w;          } @@ -394,7 +421,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)                  float w = 1.0/d2;                  w *= w; -                col += refcol*w*max(minweight, refParams[i].x); +                col += refcol*w;                  wsum += w;              }          } @@ -408,24 +435,75 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)      return col;  } -vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod) +vec3 sampleProbeAmbient(vec3 pos, vec3 dir)  { -    vec3 col = sampleProbes(pos, dir, lod, 0.f); +    // 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 -    //desaturate -    vec3 hcol = col *0.5; -     -    col *= 2.0; -    col = vec3( -        col.r + hcol.g + hcol.b, -        col.g + hcol.r + hcol.b, -        col.b + hcol.r + hcol.g -    ); -     -    col *= 0.333333; +    float minweight = 1.0; -    return col; +    for (int idx = 0; idx < probeInfluences; ++idx) +    { +        int i = probeIndex[idx]; +        if (abs(refIndex[i].w) < max_priority) +        { +            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 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; +    } +     +    return col;  }  // brighten a color so that at least one component is 1 @@ -451,7 +529,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l      vec3 refnormpersp = reflect(pos.xyz, norm.xyz); -    ambenv = sampleProbeAmbient(pos, norm, reflection_lods-2); +    ambenv = sampleProbeAmbient(pos, norm);      if (glossiness > 0.0)      { diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 025b8457c1..dfd0d1b9a9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -80,8 +80,11 @@ void LLReflectionMapManager::update()      if (mTexture.isNull())      {          mTexture = new LLCubeMapArray(); -        // store LL_REFLECTION_PROBE_COUNT+1 cube maps, final cube map is used for render target and radiance map generation source) +        // store LL_REFLECTION_PROBE_COUNT+2 cube maps, final two cube maps are used for render target and radiance map generation source)          mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2); + +        mIrradianceMaps = new LLCubeMapArray(); +        mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT);      }      if (!mRenderTarget.isComplete()) @@ -396,6 +399,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)      gPipeline.mRT = &gPipeline.mMainRT;      mRenderTarget.flush(); +    S32 targetIdx = LL_REFLECTION_PROBE_COUNT; + +    if (probe != mUpdatingProbe) +    { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel +        targetIdx += 1; +    } +      // downsample to placeholder map      {          LLGLDepthTest depth(GL_FALSE, GL_FALSE); @@ -453,7 +463,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)              {                  mTexture->bind(0);                  //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); -                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, LL_REFLECTION_PROBE_COUNT * 6 + face, 0, 0, res, res); +                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res);                  mTexture->unbind();              }              mMipChain[i].flush(); @@ -472,7 +482,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)          gRadianceGenProgram.bind();          S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);          mTexture->bind(channel); -     +        static LLStaticHashedString sSourceIdx("sourceIdx"); +        gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx); +          for (int cf = 0; cf < 6; ++cf)          { // for each cube face              LLCoordFrame frame; @@ -499,13 +511,59 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)                  gGL.end();                  gGL.flush(); -                 -                                  S32 res = mMipChain[i].getWidth();                  glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);                  mMipChain[i].flush();              }          } +        gRadianceGenProgram.unbind(); + +        //generate irradiance map +        gIrradianceGenProgram.bind(); +        channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); +        mTexture->bind(channel); + +        gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); + +        int start_mip = 0; +        // find the mip target to start with based on irradiance map resolution +        for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) +        { +            if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) +            { +                break; +            } +        } + +        for (int cf = 0; cf < 6; ++cf) +        { // for each cube face +            LLCoordFrame frame; +            frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + +            F32 mat[16]; +            frame.getOpenGLRotation(mat); +            gGL.loadMatrix(mat); + +            for (int i = start_mip; i < mMipChain.size(); ++i) +            { +                mMipChain[i].bindTarget(); + +                gGL.begin(gGL.QUADS); +                gGL.vertex3f(-1, -1, -1); +                gGL.vertex3f(1, -1, -1); +                gGL.vertex3f(1, 1, -1); +                gGL.vertex3f(-1, 1, -1); +                gGL.end(); +                gGL.flush(); + +                S32 res = mMipChain[i].getWidth(); +                mIrradianceMaps->bind(channel); +                glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i-start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); +                mTexture->bind(channel); +                mMipChain[i].flush(); +            } +        } +        gIrradianceGenProgram.unbind();      }  } diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 551a461e63..5f0b11ec17 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -39,6 +39,7 @@ class LLViewerObject;  // reflection probe resolution  #define LL_REFLECTION_PROBE_RESOLUTION 256 +#define LL_IRRADIANCE_MAP_RESOLUTION 64  // reflection probe mininum scale  #define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; @@ -112,9 +113,12 @@ private:      std::vector<LLRenderTarget> mMipChain; -    // storage for reflection probes +    // storage for reflection probe radiance maps (plus two scratch space cubemaps)      LLPointer<LLCubeMapArray> mTexture; +    // storage for reflection probe irradiance maps +    LLPointer<LLCubeMapArray> mIrradianceMaps; +      // array indicating if a particular cubemap is free      bool mCubeFree[LL_REFLECTION_PROBE_COUNT]; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d5ca915da5..c041d2470c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -86,6 +86,7 @@ LLGLSLShader	gGlowCombineProgram;  LLGLSLShader	gSplatTextureRectProgram;  LLGLSLShader	gReflectionMipProgram;  LLGLSLShader	gRadianceGenProgram; +LLGLSLShader	gIrradianceGenProgram;  LLGLSLShader	gGlowCombineFXAAProgram;  LLGLSLShader	gTwoTextureAddProgram;  LLGLSLShader	gTwoTextureCompareProgram; @@ -764,6 +765,7 @@ void LLViewerShaderMgr::unloadShaders()  	gSplatTextureRectProgram.unload();      gReflectionMipProgram.unload();      gRadianceGenProgram.unload(); +    gIrradianceGenProgram.unload();  	gGlowCombineFXAAProgram.unload();  	gTwoTextureAddProgram.unload();  	gTwoTextureCompareProgram.unload(); @@ -3833,6 +3835,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()          success = gRadianceGenProgram.createShader(NULL, NULL);      } +    if (success) +    { +        gIrradianceGenProgram.mName = "Irradiance Gen Shader"; +        gIrradianceGenProgram.mShaderFiles.clear(); +        gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER_ARB)); +        gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; +        success = gIrradianceGenProgram.createShader(NULL, NULL); +    } +  	if( !success )  	{  		mShaderLevel[SHADER_INTERFACE] = 0; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index fa5b2121b9..87d90b49a9 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -163,6 +163,7 @@ extern LLGLSLShader			gGlowCombineProgram;  extern LLGLSLShader			gSplatTextureRectProgram;  extern LLGLSLShader			gReflectionMipProgram;  extern LLGLSLShader         gRadianceGenProgram; +extern LLGLSLShader         gIrradianceGenProgram;  extern LLGLSLShader			gGlowCombineFXAAProgram;  extern LLGLSLShader			gDebugProgram;  extern LLGLSLShader			gClipProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 028a0db95c..06c9d3c136 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -9205,10 +9205,22 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)  {      S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); +    bool bound = false;      if (channel > -1 && mReflectionMapManager.mTexture.notNull())      { -        // see comments in class2/deferred/softenLightF.glsl for what these uniforms mean          mReflectionMapManager.mTexture->bind(channel); +        bound = true; +    } + +    channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); +    if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull()) +    { +        mReflectionMapManager.mIrradianceMaps->bind(channel); +        bound = true; +    } + +    if (bound) +    {          mReflectionMapManager.setUniforms();          F32* m = gGLModelView; | 
