diff options
Diffstat (limited to 'indra')
23 files changed, 359 insertions, 16 deletions
| diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 9f79c13a97..415641f65f 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -60,6 +60,12 @@ if(WINDOWS)          nghttp2.dll          libhunspell.dll          uriparser.dll +        Iex-3_2.dll +        IlmThread-3_2.dll +        Imath-3_1.dll +        OpenEXR-3_2.dll +        OpenEXRCore-3_2.dll +        OpenEXRUtil-3_2.dll          )      # ICU4C (same filenames for 32 and 64 bit builds) @@ -184,6 +190,12 @@ elseif(DARWIN)          liburiparser.dylib          liburiparser.1.dylib          liburiparser.1.0.27.dylib +        libIex-3_2.dylib +        libIlmThread-3_2.dylib +        libImath-3_1.dylib +        libOpenEXR-3_2.dylib +        libOpenEXRCore-3_2.dylib +        libOpenEXRUtil-3_2.dylib         )      if (TARGET ll::fmodstudio) diff --git a/indra/cmake/OpenEXR.cmake b/indra/cmake/OpenEXR.cmake new file mode 100644 index 0000000000..ee21fac541 --- /dev/null +++ b/indra/cmake/OpenEXR.cmake @@ -0,0 +1,18 @@ +# -*- cmake -*- + +include(Prebuilt) + +include_guard() +add_library( ll::openexr INTERFACE IMPORTED ) + +if(USE_CONAN ) +  target_link_libraries( ll::openexr INTERFACE CONAN_PKG::openexr ) +  return() +endif() + +use_prebuilt_binary(openexr) + +target_link_libraries( ll::openexr INTERFACE Iex-3_2 IlmThread-3_2 Imath-3_1 OpenEXR-3_2 OpenEXRCore-3_2 OpenEXRUtil-3_2) + +target_include_directories( ll::openexr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/OpenEXR ${LIBS_PREBUILT_DIR}/include/Imath) + diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 5384133220..6cfe065355 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -618,7 +618,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev      extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS   0.0 \n"); // atmo kill      extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS    0.34\n"); // bit 0      extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR      0.67\n"); // bit 1 -    extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_MIRROR      1.0\n");  // bit 2 +    extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_HDRI      1.0\n");  // bit 2      extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag)    (abs(norm.w-flag)< 0.1)\n");  	if (defines) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6b15e847a3..8494ba5b49 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -34,6 +34,7 @@ include(LLWindow)  include(NDOF)  include(NVAPI)  include(OPENAL) +include(OpenEXR)  include(OpenGL)  include(OpenSSL)  include(PNG) @@ -72,7 +73,6 @@ if (NOT HAVOK_TPV)     endif()  endif (NOT HAVOK_TPV) -  set(viewer_SOURCE_FILES      groupchatlistener.cpp      llaccountingcostmanager.cpp @@ -1744,6 +1744,12 @@ if (WINDOWS)        media_plugin_cef        media_plugin_libvlc        media_plugin_example +      ${SHARED_LIB_STAGING_DIR}/Iex-3_2.dll +      ${SHARED_LIB_STAGING_DIR}/IlmThread-3_2.dll +      ${SHARED_LIB_STAGING_DIR}/Imath-3_1.dll +      ${SHARED_LIB_STAGING_DIR}/OpenEXR-3_2.dll +      ${SHARED_LIB_STAGING_DIR}/OpenEXRCore-3_2.dll +      ${SHARED_LIB_STAGING_DIR}/OpenEXRUtil-3_2.dll        )      if (ADDRESS_SIZE EQUAL 64) @@ -1937,6 +1943,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}          ll::bugsplat          ll::tracy          ll::icu4c +        ll::openexr          )  if( TARGET ll::intel_memops ) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9d4f4cf911..8420f32db8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9274,6 +9274,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>RenderDesaturateIrradiance</key> +    <map> +      <key>Comment</key> +      <string>Desaturate irradiance to remove blue tint</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>RenderDebugAlphaMask</key>      <map>        <key>Comment</key> @@ -9340,6 +9351,28 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>RenderHDRIExposure</key> +  <map> +    <key>Comment</key> +    <string>Exposure adjustment of HDRI when previewing an HDRI.  Units are EV.  Sane values would be -10 to 10.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0.0</real> +  </map> +  <key>RenderHDRIRotation</key> +  <map> +    <key>Comment</key> +    <string>Rotation (in degrees) of environment when previewing an HDRI.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0.0</real> +  </map>    <key>RenderMaxOpenGLVersion</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 3443785e1a..d89377326e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -97,6 +97,7 @@ vec3 toneMapACES_Hill(vec3 color)  uniform float exposure;  uniform float gamma; +uniform float aces_mix;  vec3 toneMap(vec3 color)  { @@ -106,7 +107,7 @@ vec3 toneMap(vec3 color)      color *= exposure * exp_scale;      // mix ACES and Linear here as a compromise to avoid over-darkening legacy content -    color = mix(toneMapACES_Hill(color), color, 0.3); +    color = mix(toneMapACES_Hill(color), color, aces_mix);  #endif      return color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 9d9ba49d82..cc5280d929 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -27,6 +27,13 @@  in vec3 vary_HazeColor;  in float vary_LightNormPosDot; +#ifdef HAS_HDRI +in vec3 vary_position; +uniform float sky_hdr_scale; +uniform mat3 env_mat; +uniform sampler2D environmentMap; +#endif +  uniform sampler2D rainbow_map;  uniform sampler2D halo_map; @@ -37,6 +44,9 @@ uniform float ice_level;  out vec4 frag_data[4];  vec3 srgb_to_linear(vec3 c); +vec3 linear_to_srgb(vec3 c); + +#define PI 3.14159265  /////////////////////////////////////////////////////////////////////////  // The fragment shader for the sky @@ -71,6 +81,14 @@ vec3 halo22(float d)  void main()  { +#ifdef HAS_HDRI +    vec3 pos = normalize(vary_position); +    pos = env_mat * pos; +    vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI); +    vec3 color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale; +    color = min(color, vec3(8192*8192*16)); +#else +      // Potential Fill-rate optimization.  Add cloud calculation       // back in and output alpha of 0 (so that alpha culling kills       // the fragment) if the sky wouldn't show up because the clouds  @@ -86,9 +104,12 @@ void main()      color.rgb *= 2.;      color.rgb = clamp(color.rgb, vec3(0), vec3(5)); +#endif +      frag_data[0] = vec4(0);      frag_data[1] = vec4(0); -    frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog +    frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS);      frag_data[3] = vec4(color.rgb, 1.0); +  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 17ce2dee5b..bbe9a5a838 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -35,6 +35,10 @@ in vec3 position;  out vec3 vary_HazeColor;  out float vary_LightNormPosDot; +#ifdef HAS_HDRI +out vec3 vary_position; +#endif +  // Inputs  uniform vec3 camPosLocal; @@ -72,6 +76,10 @@ void main()      // Get relative position      vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); +#ifdef HAS_HDRI +    vary_position = rel_pos; +#endif +      // Adj position vector to clamp altitude      if (rel_pos.y > 0.)      { diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 2f90249169..5cc7ea698a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -189,6 +189,10 @@ void main()          vec3 v = -normalize(pos.xyz);          color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);      } +    else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI)) +    { +        color = texture(emissiveRect, tc).rgb; +    }      else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))      {          //should only be true of WL sky, just port over base color value diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b14235f25c..a9cc138549 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,7 @@  #include "llsky.h"  #include "llvowlsky.h"  #include "llsettingsvo.h" +#include "llviewercontrol.h"  extern BOOL gCubeSnapshot; @@ -127,6 +128,8 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca  	gGL.popMatrix();  } +extern LLPointer<LLImageGL> gEXRImage; +  void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const  {      if (!gSky.mVOSkyp) @@ -138,9 +141,33 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))  	{ +        if (gEXRImage.notNull()) +        { +            sky_shader = &gEnvironmentMapProgram; +            sky_shader->bind(); +            S32 idx = sky_shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP); +            if (idx > -1) +            { +                gGL.getTexUnit(idx)->bind(gEXRImage); +            } + +            static LLCachedControl<F32> hdri_exposure(gSavedSettings, "RenderHDRIExposure", 0.0f); +            static LLCachedControl<F32> hdri_rotation(gSavedSettings, "RenderHDRIRotation", 0.f); +             +            LLMatrix3 rot; +            rot.setRot(0.f, hdri_rotation*DEG_TO_RAD, 0.f); + +            sky_shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, powf(2.f, hdri_exposure)); +            sky_shader->uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, GL_FALSE, (F32*) rot.mMatrix); +        } +        else +        { +            sky_shader->bind(); +        } +          LLGLSPipelineDepthTestSkyBox sky(true, true); -        sky_shader->bind(); +                  sky_shader->uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0); @@ -180,7 +207,7 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca  void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const  { -    if (!gSky.mVOSkyp) +    if (!gSky.mVOSkyp || gEXRImage.notNull())      {          return;      } @@ -251,6 +278,11 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const  void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const  { +    if (gEXRImage.notNull()) +    { +        return; +    } +  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex())  	{          LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); @@ -310,7 +342,7 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32  void LLDrawPoolWLSky::renderHeavenlyBodies()  { -    if (!gSky.mVOSkyp) return; +    if (!gSky.mVOSkyp || gEXRImage.notNull()) return;      LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index affea3f69c..0b535e15b0 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1770,8 +1770,10 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con          case LLSD::TypeArray:          {              LLVector4 vect4(value); +            // always identify as a radiance pass if desaturating irradiance is disabled +            static LLCachedControl<bool> desaturate_irradiance(gSavedSettings, "RenderDesaturateIrradiance", true); -            if (gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass()) +            if (desaturate_irradiance && gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass())              { // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color                  auto max_vec = [](LLVector4 col)                  { @@ -2966,7 +2968,7 @@ void LLEnvironment::DayTransition::animate()      // pause probe updates and reset reflection maps on sky change -    gPipeline.mReflectionMapManager.pause(); +    gPipeline.mReflectionMapManager.pause(mTransitionTime);      gPipeline.mReflectionMapManager.reset();      mSky = mStartSky->buildClone(); @@ -3569,7 +3571,7 @@ namespace              mInjectedSky->setSource(target_sky);              // clear reflection probes and pause updates during sky change -            gPipeline.mReflectionMapManager.pause(); +            gPipeline.mReflectionMapManager.pause(transition);              gPipeline.mReflectionMapManager.reset();              mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(target_sky, start_sky, psky, transition); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4ad136e13a..b82172c506 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -61,6 +61,7 @@ LLFilePicker LLFilePicker::sInstance;  #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"  #define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"  #define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0" +#define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0"  #define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"  #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"  #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" @@ -228,6 +229,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)              IMAGE_FILTER \              L"\0";          break; +    case FFLOAD_HDRI: +        mOFN.lpstrFilter = HDRI_FILTER \ +            L"\0"; +        break;  	case FFLOAD_SCRIPT:  		mOFN.lpstrFilter = SCRIPT_FILTER \  			L"\0"; @@ -663,6 +668,8 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF              allowedv->push_back("gltf");              allowedv->push_back("glb");              break; +        case FFLOAD_HDRI: +            allowedv->push_back("exr");          case FFLOAD_COLLADA:              allowedv->push_back("dae");              break; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 38daff9937..891c0c0482 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -89,6 +89,7 @@ public:          FFLOAD_EXE = 14,          // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin          FFLOAD_MATERIAL = 15,          FFLOAD_MATERIAL_TEXTURE = 16, +        FFLOAD_HDRI = 17,  	};  	enum ESaveFilter diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index ce389a5cad..f9c5421866 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -38,6 +38,126 @@  #include "llviewercontrol.h"  #include "llenvironment.h"  #include "llstartup.h" +#include "llviewermenufile.h" +#include "llnotificationsutil.h" + + +// load an OpenEXR image from a file +#define IMATH_HALF_NO_LOOKUP_TABLE 1 +#include <ImfInputFile.h> +#include <ImfArray.h> +#include <ImfHeader.h> +#include <ImfFrameBuffer.h> +#include <iostream> + +LLPointer<LLImageGL> gEXRImage; + +void load_exr(const std::string& filename) +{ +    // reset reflection maps when previewing a new HDRI +    gPipeline.mReflectionMapManager.reset(); +    gPipeline.mReflectionMapManager.initReflectionMaps(); + +    try { +        Imf::InputFile file(filename.c_str()); +        Imath::Box2i       dw = file.header().dataWindow(); +        int                width = dw.max.x - dw.min.x + 1; +        int                height = dw.max.y - dw.min.y + 1; + +        Imf::Array2D<Imath::half> rPixels; +        Imf::Array2D<Imath::half> gPixels; +        Imf::Array2D<Imath::half> bPixels; + +        rPixels.resizeErase(height, width); +        gPixels.resizeErase(height, width); +        bPixels.resizeErase(height, width); + +        Imf::FrameBuffer frameBuffer; + +        frameBuffer.insert("R",                                    // name +            Imf::Slice(Imf::HALF,                            // type +                (char*)(&rPixels[0][0] -      // base +                    dw.min.x - +                    dw.min.y * width), +                sizeof(rPixels[0][0]) * 1,     // xStride +                sizeof(rPixels[0][0]) * width, // yStride +                1, 1,                            // x/y sampling +                0.0));                           // fillValue + +        frameBuffer.insert("G",                                    // name +            Imf::Slice(Imf::HALF,                            // type +                (char*)(&gPixels[0][0] -      // base +                    dw.min.x - +                    dw.min.y * width), +                sizeof(gPixels[0][0]) * 1,     // xStride +                sizeof(gPixels[0][0]) * width, // yStride +                1, 1,                            // x/y sampling +                0.0));                           // fillValue + +        frameBuffer.insert("B",                                    // name +            Imf::Slice(Imf::HALF,                           // type +                (char*)(&bPixels[0][0] -      // base +                    dw.min.x - +                    dw.min.y * width), +                sizeof(bPixels[0][0]) * 1,     // xStride +                sizeof(bPixels[0][0]) * width, // yStride +                1, 1,                            // x/y sampling +                FLT_MAX));                       // fillValue + +        file.setFrameBuffer(frameBuffer); +        file.readPixels(dw.min.y, dw.max.y); + +        U32 texName = 0; +        LLImageGL::generateTextures(1, &texName); + +        gEXRImage = new LLImageGL(texName, 4, GL_TEXTURE_2D, GL_RGB16F, GL_RGB16F, GL_FLOAT, LLTexUnit::TAM_CLAMP); +        gEXRImage->setHasMipMaps(TRUE); +        gEXRImage->setUseMipMaps(TRUE); +        gEXRImage->setFilteringOption(LLTexUnit::TFO_TRILINEAR); + +        gGL.getTexUnit(0)->bind(gEXRImage); + +        std::vector<F32> data(width * height * 3); +        for (int i = 0; i < width * height; ++i) +        { +            data[i * 3 + 0] = rPixels[i / width][i % width]; +            data[i * 3 + 1] = gPixels[i / width][i % width]; +            data[i * 3 + 2] = bPixels[i / width][i % width]; +        } + +        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data.data()); +         +        glGenerateMipmap(GL_TEXTURE_2D); + +        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +    } +    catch (const std::exception& e) { +        LLSD notif_args; +        notif_args["WHAT"] = filename; +        notif_args["REASON"] = e.what(); +        LLNotificationsUtil::add("CannotLoad", notif_args); +        return; +    } +} + +void hdri_preview() +{ +    LLFilePickerReplyThread::startPicker( +        [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) +        { +            if (LLAppViewer::instance()->quitRequested()) +            { +                return; +            } +            if (filenames.size() > 0) +            { +                load_exr(filenames[0]); +            } +        }, +        LLFilePicker::FFLOAD_HDRI, +        true); +}  extern BOOL gCubeSnapshot;  extern BOOL gTeleportDisplay; @@ -133,6 +253,11 @@ void LLReflectionMapManager::update()          return;      } +    if (mPaused && gFrameTimeSeconds > mResumeTime) +    { +        resume(); +    } +      initReflectionMaps();      if (!mRenderTarget.isComplete()) @@ -831,9 +956,10 @@ void LLReflectionMapManager::reset()      mReset = true;  } -void LLReflectionMapManager::pause() +void LLReflectionMapManager::pause(F32 duration)  {      mPaused = true; +    mResumeTime = gFrameTimeSeconds + duration;  }  void LLReflectionMapManager::resume() @@ -1283,6 +1409,8 @@ void LLReflectionMapManager::initReflectionMaps()      if (mTexture.isNull() || mReflectionProbeCount != count || mReset)      { +        gEXRImage = nullptr; +          mReset = false;          mReflectionProbeCount = count;          mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); @@ -1340,7 +1468,6 @@ void LLReflectionMapManager::initReflectionMaps()          mDefaultProbe->mComplete = default_complete;          touch_default_probe(mDefaultProbe); -      }      if (mVertexBuffer.isNull()) diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 0fee99eefc..5c0651bc24 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -87,7 +87,8 @@ public:      void reset();      // pause all updates other than the default probe -    void pause(); +    // duration - number of seconds to pause (default 10) +    void pause(F32 duration = 10.f);      // unpause (see pause)      void resume(); @@ -208,5 +209,6 @@ private:      // if true, only update the default probe      bool mPaused = false; +    F32 mResumeTime = 0.f;  }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d5e4de03a9..c50ae2e153 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7890,6 +7890,19 @@ class LLAdvancedClickRenderBenchmark: public view_listener_t  	}  }; +void hdri_preview(); + +class LLAdvancedClickHDRIPreview: public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        // open personal lighting floater when previewing an HDRI (keeps HDRI from implicitly unloading when opening build tools) +        LLFloaterReg::showInstance("env_adjust_snapshot"); +        hdri_preview(); +        return true; +    } +}; +  // these are used in the gl menus to set control values that require shader recompilation  class LLToggleShaderControl : public view_listener_t  { @@ -9529,6 +9542,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");  	view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");  	view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); +    view_listener_t::addMenu(new LLAdvancedClickHDRIPreview(), "Advanced.ClickHDRIPreview");  	view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");      view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 354cc79036..dc20f035c9 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -201,6 +201,7 @@ LLGLSLShader			gLuminanceProgram;  LLGLSLShader			gFXAAProgram;  LLGLSLShader			gDeferredPostNoDoFProgram;  LLGLSLShader			gDeferredWLSkyProgram; +LLGLSLShader            gEnvironmentMapProgram;  LLGLSLShader			gDeferredWLCloudProgram;  LLGLSLShader			gDeferredWLSunProgram;  LLGLSLShader			gDeferredWLMoonProgram; @@ -315,6 +316,7 @@ void LLViewerShaderMgr::finalizeShaderList()      mShaderList.push_back(&gDeferredEmissiveProgram);      mShaderList.push_back(&gDeferredAvatarEyesProgram);      mShaderList.push_back(&gDeferredAvatarAlphaProgram); +    mShaderList.push_back(&gEnvironmentMapProgram);      mShaderList.push_back(&gDeferredWLSkyProgram);      mShaderList.push_back(&gDeferredWLCloudProgram);      mShaderList.push_back(&gDeferredWLMoonProgram); @@ -987,6 +989,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gNoPostGammaCorrectProgram.unload();          gLegacyPostGammaCorrectProgram.unload();  		gFXAAProgram.unload(); +        gEnvironmentMapProgram.unload();  		gDeferredWLSkyProgram.unload();  		gDeferredWLCloudProgram.unload();          gDeferredWLSunProgram.unload(); @@ -2268,6 +2271,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		llassert(success);  	} +    if (success) +    { +        gEnvironmentMapProgram.mName = "Environment Map Program"; +        gEnvironmentMapProgram.mShaderFiles.clear(); +        gEnvironmentMapProgram.mFeatures.calculatesAtmospherics = true; +        gEnvironmentMapProgram.mFeatures.hasAtmospherics = true; +        gEnvironmentMapProgram.mFeatures.hasGamma = true; +        gEnvironmentMapProgram.mFeatures.hasSrgb = true; + +        gEnvironmentMapProgram.clearPermutations(); +        gEnvironmentMapProgram.addPermutation("HAS_HDRI", "1"); +        gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER)); +        gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER)); +        gEnvironmentMapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        gEnvironmentMapProgram.mShaderGroup = LLGLSLShader::SG_SKY; + +        success = gEnvironmentMapProgram.createShader(NULL, NULL); +        llassert(success); +    } +  	if (success)  	{  		gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 2502be6bb1..c51f583ebc 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -266,6 +266,7 @@ extern LLGLSLShader			gHUDFullbrightAlphaMaskAlphaProgram;  extern LLGLSLShader			gDeferredEmissiveProgram;  extern LLGLSLShader			gDeferredAvatarEyesProgram;  extern LLGLSLShader			gDeferredAvatarAlphaProgram; +extern LLGLSLShader         gEnvironmentMapProgram;  extern LLGLSLShader			gDeferredWLSkyProgram;  extern LLGLSLShader			gDeferredWLCloudProgram;  extern LLGLSLShader			gDeferredWLSunProgram; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index fee00eb6f4..35e45c6cd9 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5233,9 +5233,6 @@ U32 LLVOAvatar::renderRigid()  		return 0;  	} -	bool should_alpha_mask = shouldAlphaMask(); -	LLGLState test(GL_ALPHA_TEST, should_alpha_mask); -  	if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())  	{  		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 94ec5c0817..7809129743 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6869,6 +6869,8 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool  	}  } +extern LLPointer<LLImageGL> gEXRImage; +  void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {  	dst->bindTarget();  	// gamma correct lighting @@ -6905,8 +6907,10 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {  		F32 e = llclamp(exposure(), 0.5f, 4.f);  		static LLStaticHashedString s_exposure("exposure"); +        static LLStaticHashedString aces_mix("aces_mix");          shader.uniform1f(s_exposure, e); +        shader.uniform1f(aces_mix, gEXRImage.notNull() ? 0.f : 0.3f);  		mScreenTriangleVB->setBuffer();  		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 4719b091ab..591b5537c7 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2824,6 +2824,12 @@ function="World.EnvPreset"                <menu_item_call.on_click                 function="Advanced.ClickRenderBenchmark" />            </menu_item_call> +          <menu_item_call +           label="HDRI Preview" +           name="HDRI Preview"> +            <menu_item_call.on_click +             function="Advanced.ClickHDRIPreview" /> +          </menu_item_call>          </menu>        <menu          create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index df9f53686e..1a6cadf43e 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9260,6 +9260,15 @@ Unable to upload texture.    </notification>    <notification + icon="alertmodal.tga" + name="CannotLoad" + type="alertmodal"> +    Unable to load [WHAT]. +    [REASON] +    <tag>fail</tag> +  </notification> + +  <notification     icon="alertmodal.tga"     name="CannotUploadMaterial"     type="alertmodal"> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index c7f32d0da9..70121ecc64 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -587,6 +587,14 @@ class Windows_x86_64_Manifest(ViewerManifest):              self.path("libcrypto-1_1-x64.dll")              self.path("libssl-1_1-x64.dll") +            # OpenEXR +            self.path("Iex-3_2.dll") +            self.path("IlmThread-3_2.dll") +            self.path("Imath-3_1.dll") +            self.path("OpenEXR-3_2.dll") +            self.path("OpenEXRCore-3_2.dll") +            self.path("OpenEXRUtil-3_2.dll") +              # HTTP/2              self.path("nghttp2.dll") @@ -934,6 +942,12 @@ class Darwin_x86_64_Manifest(ViewerManifest):                  with self.prefix(src=relpkgdir, dst=""):                      self.path("libndofdev.dylib")                      self.path("libhunspell-*.dylib")    +                    self.path("libIex-3_2.dylib") +                    self.path("libIlmThread-3_2.dylib") +                    self.path("libImath-3_1.dylib") +                    self.path("libOpenEXR-3_2.dylib") +                    self.path("libOpenEXRCore-3_2.dylib") +                    self.path("libOpenEXRUtil-3_2.dylib")                  with self.prefix(src_dst="cursors_mac"):                      self.path("*.tif") | 
