summaryrefslogtreecommitdiff
path: root/indra/newview/llviewershadermgr.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llviewershadermgr.cpp
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/newview/llviewershadermgr.cpp')
-rw-r--r--indra/newview/llviewershadermgr.cpp5578
1 files changed, 2789 insertions, 2789 deletions
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 4ffe49beae..89286d0ba9 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1,2789 +1,2789 @@
-/**
- * @file llviewershadermgr.cpp
- * @brief Viewer shader manager implementation.
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-
-#include <boost/lexical_cast.hpp>
-
-#include "llfeaturemanager.h"
-#include "llviewershadermgr.h"
-#include "llviewercontrol.h"
-#include "llversioninfo.h"
-
-#include "llrender.h"
-#include "llenvironment.h"
-#include "llerrorcontrol.h"
-#include "llatmosphere.h"
-#include "llworld.h"
-#include "llsky.h"
-
-#include "pipeline.h"
-
-#include "llfile.h"
-#include "llviewerwindow.h"
-#include "llwindow.h"
-
-#include "lljoint.h"
-#include "llskinningutil.h"
-
-static LLStaticHashedString sTexture0("texture0");
-static LLStaticHashedString sTexture1("texture1");
-static LLStaticHashedString sTex0("tex0");
-static LLStaticHashedString sTex1("tex1");
-static LLStaticHashedString sDitherTex("dither_tex");
-static LLStaticHashedString sGlowMap("glowMap");
-static LLStaticHashedString sScreenMap("screenMap");
-
-// Lots of STL stuff in here, using namespace std to keep things more readable
-using std::vector;
-using std::pair;
-using std::make_pair;
-using std::string;
-
-bool LLViewerShaderMgr::sInitialized = false;
-bool LLViewerShaderMgr::sSkipReload = false;
-
-LLVector4 gShinyOrigin;
-
-//utility shaders
-LLGLSLShader gOcclusionProgram;
-LLGLSLShader gSkinnedOcclusionProgram;
-LLGLSLShader gOcclusionCubeProgram;
-LLGLSLShader gGlowCombineProgram;
-LLGLSLShader gReflectionMipProgram;
-LLGLSLShader gGaussianProgram;
-LLGLSLShader gRadianceGenProgram;
-LLGLSLShader gIrradianceGenProgram;
-LLGLSLShader gGlowCombineFXAAProgram;
-LLGLSLShader gTwoTextureCompareProgram;
-LLGLSLShader gOneTextureFilterProgram;
-LLGLSLShader gDebugProgram;
-LLGLSLShader gSkinnedDebugProgram;
-LLGLSLShader gClipProgram;
-LLGLSLShader gAlphaMaskProgram;
-LLGLSLShader gBenchmarkProgram;
-LLGLSLShader gReflectionProbeDisplayProgram;
-LLGLSLShader gCopyProgram;
-LLGLSLShader gCopyDepthProgram;
-
-//object shaders
-LLGLSLShader gObjectPreviewProgram;
-LLGLSLShader gSkinnedObjectPreviewProgram;
-LLGLSLShader gPhysicsPreviewProgram;
-LLGLSLShader gObjectFullbrightAlphaMaskProgram;
-LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
-LLGLSLShader gObjectBumpProgram;
-LLGLSLShader gSkinnedObjectBumpProgram;
-LLGLSLShader gObjectAlphaMaskNoColorProgram;
-
-//environment shaders
-LLGLSLShader gWaterProgram;
-LLGLSLShader gWaterEdgeProgram;
-LLGLSLShader gUnderWaterProgram;
-
-//interface shaders
-LLGLSLShader gHighlightProgram;
-LLGLSLShader gSkinnedHighlightProgram;
-LLGLSLShader gHighlightNormalProgram;
-LLGLSLShader gHighlightSpecularProgram;
-
-LLGLSLShader gDeferredHighlightProgram;
-
-LLGLSLShader gPathfindingProgram;
-LLGLSLShader gPathfindingNoNormalsProgram;
-
-//avatar shader handles
-LLGLSLShader gAvatarProgram;
-LLGLSLShader gAvatarEyeballProgram;
-LLGLSLShader gImpostorProgram;
-
-// Effects Shaders
-LLGLSLShader gGlowProgram;
-LLGLSLShader gGlowExtractProgram;
-LLGLSLShader gPostScreenSpaceReflectionProgram;
-
-// Deferred rendering shaders
-LLGLSLShader gDeferredImpostorProgram;
-LLGLSLShader gDeferredDiffuseProgram;
-LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
-LLGLSLShader gDeferredSkinnedDiffuseProgram;
-LLGLSLShader gDeferredSkinnedBumpProgram;
-LLGLSLShader gDeferredBumpProgram;
-LLGLSLShader gDeferredTerrainProgram;
-LLGLSLShader gDeferredTreeProgram;
-LLGLSLShader gDeferredTreeShadowProgram;
-LLGLSLShader gDeferredSkinnedTreeShadowProgram;
-LLGLSLShader gDeferredAvatarProgram;
-LLGLSLShader gDeferredAvatarAlphaProgram;
-LLGLSLShader gDeferredLightProgram;
-LLGLSLShader gDeferredMultiLightProgram[16];
-LLGLSLShader gDeferredSpotLightProgram;
-LLGLSLShader gDeferredMultiSpotLightProgram;
-LLGLSLShader gDeferredSunProgram;
-LLGLSLShader gHazeProgram;
-LLGLSLShader gHazeWaterProgram;
-LLGLSLShader gDeferredBlurLightProgram;
-LLGLSLShader gDeferredSoftenProgram;
-LLGLSLShader gDeferredShadowProgram;
-LLGLSLShader gDeferredSkinnedShadowProgram;
-LLGLSLShader gDeferredShadowCubeProgram;
-LLGLSLShader gDeferredShadowAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram;
-LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram;
-LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
-LLGLSLShader gDeferredSkinnedShadowGLTFAlphaBlendProgram;
-LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredAvatarShadowProgram;
-LLGLSLShader gDeferredAvatarAlphaShadowProgram;
-LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
-LLGLSLShader gDeferredAlphaProgram;
-LLGLSLShader gHUDAlphaProgram;
-LLGLSLShader gDeferredSkinnedAlphaProgram;
-LLGLSLShader gDeferredAlphaImpostorProgram;
-LLGLSLShader gDeferredSkinnedAlphaImpostorProgram;
-LLGLSLShader gDeferredAvatarEyesProgram;
-LLGLSLShader gDeferredFullbrightProgram;
-LLGLSLShader gHUDFullbrightProgram;
-LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
-LLGLSLShader gHUDFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gDeferredEmissiveProgram;
-LLGLSLShader gDeferredSkinnedEmissiveProgram;
-LLGLSLShader gDeferredPostProgram;
-LLGLSLShader gDeferredCoFProgram;
-LLGLSLShader gDeferredDoFCombineProgram;
-LLGLSLShader gDeferredPostGammaCorrectProgram;
-LLGLSLShader gNoPostGammaCorrectProgram;
-LLGLSLShader gLegacyPostGammaCorrectProgram;
-LLGLSLShader gExposureProgram;
-LLGLSLShader gLuminanceProgram;
-LLGLSLShader gFXAAProgram;
-LLGLSLShader gDeferredPostNoDoFProgram;
-LLGLSLShader gDeferredWLSkyProgram;
-LLGLSLShader gDeferredWLCloudProgram;
-LLGLSLShader gDeferredWLSunProgram;
-LLGLSLShader gDeferredWLMoonProgram;
-LLGLSLShader gDeferredStarProgram;
-LLGLSLShader gDeferredFullbrightShinyProgram;
-LLGLSLShader gHUDFullbrightShinyProgram;
-LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
-LLGLSLShader gDeferredSkinnedFullbrightProgram;
-LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
-LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader gNormalMapGenProgram;
-LLGLSLShader gDeferredGenBrdfLutProgram;
-LLGLSLShader gDeferredBufferVisualProgram;
-
-// Deferred materials shaders
-LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-LLGLSLShader gHUDPBROpaqueProgram;
-LLGLSLShader gPBRGlowProgram;
-LLGLSLShader gPBRGlowSkinnedProgram;
-LLGLSLShader gDeferredPBROpaqueProgram;
-LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
-LLGLSLShader gHUDPBRAlphaProgram;
-LLGLSLShader gDeferredPBRAlphaProgram;
-LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
-
-//helper for making a rigged variant of a given shader
-bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
-{
- riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
- riggedShader.mFeatures = shader.mFeatures;
- riggedShader.mFeatures.hasObjectSkinning = true;
- riggedShader.mDefines = shader.mDefines; // NOTE: Must come before addPermutation
- riggedShader.addPermutation("HAS_SKIN", "1");
- riggedShader.mShaderFiles = shader.mShaderFiles;
- riggedShader.mShaderLevel = shader.mShaderLevel;
- riggedShader.mShaderGroup = shader.mShaderGroup;
-
- shader.mRiggedVariant = &riggedShader;
- return riggedShader.createShader(NULL, NULL);
-}
-
-LLViewerShaderMgr::LLViewerShaderMgr() :
- mShaderLevel(SHADER_COUNT, 0),
- mMaxAvatarShaderLevel(0)
-{
- //ONLY shaders that need WL Param management should be added here
- mShaderList.push_back(&gAvatarProgram);
- mShaderList.push_back(&gWaterProgram);
- mShaderList.push_back(&gWaterEdgeProgram);
- mShaderList.push_back(&gAvatarEyeballProgram);
- mShaderList.push_back(&gImpostorProgram);
- mShaderList.push_back(&gObjectBumpProgram);
- mShaderList.push_back(&gSkinnedObjectBumpProgram);
- mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
- mShaderList.push_back(&gUnderWaterProgram);
- mShaderList.push_back(&gDeferredSunProgram);
- mShaderList.push_back(&gHazeProgram);
- mShaderList.push_back(&gHazeWaterProgram);
- mShaderList.push_back(&gDeferredSoftenProgram);
- mShaderList.push_back(&gDeferredAlphaProgram);
- mShaderList.push_back(&gHUDAlphaProgram);
- mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
- mShaderList.push_back(&gDeferredAlphaImpostorProgram);
- mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
- mShaderList.push_back(&gDeferredFullbrightProgram);
- mShaderList.push_back(&gHUDFullbrightProgram);
- mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
- mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
- mShaderList.push_back(&gDeferredFullbrightShinyProgram);
- mShaderList.push_back(&gHUDFullbrightShinyProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
- mShaderList.push_back(&gDeferredEmissiveProgram);
- mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
- mShaderList.push_back(&gDeferredAvatarEyesProgram);
- mShaderList.push_back(&gDeferredAvatarAlphaProgram);
- mShaderList.push_back(&gDeferredWLSkyProgram);
- mShaderList.push_back(&gDeferredWLCloudProgram);
- mShaderList.push_back(&gDeferredWLMoonProgram);
- mShaderList.push_back(&gDeferredWLSunProgram);
- mShaderList.push_back(&gDeferredPBRAlphaProgram);
- mShaderList.push_back(&gHUDPBRAlphaProgram);
- mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
- mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
- mShaderList.push_back(&gNoPostGammaCorrectProgram);
- mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
-
-}
-
-LLViewerShaderMgr::~LLViewerShaderMgr()
-{
- mShaderLevel.clear();
- mShaderList.clear();
-}
-
-// static
-LLViewerShaderMgr * LLViewerShaderMgr::instance()
-{
- if(NULL == sInstance)
- {
- sInstance = new LLViewerShaderMgr();
- }
-
- return static_cast<LLViewerShaderMgr*>(sInstance);
-}
-
-// static
-void LLViewerShaderMgr::releaseInstance()
-{
- if (sInstance != NULL)
- {
- delete sInstance;
- sInstance = NULL;
- }
-}
-
-void LLViewerShaderMgr::initAttribsAndUniforms(void)
-{
- if (mReservedAttribs.empty())
- {
- LLShaderMgr::initAttribsAndUniforms();
- }
-}
-
-
-//============================================================================
-// Set Levels
-
-S32 LLViewerShaderMgr::getShaderLevel(S32 type)
-{
- return mShaderLevel[type];
-}
-
-//============================================================================
-// Shader Management
-
-void LLViewerShaderMgr::setShaders()
-{
- LL_PROFILE_ZONE_SCOPED;
- //setShaders might be called redundantly by gSavedSettings, so return on reentrance
- static bool reentrance = false;
-
- if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
- {
- return;
- }
-
- if (!gGLManager.mHasRequirements)
- {
- // Viewer will show 'hardware requirements' warning later
- LL_INFOS("ShaderLoading") << "Not supported hardware/software" << LL_ENDL;
- return;
- }
-
- {
- static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true);
- static LLUUID old_cache_version;
- static LLUUID current_cache_version;
- if (current_cache_version.isNull())
- {
- HBXXH128 hash_obj;
- hash_obj.update(LLVersionInfo::instance().getVersion());
- current_cache_version = hash_obj.digest();
-
- old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion"));
- gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
- }
-
- initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
- }
-
- static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
-
- // when using indexed texture rendering, leave some texture units available for shadow and reflection maps
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
-
- reentrance = true;
-
- // Make sure the compiled shader map is cleared before we recompile shaders.
- mVertexShaderObjects.clear();
- mFragmentShaderObjects.clear();
-
- initAttribsAndUniforms();
- gPipeline.releaseGLBuffers();
-
- unloadShaders();
-
- LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
-
- if (gViewerWindow)
- {
- gViewerWindow->setCursor(UI_CURSOR_WAIT);
- }
-
- // Shaders
- LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
- LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
-
- for (S32 i = 0; i < SHADER_COUNT; i++)
- {
- mShaderLevel[i] = 0;
- }
- mMaxAvatarShaderLevel = 0;
-
- LLVertexBuffer::unbind();
-
- llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
-
-
- S32 light_class = 3;
- S32 interface_class = 2;
- S32 env_class = 2;
- S32 obj_class = 2;
- S32 effect_class = 2;
- S32 wl_class = 2;
- S32 water_class = 3;
- S32 deferred_class = 3;
-
- // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
- if (!wl_class || (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()))
- {
- gSky.mVOSkyp->forceSkyUpdate();
- }
-
- // Load lighting shaders
- mShaderLevel[SHADER_LIGHTING] = light_class;
- mShaderLevel[SHADER_INTERFACE] = interface_class;
- mShaderLevel[SHADER_ENVIRONMENT] = env_class;
- mShaderLevel[SHADER_WATER] = water_class;
- mShaderLevel[SHADER_OBJECT] = obj_class;
- mShaderLevel[SHADER_EFFECT] = effect_class;
- mShaderLevel[SHADER_WINDLIGHT] = wl_class;
- mShaderLevel[SHADER_DEFERRED] = deferred_class;
-
- std::string shader_name = loadBasicShaders();
- if (shader_name.empty())
- {
- LL_INFOS("Shader") << "Loaded basic shaders." << LL_ENDL;
- }
- else
- {
- // "ShaderLoading" and "Shader" need to be logged
- LLError::ELevel lvl = LLError::getDefaultLevel();
- LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
- loadBasicShaders();
- LLError::setDefaultLevel(lvl);
- LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
- reentrance = false; // For hygiene only, re-try probably helps nothing
- return;
- }
-
- gPipeline.mShadersLoaded = true;
-
- bool loaded = loadShadersWater();
-
- if (loaded)
- {
- LL_INFOS() << "Loaded water shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
- llassert(loaded);
- }
-
- if (loaded)
- {
- loaded = loadShadersEffects();
- if (loaded)
- {
- LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
- {
- loaded = loadShadersInterface();
- if (loaded)
- {
- LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
- {
- // Load max avatar shaders to set the max level
- mShaderLevel[SHADER_AVATAR] = 3;
- mMaxAvatarShaderLevel = 3;
-
- if (loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- // cloth is a class3 shader
- S32 avatar_class = 1;
-
- // Set the actual level
- mShaderLevel[SHADER_AVATAR] = avatar_class;
-
- loaded = loadShadersAvatar();
- llassert(loaded);
- }
- else
- { //hardware skinning not possible, neither is deferred rendering
- llassert(false); // SHOULD NOT BE POSSIBLE
- }
- }
-
- llassert(loaded);
- loaded = loaded && loadShadersDeferred();
- llassert(loaded);
-
- persistShaderCacheMetadata();
-
- if (gViewerWindow)
- {
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- }
- gPipeline.createGLBuffers();
-
- reentrance = false;
-}
-
-void LLViewerShaderMgr::unloadShaders()
-{
- while (!LLGLSLShader::sInstances.empty())
- {
- LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
- shader->unload();
- }
-
- mShaderLevel[SHADER_LIGHTING] = 0;
- mShaderLevel[SHADER_OBJECT] = 0;
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_ENVIRONMENT] = 0;
- mShaderLevel[SHADER_WATER] = 0;
- mShaderLevel[SHADER_INTERFACE] = 0;
- mShaderLevel[SHADER_EFFECT] = 0;
- mShaderLevel[SHADER_WINDLIGHT] = 0;
-
- gPipeline.mShadersLoaded = false;
-}
-
-std::string LLViewerShaderMgr::loadBasicShaders()
-{
- // Load basic dependency shaders first
- // All of these have to load for any shaders to function
-
- S32 sum_lights_class = 3;
-
-#if LL_DARWIN
- // Work around driver crashes on older Macs when using deferred rendering
- // NORSPEC-59
- //
- if (gGLManager.mIsMobileGF)
- sum_lights_class = 3;
-#endif
-
- // Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
- S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
- sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
-
- // Load the Basic Vertex Shaders at the appropriate level.
- // (in order of shader function call depth for reference purposes, deepest level first)
-
- vector< pair<string, S32> > shaders;
- shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
- shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
- shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
- shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
- if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
- {
- shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
- }
- shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
-
- std::map<std::string, std::string> attribs;
- attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
- std::to_string(LLSkinningUtil::getMaxJointCount());
-
- bool ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
-
- bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
-
- S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3);
-
- S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
-
- if (shadow_detail >= 1)
- {
- attribs["SUN_SHADOW"] = "1";
-
- if (shadow_detail >= 2)
- {
- attribs["SPOT_SHADOW"] = "1";
- }
- }
-
- if (ssr)
- {
- attribs["SSR"] = "1";
- }
-
- if (has_reflection_probes)
- {
- attribs["REFMAP_LEVEL"] = std::to_string(probe_level);
- attribs["REF_SAMPLE_COUNT"] = "32";
- }
-
- LLGLSLShader::sGlobalDefines = attribs;
-
- // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
- for (U32 i = 0; i < shaders.size(); i++)
- {
- // Note usage of GL_VERTEX_SHADER
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
- {
- LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return shaders[i].first;
- }
- }
-
- // Load the Basic Fragment Shaders at the appropriate level.
- // (in order of shader function call depth for reference purposes, deepest level first)
-
- shaders.clear();
- S32 ch = 1;
-
- if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
- { //use indexed texture rendering for GLSL >= 1.30
- ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
- }
-
-
- std::vector<S32> index_channels;
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
-
- for (U32 i = 0; i < shaders.size(); i++)
- {
- // Note usage of GL_FRAGMENT_SHADER
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
- {
- LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return shaders[i].first;
- }
- }
-
- return std::string();
-}
-
-bool LLViewerShaderMgr::loadShadersWater()
-{
- LL_PROFILE_ZONE_SCOPED;
- bool success = true;
- bool terrainWaterSuccess = true;
-
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
- gSavedSettings.getS32("RenderShadowDetail") > 0;
-
- if (mShaderLevel[SHADER_WATER] == 0)
- {
- gWaterProgram.unload();
- gWaterEdgeProgram.unload();
- gUnderWaterProgram.unload();
- return true;
- }
-
- if (success)
- {
- // load water shader
- gWaterProgram.mName = "Water Shader";
- gWaterProgram.mFeatures.calculatesAtmospherics = true;
- gWaterProgram.mFeatures.hasAtmospherics = true;
- gWaterProgram.mFeatures.hasGamma = true;
- gWaterProgram.mFeatures.hasSrgb = true;
- gWaterProgram.mFeatures.hasReflectionProbes = true;
- gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterProgram.mShaderFiles.clear();
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
- gWaterProgram.clearPermutations();
- if (LLPipeline::sRenderTransparentWater)
- {
- gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
- }
-
- if (use_sun_shadow)
- {
- gWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- // load water shader
- gWaterEdgeProgram.mName = "Water Edge Shader";
- gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasGamma = true;
- gWaterEdgeProgram.mFeatures.hasSrgb = true;
- gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
- gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
- gWaterEdgeProgram.clearPermutations();
- gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
- if (LLPipeline::sRenderTransparentWater)
- {
- gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
- }
-
- if (use_sun_shadow)
- {
- gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
- gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterEdgeProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- //load under water vertex shader
- gUnderWaterProgram.mName = "Underwater Shader";
- gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
- gUnderWaterProgram.mFeatures.hasAtmospherics = true;
- gUnderWaterProgram.mShaderFiles.clear();
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
- gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gUnderWaterProgram.clearPermutations();
- if (LLPipeline::sRenderTransparentWater)
- {
- gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
- }
- success = gUnderWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- /// Keep track of water shader levels
- if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
- || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
- {
- mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
- }
-
- if (!success)
- {
- mShaderLevel[SHADER_WATER] = 0;
- return false;
- }
-
- // if we failed to load the terrain water shaders and we need them (using class2 water),
- // then drop down to class1 water.
- if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
- {
- mShaderLevel[SHADER_WATER]--;
- return loadShadersWater();
- }
-
- LLWorld::getInstance()->updateWaterObjects();
-
- return true;
-}
-
-bool LLViewerShaderMgr::loadShadersEffects()
-{
- LL_PROFILE_ZONE_SCOPED;
- bool success = true;
-
- if (mShaderLevel[SHADER_EFFECT] == 0)
- {
- gGlowProgram.unload();
- gGlowExtractProgram.unload();
- return true;
- }
-
- if (success)
- {
- gGlowProgram.mName = "Glow Shader (Post)";
- gGlowProgram.mShaderFiles.clear();
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
- gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
- success = gGlowProgram.createShader(NULL, NULL);
- if (!success)
- {
- LLPipeline::sRenderGlow = false;
- }
- }
-
- if (success)
- {
- const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise");
- const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : "";
-
- gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
- gGlowExtractProgram.mShaderFiles.clear();
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
- gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
-
- if (use_glow_noise)
- {
- gGlowExtractProgram.addPermutation("HAS_NOISE", "1");
- }
-
- success = gGlowExtractProgram.createShader(NULL, NULL);
- if (!success)
- {
- LLPipeline::sRenderGlow = false;
- }
- }
-
- return success;
-
-}
-
-bool LLViewerShaderMgr::loadShadersDeferred()
-{
- LL_PROFILE_ZONE_SCOPED;
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
- gSavedSettings.getS32("RenderShadowDetail") > 0;
-
- if (mShaderLevel[SHADER_DEFERRED] == 0)
- {
- gDeferredTreeProgram.unload();
- gDeferredTreeShadowProgram.unload();
- gDeferredSkinnedTreeShadowProgram.unload();
- gDeferredDiffuseProgram.unload();
- gDeferredSkinnedDiffuseProgram.unload();
- gDeferredDiffuseAlphaMaskProgram.unload();
- gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
- gDeferredBumpProgram.unload();
- gDeferredSkinnedBumpProgram.unload();
- gDeferredImpostorProgram.unload();
- gDeferredTerrainProgram.unload();
- gDeferredLightProgram.unload();
- for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
- {
- gDeferredMultiLightProgram[i].unload();
- }
- gDeferredSpotLightProgram.unload();
- gDeferredMultiSpotLightProgram.unload();
- gDeferredSunProgram.unload();
- gDeferredBlurLightProgram.unload();
- gDeferredSoftenProgram.unload();
- gDeferredShadowProgram.unload();
- gDeferredSkinnedShadowProgram.unload();
- gDeferredShadowCubeProgram.unload();
- gDeferredShadowAlphaMaskProgram.unload();
- gDeferredSkinnedShadowAlphaMaskProgram.unload();
- gDeferredShadowGLTFAlphaMaskProgram.unload();
- gDeferredSkinnedShadowGLTFAlphaMaskProgram.unload();
- gDeferredShadowFullbrightAlphaMaskProgram.unload();
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();
- gDeferredAvatarShadowProgram.unload();
- gDeferredAvatarAlphaShadowProgram.unload();
- gDeferredAvatarAlphaMaskShadowProgram.unload();
- gDeferredAvatarProgram.unload();
- gDeferredAvatarAlphaProgram.unload();
- gDeferredAlphaProgram.unload();
- gHUDAlphaProgram.unload();
- gDeferredSkinnedAlphaProgram.unload();
- gDeferredFullbrightProgram.unload();
- gHUDFullbrightProgram.unload();
- gDeferredFullbrightAlphaMaskProgram.unload();
- gHUDFullbrightAlphaMaskProgram.unload();
- gDeferredFullbrightAlphaMaskAlphaProgram.unload();
- gHUDFullbrightAlphaMaskAlphaProgram.unload();
- gDeferredEmissiveProgram.unload();
- gDeferredSkinnedEmissiveProgram.unload();
- gDeferredAvatarEyesProgram.unload();
- gDeferredPostProgram.unload();
- gDeferredCoFProgram.unload();
- gDeferredDoFCombineProgram.unload();
- gExposureProgram.unload();
- gLuminanceProgram.unload();
- gDeferredPostGammaCorrectProgram.unload();
- gNoPostGammaCorrectProgram.unload();
- gLegacyPostGammaCorrectProgram.unload();
- gFXAAProgram.unload();
- gDeferredWLSkyProgram.unload();
- gDeferredWLCloudProgram.unload();
- gDeferredWLSunProgram.unload();
- gDeferredWLMoonProgram.unload();
- gDeferredStarProgram.unload();
- gDeferredFullbrightShinyProgram.unload();
- gHUDFullbrightShinyProgram.unload();
- gDeferredSkinnedFullbrightShinyProgram.unload();
- gDeferredSkinnedFullbrightProgram.unload();
- gDeferredSkinnedFullbrightAlphaMaskProgram.unload();
- gDeferredSkinnedFullbrightAlphaMaskAlphaProgram.unload();
-
- gDeferredHighlightProgram.unload();
-
- gNormalMapGenProgram.unload();
- gDeferredGenBrdfLutProgram.unload();
- gDeferredBufferVisualProgram.unload();
-
- for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
- {
- gDeferredMaterialProgram[i].unload();
- }
-
- gHUDPBROpaqueProgram.unload();
- gPBRGlowProgram.unload();
- gDeferredPBROpaqueProgram.unload();
- gDeferredSkinnedPBROpaqueProgram.unload();
- gDeferredPBRAlphaProgram.unload();
- gDeferredSkinnedPBRAlphaProgram.unload();
-
- return true;
- }
-
- bool success = true;
-
- if (success)
- {
- gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
- gDeferredHighlightProgram.mShaderFiles.clear();
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDeferredHighlightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
- gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
- gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredDiffuseProgram.mShaderFiles.clear();
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
- success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
- gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
- success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredBumpProgram.mName = "Deferred Bump Shader";
- gDeferredBumpProgram.mFeatures.encodesNormal = true;
- gDeferredBumpProgram.mShaderFiles.clear();
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
- gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
- success = success && gDeferredBumpProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
- gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-
- for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
- {
- if (success)
- {
- mShaderList.push_back(&gDeferredMaterialProgram[i]);
-
- gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
-
- U32 alpha_mode = i & 0x3;
-
- gDeferredMaterialProgram[i].mShaderFiles.clear();
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- gDeferredMaterialProgram[i].clearPermutations();
-
- bool has_normal_map = (i & 0x8) > 0;
- bool has_specular_map = (i & 0x4) > 0;
-
- if (has_normal_map)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
- }
-
- if (has_specular_map)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
- }
-
- gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-
- if (alpha_mode != 0)
- {
- gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
- gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
- }
-
- if (use_sun_shadow)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- bool has_skin = i & 0x10;
- gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
- gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
- gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
- gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
- gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
- gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
- gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true;
-
- if (has_skin)
- {
- gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
- gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
- }
- else
- {
- gDeferredMaterialProgram[i].mRiggedVariant = &gDeferredMaterialProgram[i + 0x10];
- }
-
- success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
- llassert(success);
- }
- }
-
- gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
- gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-
- if (success)
- {
- gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
- gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
- gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
-
- gDeferredPBROpaqueProgram.mShaderFiles.clear();
- gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
- gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
- gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredPBROpaqueProgram.clearPermutations();
-
- success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
- if (success)
- {
- success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
- }
- llassert(success);
- }
-
- if (success)
- {
- gPBRGlowProgram.mName = " PBR Glow Shader";
- gPBRGlowProgram.mFeatures.hasSrgb = true;
- gPBRGlowProgram.mShaderFiles.clear();
- gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowV.glsl", GL_VERTEX_SHADER));
- gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowF.glsl", GL_FRAGMENT_SHADER));
- gPBRGlowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = make_rigged_variant(gPBRGlowProgram, gPBRGlowSkinnedProgram);
- if (success)
- {
- success = gPBRGlowProgram.createShader(NULL, NULL);
- }
- llassert(success);
- }
-
- if (success)
- {
- gHUDPBROpaqueProgram.mName = "HUD PBR Opaque Shader";
- gHUDPBROpaqueProgram.mFeatures.hasSrgb = true;
- gHUDPBROpaqueProgram.mShaderFiles.clear();
- gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
- gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
- gHUDPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gHUDPBROpaqueProgram.clearPermutations();
- gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1");
-
- success = gHUDPBROpaqueProgram.createShader(NULL, NULL);
-
- llassert(success);
- }
-
-
-
- if (success)
- {
- LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
- shader->mName = "Deferred PBR Alpha Shader";
-
- shader->mFeatures.calculatesLighting = false;
- shader->mFeatures.hasLighting = false;
- shader->mFeatures.isAlphaLighting = true;
- shader->mFeatures.hasSrgb = true;
- shader->mFeatures.encodesNormal = true;
- shader->mFeatures.calculatesAtmospherics = true;
- shader->mFeatures.hasAtmospherics = true;
- shader->mFeatures.hasGamma = true;
- shader->mFeatures.hasShadows = use_sun_shadow;
- shader->mFeatures.isDeferred = true; // include deferredUtils
- shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
-
- shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
- shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
-
- shader->clearPermutations();
-
- U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
- shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
- shader->addPermutation("HAS_NORMAL_MAP", "1");
- shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
- shader->addPermutation("HAS_EMISSIVE_MAP", "1");
- shader->addPermutation("USE_VERTEX_COLOR", "1");
-
- if (use_sun_shadow)
- {
- shader->addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram);
- if (success)
- {
- success = shader->createShader(NULL, NULL);
- }
- llassert(success);
-
- // Alpha Shader Hack
- // See: LLRender::syncMatrices()
- shader->mFeatures.calculatesLighting = true;
- shader->mFeatures.hasLighting = true;
-
- shader->mRiggedVariant->mFeatures.calculatesLighting = true;
- shader->mRiggedVariant->mFeatures.hasLighting = true;
- }
-
- if (success)
- {
- LLGLSLShader* shader = &gHUDPBRAlphaProgram;
- shader->mName = "HUD PBR Alpha Shader";
-
- shader->mFeatures.hasSrgb = true;
-
- shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
- shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
-
- shader->clearPermutations();
-
- shader->addPermutation("IS_HUD", "1");
-
- shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = shader->createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredTreeProgram.mName = "Deferred Tree Shader";
- gDeferredTreeProgram.mShaderFiles.clear();
- gDeferredTreeProgram.mFeatures.encodesNormal = true;
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredTreeProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
- gDeferredTreeShadowProgram.mShaderFiles.clear();
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
- success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader";
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER));
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
- gDeferredImpostorProgram.mFeatures.hasSrgb = true;
- gDeferredImpostorProgram.mFeatures.encodesNormal = true;
- //gDeferredImpostorProgram.mFeatures.isDeferred = true;
- gDeferredImpostorProgram.mShaderFiles.clear();
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
- gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredImpostorProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredLightProgram.mName = "Deferred Light Shader";
- gDeferredLightProgram.mFeatures.isDeferred = true;
- gDeferredLightProgram.mFeatures.hasShadows = true;
- gDeferredLightProgram.mFeatures.hasSrgb = true;
-
- gDeferredLightProgram.mShaderFiles.clear();
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- gDeferredLightProgram.clearPermutations();
-
- success = gDeferredLightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
- {
- if (success)
- {
- gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
- gDeferredMultiLightProgram[i].mFeatures.isDeferred = true;
- gDeferredMultiLightProgram[i].mFeatures.hasShadows = true;
- gDeferredMultiLightProgram[i].mFeatures.hasSrgb = true;
-
- gDeferredMultiLightProgram[i].clearPermutations();
- gDeferredMultiLightProgram[i].mShaderFiles.clear();
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
-
- success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
- llassert(success);
- }
- }
-
- if (success)
- {
- gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
- gDeferredSpotLightProgram.mShaderFiles.clear();
- gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
- gDeferredSpotLightProgram.mFeatures.isDeferred = true;
- gDeferredSpotLightProgram.mFeatures.hasShadows = true;
-
- gDeferredSpotLightProgram.clearPermutations();
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gDeferredSpotLightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
- gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
- gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true;
- gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
-
- gDeferredMultiSpotLightProgram.clearPermutations();
- gDeferredMultiSpotLightProgram.addPermutation("MULTI_SPOTLIGHT", "1");
- gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- std::string fragment;
- std::string vertex = "deferred/sunLightV.glsl";
-
- bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO");
-
- if (use_ao)
- {
- fragment = "deferred/sunLightSSAOF.glsl";
- }
- else
- {
- fragment = "deferred/sunLightF.glsl";
- if (mShaderLevel[SHADER_DEFERRED] == 1)
- { //no shadows, no SSAO, no frag coord
- vertex = "deferred/sunLightNoFragCoordV.glsl";
- }
- }
-
- gDeferredSunProgram.mName = "Deferred Sun Shader";
- gDeferredSunProgram.mFeatures.isDeferred = true;
- gDeferredSunProgram.mFeatures.hasShadows = true;
- gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
-
- gDeferredSunProgram.mShaderFiles.clear();
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
- gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gDeferredSunProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
- gDeferredBlurLightProgram.mFeatures.isDeferred = true;
-
- gDeferredBlurLightProgram.mShaderFiles.clear();
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gDeferredBlurLightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- for (int i = 0; i < 3 && success; ++i)
- {
- LLGLSLShader* shader = nullptr;
- bool rigged = (i == 1);
- bool hud = (i == 2);
-
- if (hud)
- {
- shader = &gHUDAlphaProgram;
- shader->mName = "HUD Alpha Shader";
- }
- else if (!rigged)
- {
- shader = &gDeferredAlphaProgram;
- shader->mName = "Deferred Alpha Shader";
- shader->mRiggedVariant = &gDeferredSkinnedAlphaProgram;
- }
- else
- {
- shader = &gDeferredSkinnedAlphaProgram;
- shader->mName = "Skinned Deferred Alpha Shader";
- shader->mFeatures.hasObjectSkinning = true;
- }
-
- shader->mFeatures.calculatesLighting = false;
- shader->mFeatures.hasLighting = false;
- shader->mFeatures.isAlphaLighting = true;
- shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- shader->mFeatures.hasSrgb = true;
- shader->mFeatures.encodesNormal = true;
- shader->mFeatures.calculatesAtmospherics = true;
- shader->mFeatures.hasAtmospherics = true;
- shader->mFeatures.hasGamma = true;
- shader->mFeatures.hasShadows = use_sun_shadow;
- shader->mFeatures.hasReflectionProbes = true;
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
-
- shader->clearPermutations();
- shader->addPermutation("USE_VERTEX_COLOR", "1");
- shader->addPermutation("HAS_ALPHA_MASK", "1");
- shader->addPermutation("USE_INDEXED_TEX", "1");
- if (use_sun_shadow)
- {
- shader->addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- if (rigged)
- {
- shader->addPermutation("HAS_SKIN", "1");
- }
-
- if (hud)
- {
- shader->addPermutation("IS_HUD", "1");
- }
-
- shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = shader->createShader(NULL, NULL);
- llassert(success);
-
- // Hack
- shader->mFeatures.calculatesLighting = true;
- shader->mFeatures.hasLighting = true;
- }
- }
-
- if (success)
- {
- LLGLSLShader* shaders[] = {
- &gDeferredAlphaImpostorProgram,
- &gDeferredSkinnedAlphaImpostorProgram
- };
-
- for (int i = 0; i < 2 && success; ++i)
- {
- bool rigged = i == 1;
- LLGLSLShader* shader = shaders[i];
-
- shader->mName = rigged ? "Skinned Deferred Alpha Impostor Shader" : "Deferred Alpha Impostor Shader";
-
- // Begin Hack
- shader->mFeatures.calculatesLighting = false;
- shader->mFeatures.hasLighting = false;
-
- shader->mFeatures.hasSrgb = true;
- shader->mFeatures.isAlphaLighting = true;
- shader->mFeatures.encodesNormal = true;
- shader->mFeatures.hasShadows = use_sun_shadow;
- shader->mFeatures.hasReflectionProbes = true;
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
-
- shader->clearPermutations();
- shader->addPermutation("USE_INDEXED_TEX", "1");
- shader->addPermutation("FOR_IMPOSTOR", "1");
- shader->addPermutation("HAS_ALPHA_MASK", "1");
- shader->addPermutation("USE_VERTEX_COLOR", "1");
- if (rigged)
- {
- shader->mFeatures.hasObjectSkinning = true;
- shader->addPermutation("HAS_SKIN", "1");
- }
-
- if (use_sun_shadow)
- {
- shader->addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
- shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (!rigged)
- {
- shader->mRiggedVariant = shaders[1];
- }
- success = shader->createShader(NULL, NULL);
- llassert(success);
-
- // End Hack
- shader->mFeatures.calculatesLighting = true;
- shader->mFeatures.hasLighting = true;
- }
- }
-
- if (success)
- {
- gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
- gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
- gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true;
- gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
- gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
- gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true;
- gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
-
- gDeferredAvatarEyesProgram.mShaderFiles.clear();
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";
- gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
- gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredFullbrightProgram.mShaderFiles.clear();
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
- success = gDeferredFullbrightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gHUDFullbrightProgram.mName = "HUD Fullbright Shader";
- gHUDFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gHUDFullbrightProgram.mFeatures.hasGamma = true;
- gHUDFullbrightProgram.mFeatures.hasAtmospherics = true;
- gHUDFullbrightProgram.mFeatures.hasSrgb = true;
- gHUDFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gHUDFullbrightProgram.mShaderFiles.clear();
- gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gHUDFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gHUDFullbrightProgram.clearPermutations();
- gHUDFullbrightProgram.addPermutation("IS_HUD", "1");
- success = gHUDFullbrightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
- gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightAlphaMaskProgram.clearPermutations();
- gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
- gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
- success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gHUDFullbrightAlphaMaskProgram.mName = "HUD Fullbright Alpha Masking Shader";
- gHUDFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gHUDFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
- gHUDFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
- gHUDFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
- gHUDFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gHUDFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gHUDFullbrightAlphaMaskProgram.clearPermutations();
- gHUDFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK", "1");
- gHUDFullbrightAlphaMaskProgram.addPermutation("IS_HUD", "1");
- gHUDFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gHUDFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredFullbrightAlphaMaskAlphaProgram.mName = "Deferred Fullbright Alpha Masking Alpha Shader";
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
- gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightAlphaMaskAlphaProgram.clearPermutations();
- gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
- gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
- gDeferredFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredFullbrightAlphaMaskAlphaProgram, gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
- success = success && gDeferredFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gHUDFullbrightAlphaMaskAlphaProgram.mName = "HUD Fullbright Alpha Masking Alpha Shader";
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
- gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
- gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
- gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
- gHUDFullbrightAlphaMaskAlphaProgram.clearPermutations();
- gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
- gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
- gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_HUD", "1");
- gHUDFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = success && gHUDFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
- gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
- gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
- success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
- success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gHUDFullbrightShinyProgram.mName = "HUD FullbrightShiny Shader";
- gHUDFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gHUDFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
- gHUDFullbrightShinyProgram.mFeatures.hasGamma = true;
- gHUDFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gHUDFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gHUDFullbrightShinyProgram.mShaderFiles.clear();
- gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
- gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
- gHUDFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gHUDFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
- gHUDFullbrightShinyProgram.clearPermutations();
- gHUDFullbrightShinyProgram.addPermutation("IS_HUD", "1");
- success = gHUDFullbrightShinyProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
- gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredEmissiveProgram.mFeatures.hasGamma = true;
- gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true;
- gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredEmissiveProgram.mShaderFiles.clear();
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
- gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
- success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSoftenProgram.mName = "Deferred Soften Shader";
- gDeferredSoftenProgram.mShaderFiles.clear();
- gDeferredSoftenProgram.mFeatures.hasSrgb = true;
- gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
- gDeferredSoftenProgram.mFeatures.hasGamma = true;
- gDeferredSoftenProgram.mFeatures.isDeferred = true;
- gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
- gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
-
- gDeferredSoftenProgram.clearPermutations();
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
-
- gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- if (use_sun_shadow)
- {
- gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
- { //if using SSAO, take screen space light map into account as if shadows are enabled
- gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
- gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
- }
-
- success = gDeferredSoftenProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gHazeProgram.mName = "Haze Shader";
- gHazeProgram.mShaderFiles.clear();
- gHazeProgram.mFeatures.hasSrgb = true;
- gHazeProgram.mFeatures.calculatesAtmospherics = true;
- gHazeProgram.mFeatures.hasAtmospherics = true;
- gHazeProgram.mFeatures.hasGamma = true;
- gHazeProgram.mFeatures.isDeferred = true;
- gHazeProgram.mFeatures.hasShadows = use_sun_shadow;
- gHazeProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
-
- gHazeProgram.clearPermutations();
- gHazeProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
- gHazeProgram.mShaderFiles.push_back(make_pair("deferred/hazeF.glsl", GL_FRAGMENT_SHADER));
-
- gHazeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gHazeProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
-
- if (success)
- {
- gHazeWaterProgram.mName = "Water Haze Shader";
- gHazeWaterProgram.mShaderFiles.clear();
- gHazeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gHazeWaterProgram.mFeatures.hasSrgb = true;
- gHazeWaterProgram.mFeatures.calculatesAtmospherics = true;
- gHazeWaterProgram.mFeatures.hasAtmospherics = true;
- gHazeWaterProgram.mFeatures.hasGamma = true;
- gHazeWaterProgram.mFeatures.isDeferred = true;
- gHazeWaterProgram.mFeatures.hasShadows = use_sun_shadow;
- gHazeWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
-
- gHazeWaterProgram.clearPermutations();
- gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeV.glsl", GL_VERTEX_SHADER));
- gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeF.glsl", GL_FRAGMENT_SHADER));
-
- gHazeWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gHazeWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
-
- if (success)
- {
- gDeferredShadowProgram.mName = "Deferred Shadow Shader";
- gDeferredShadowProgram.mShaderFiles.clear();
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
- success = gDeferredShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedShadowProgram.mName = "Deferred Skinned Shadow Shader";
- gDeferredSkinnedShadowProgram.mFeatures.isDeferred = true;
- gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
- gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER));
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
- success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
- gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
- gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
- gDeferredShadowCubeProgram.mShaderFiles.clear();
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
- // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
- gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader";
- gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
-
- gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredShadowFullbrightAlphaMaskProgram, gDeferredSkinnedShadowFullbrightAlphaMaskProgram);
- success = success && gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
- gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-
- gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = make_rigged_variant(gDeferredShadowAlphaMaskProgram, gDeferredSkinnedShadowAlphaMaskProgram);
- success = success && gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
-
- if (success)
- {
- gDeferredShadowGLTFAlphaMaskProgram.mName = "Deferred GLTF Shadow Alpha Mask Shader";
- gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowGLTFAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowGLTFAlphaMaskProgram.clearPermutations();
- success = make_rigged_variant(gDeferredShadowGLTFAlphaMaskProgram, gDeferredSkinnedShadowGLTFAlphaMaskProgram);
- success = success && gDeferredShadowGLTFAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredShadowGLTFAlphaBlendProgram.mName = "Deferred GLTF Shadow Alpha Blend Shader";
- gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.clear();
- gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
- gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaBlendF.glsl", GL_FRAGMENT_SHADER));
- gDeferredShadowGLTFAlphaBlendProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowGLTFAlphaBlendProgram.clearPermutations();
- success = make_rigged_variant(gDeferredShadowGLTFAlphaBlendProgram, gDeferredSkinnedShadowGLTFAlphaBlendProgram);
- success = success && gDeferredShadowGLTFAlphaBlendProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
- gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
-
- gDeferredAvatarShadowProgram.mShaderFiles.clear();
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
- gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
- if (success)
- {
- gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
- gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
- gDeferredTerrainProgram.mFeatures.encodesNormal = true;
- gDeferredTerrainProgram.mFeatures.hasSrgb = true;
- gDeferredTerrainProgram.mFeatures.calculatesLighting = false;
- gDeferredTerrainProgram.mFeatures.hasLighting = false;
- gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
- gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
- gDeferredTerrainProgram.mFeatures.hasGamma = true;
-
- gDeferredTerrainProgram.mShaderFiles.clear();
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
- gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredTerrainProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
- gDeferredAvatarProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarProgram.mFeatures.encodesNormal = true;
- gDeferredAvatarProgram.mShaderFiles.clear();
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";
- gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
- gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true;
- gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
-
- gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
-
- gDeferredAvatarAlphaProgram.clearPermutations();
- gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
- gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
- if (use_sun_shadow)
- {
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
-
- gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
- llassert(success);
-
- gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
- }
-
- if (success)
- {
- gExposureProgram.mName = "Exposure";
- gExposureProgram.mFeatures.hasSrgb = true;
- gExposureProgram.mFeatures.isDeferred = true;
- gExposureProgram.mShaderFiles.clear();
- gExposureProgram.clearPermutations();
- gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
- gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gExposureProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gLuminanceProgram.mName = "Luminance";
- gLuminanceProgram.mShaderFiles.clear();
- gLuminanceProgram.clearPermutations();
- gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER));
- gLuminanceProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gLuminanceProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
- gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
- gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
- gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
- gDeferredPostGammaCorrectProgram.clearPermutations();
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
- gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process";
- gNoPostGammaCorrectProgram.mFeatures.hasSrgb = true;
- gNoPostGammaCorrectProgram.mFeatures.isDeferred = true;
- gNoPostGammaCorrectProgram.mShaderFiles.clear();
- gNoPostGammaCorrectProgram.clearPermutations();
- gNoPostGammaCorrectProgram.addPermutation("NO_POST", "1");
- gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
- gNoPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gNoPostGammaCorrectProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gLegacyPostGammaCorrectProgram.mName = "Legacy Gamma Correction Post Process";
- gLegacyPostGammaCorrectProgram.mFeatures.hasSrgb = true;
- gLegacyPostGammaCorrectProgram.mFeatures.isDeferred = true;
- gLegacyPostGammaCorrectProgram.mShaderFiles.clear();
- gLegacyPostGammaCorrectProgram.clearPermutations();
- gLegacyPostGammaCorrectProgram.addPermutation("LEGACY_GAMMA", "1");
- gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
- gLegacyPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gLegacyPostGammaCorrectProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
-
- if (success && gGLManager.mGLVersion > 3.9f)
- {
- gFXAAProgram.mName = "FXAA Shader";
- gFXAAProgram.mFeatures.isDeferred = true;
- gFXAAProgram.mShaderFiles.clear();
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
- gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gFXAAProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredPostProgram.mName = "Deferred Post Shader";
- gDeferredPostProgram.mFeatures.isDeferred = true;
- gDeferredPostProgram.mShaderFiles.clear();
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
- gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredCoFProgram.mName = "Deferred CoF Shader";
- gDeferredCoFProgram.mShaderFiles.clear();
- gDeferredCoFProgram.mFeatures.isDeferred = true;
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
- gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredCoFProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
- gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
- gDeferredDoFCombineProgram.mShaderFiles.clear();
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
- gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";
- gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
- gDeferredPostNoDoFProgram.mShaderFiles.clear();
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
- gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
- gDeferredWLSkyProgram.mShaderFiles.clear();
- gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLSkyProgram.mFeatures.hasGamma = true;
- gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
-
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
-
- success = gDeferredWLSkyProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
- gDeferredWLCloudProgram.mShaderFiles.clear();
- gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLCloudProgram.mFeatures.hasGamma = true;
- gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
-
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
- success = gDeferredWLCloudProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
- gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLSunProgram.mFeatures.hasGamma = true;
- gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLSunProgram.mFeatures.disableTextureIndex = true;
- gDeferredWLSunProgram.mFeatures.hasSrgb = true;
- gDeferredWLSunProgram.mShaderFiles.clear();
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER));
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gDeferredWLSunProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredWLMoonProgram.mName = "Deferred Windlight Moon Program";
- gDeferredWLMoonProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLMoonProgram.mFeatures.hasGamma = true;
- gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLMoonProgram.mFeatures.hasSrgb = true;
- gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
-
- gDeferredWLMoonProgram.mShaderFiles.clear();
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
- gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
- success = gDeferredWLMoonProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredStarProgram.mName = "Deferred Star Program";
- gDeferredStarProgram.mShaderFiles.clear();
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
- gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
- success = gDeferredStarProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gNormalMapGenProgram.mName = "Normal Map Generation Program";
- gNormalMapGenProgram.mShaderFiles.clear();
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
- gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gNormalMapGenProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
- gDeferredGenBrdfLutProgram.mShaderFiles.clear();
- gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
- gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
- gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
- }
-
- if (success) {
- gPostScreenSpaceReflectionProgram.mName = "Screen Space Reflection Post";
- gPostScreenSpaceReflectionProgram.mShaderFiles.clear();
- gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostV.glsl", GL_VERTEX_SHADER));
- gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostF.glsl", GL_FRAGMENT_SHADER));
- gPostScreenSpaceReflectionProgram.mFeatures.hasScreenSpaceReflections = true;
- gPostScreenSpaceReflectionProgram.mFeatures.isDeferred = true;
- gPostScreenSpaceReflectionProgram.mShaderLevel = 3;
- success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL);
- }
-
- if (success) {
- gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
- gDeferredBufferVisualProgram.mShaderFiles.clear();
- gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
- gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
- gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
- }
-
- return success;
-}
-
-bool LLViewerShaderMgr::loadShadersObject()
-{
- LL_PROFILE_ZONE_SCOPED;
- bool success = true;
-
- if (success)
- {
- gObjectBumpProgram.mName = "Bump Shader";
- gObjectBumpProgram.mFeatures.encodesNormal = true;
- gObjectBumpProgram.mShaderFiles.clear();
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
- gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
- success = success && gObjectBumpProgram.createShader(NULL, NULL);
- if (success)
- { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
- LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
- for (int i = 0; i < 2; ++i)
- {
- shader[i]->bind();
- shader[i]->uniform1i(sTexture0, 0);
- shader[i]->uniform1i(sTexture1, 1);
- shader[i]->unbind();
- }
- }
- }
-
- if (success)
- {
- gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader";
- gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
- gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
- gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
- gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gImpostorProgram.mName = "Impostor Shader";
- gImpostorProgram.mFeatures.disableTextureIndex = true;
- gImpostorProgram.mFeatures.hasSrgb = true;
- gImpostorProgram.mShaderFiles.clear();
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER));
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
- gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gImpostorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectPreviewProgram.mName = "Object Preview Shader";
- gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
- gObjectPreviewProgram.mShaderFiles.clear();
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
- gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram);
- success = gObjectPreviewProgram.createShader(NULL, NULL);
- gObjectPreviewProgram.mFeatures.hasLighting = true;
- gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true;
- }
-
- if (success)
- {
- gPhysicsPreviewProgram.mName = "Preview Physics Shader";
- gPhysicsPreviewProgram.mFeatures.calculatesLighting = false;
- gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false;
- gPhysicsPreviewProgram.mFeatures.hasGamma = false;
- gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false;
- gPhysicsPreviewProgram.mFeatures.hasLighting = false;
- gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
- gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
- gPhysicsPreviewProgram.mShaderFiles.clear();
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
- gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gPhysicsPreviewProgram.createShader(NULL, NULL);
- gPhysicsPreviewProgram.mFeatures.hasLighting = false;
- }
-
- if (!success)
- {
- mShaderLevel[SHADER_OBJECT] = 0;
- return false;
- }
-
- return true;
-}
-
-bool LLViewerShaderMgr::loadShadersAvatar()
-{
- LL_PROFILE_ZONE_SCOPED;
-#if 1 // DEPRECATED -- forward rendering is deprecated
- bool success = true;
-
- if (mShaderLevel[SHADER_AVATAR] == 0)
- {
- gAvatarProgram.unload();
- gAvatarEyeballProgram.unload();
- return true;
- }
-
- if (success)
- {
- gAvatarProgram.mName = "Avatar Shader";
- gAvatarProgram.mFeatures.hasSkinning = true;
- gAvatarProgram.mFeatures.calculatesAtmospherics = true;
- gAvatarProgram.mFeatures.calculatesLighting = true;
- gAvatarProgram.mFeatures.hasGamma = true;
- gAvatarProgram.mFeatures.hasAtmospherics = true;
- gAvatarProgram.mFeatures.hasLighting = true;
- gAvatarProgram.mFeatures.hasAlphaMask = true;
- gAvatarProgram.mFeatures.disableTextureIndex = true;
- gAvatarProgram.mShaderFiles.clear();
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
- gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
- success = gAvatarProgram.createShader(NULL, NULL);
-
- /// Keep track of avatar levels
- if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
- {
- mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
- }
- }
-
- if (success)
- {
- gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
- gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
- gAvatarEyeballProgram.mFeatures.isSpecular = true;
- gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
- gAvatarEyeballProgram.mFeatures.hasGamma = true;
- gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
- gAvatarEyeballProgram.mFeatures.hasLighting = true;
- gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
- gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
- gAvatarEyeballProgram.mShaderFiles.clear();
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
- gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
- success = gAvatarEyeballProgram.createShader(NULL, NULL);
- }
-
- if( !success )
- {
- mShaderLevel[SHADER_AVATAR] = 0;
- mMaxAvatarShaderLevel = 0;
- return false;
- }
-#endif
- return true;
-}
-
-bool LLViewerShaderMgr::loadShadersInterface()
-{
- LL_PROFILE_ZONE_SCOPED;
- bool success = true;
-
- if (success)
- {
- gHighlightProgram.mName = "Highlight Shader";
- gHighlightProgram.mShaderFiles.clear();
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
- success = success && gHighlightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gHighlightNormalProgram.mName = "Highlight Normals Shader";
- gHighlightNormalProgram.mShaderFiles.clear();
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightNormalProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gHighlightSpecularProgram.mName = "Highlight Spec Shader";
- gHighlightSpecularProgram.mShaderFiles.clear();
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
- gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightSpecularProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gUIProgram.mName = "UI Shader";
- gUIProgram.mShaderFiles.clear();
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
- gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gUIProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gPathfindingProgram.mName = "Pathfinding Shader";
- gPathfindingProgram.mShaderFiles.clear();
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
- gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gPathfindingProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
- gPathfindingNoNormalsProgram.mShaderFiles.clear();
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
- gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gGlowCombineProgram.mName = "Glow Combine Shader";
- gGlowCombineProgram.mShaderFiles.clear();
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
- gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gGlowCombineProgram.createShader(NULL, NULL);
- if (success)
- {
- gGlowCombineProgram.bind();
- gGlowCombineProgram.uniform1i(sGlowMap, 0);
- gGlowCombineProgram.uniform1i(sScreenMap, 1);
- gGlowCombineProgram.unbind();
- }
- }
-
- if (success)
- {
- gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
- gGlowCombineFXAAProgram.mShaderFiles.clear();
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
- gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
- if (success)
- {
- gGlowCombineFXAAProgram.bind();
- gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
- gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
- gGlowCombineFXAAProgram.unbind();
- }
- }
-
-#ifdef LL_WINDOWS
- if (success)
- {
- gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
- gTwoTextureCompareProgram.mShaderFiles.clear();
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
- gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gTwoTextureCompareProgram.createShader(NULL, NULL);
- if (success)
- {
- gTwoTextureCompareProgram.bind();
- gTwoTextureCompareProgram.uniform1i(sTex0, 0);
- gTwoTextureCompareProgram.uniform1i(sTex1, 1);
- gTwoTextureCompareProgram.uniform1i(sDitherTex, 2);
- }
- }
-
- if (success)
- {
- gOneTextureFilterProgram.mName = "One Texture Filter Shader";
- gOneTextureFilterProgram.mShaderFiles.clear();
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
- gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gOneTextureFilterProgram.createShader(NULL, NULL);
- if (success)
- {
- gOneTextureFilterProgram.bind();
- gOneTextureFilterProgram.uniform1i(sTex0, 0);
- }
- }
-#endif
-
- if (success)
- {
- gSolidColorProgram.mName = "Solid Color Shader";
- gSolidColorProgram.mShaderFiles.clear();
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
- gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gSolidColorProgram.createShader(NULL, NULL);
- if (success)
- {
- gSolidColorProgram.bind();
- gSolidColorProgram.uniform1i(sTex0, 0);
- gSolidColorProgram.unbind();
- }
- }
-
- if (success)
- {
- gOcclusionProgram.mName = "Occlusion Shader";
- gOcclusionProgram.mShaderFiles.clear();
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
- gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
- success = gOcclusionProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
- gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedOcclusionProgram.mShaderFiles.clear();
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER));
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
- gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
- gOcclusionCubeProgram.mShaderFiles.clear();
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
- gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gOcclusionCubeProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDebugProgram.mName = "Debug Shader";
- gDebugProgram.mShaderFiles.clear();
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
- gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
- gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
- success = success && gDebugProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gClipProgram.mName = "Clip Shader";
- gClipProgram.mShaderFiles.clear();
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
- gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gClipProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gBenchmarkProgram.mName = "Benchmark Shader";
- gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
- gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gBenchmarkProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gReflectionProbeDisplayProgram.mName = "Reflection Probe Display Shader";
- gReflectionProbeDisplayProgram.mFeatures.hasReflectionProbes = true;
- gReflectionProbeDisplayProgram.mFeatures.hasSrgb = true;
- gReflectionProbeDisplayProgram.mFeatures.calculatesAtmospherics = true;
- gReflectionProbeDisplayProgram.mFeatures.hasAtmospherics = true;
- gReflectionProbeDisplayProgram.mFeatures.hasGamma = true;
- gReflectionProbeDisplayProgram.mFeatures.isDeferred = true;
- gReflectionProbeDisplayProgram.mShaderFiles.clear();
- gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeV.glsl", GL_VERTEX_SHADER));
- gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeF.glsl", GL_FRAGMENT_SHADER));
- gReflectionProbeDisplayProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gCopyProgram.mName = "Copy Shader";
- gCopyProgram.mShaderFiles.clear();
- gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
- gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
- gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gCopyProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gCopyDepthProgram.mName = "Copy Depth Shader";
- gCopyDepthProgram.mShaderFiles.clear();
- gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
- gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
- gCopyDepthProgram.clearPermutations();
- gCopyDepthProgram.addPermutation("COPY_DEPTH", "1");
- gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gCopyDepthProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gAlphaMaskProgram.mName = "Alpha Mask Shader";
- gAlphaMaskProgram.mShaderFiles.clear();
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
- gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gReflectionMipProgram.mName = "Reflection Mip Shader";
- gReflectionMipProgram.mFeatures.isDeferred = true;
- gReflectionMipProgram.mFeatures.hasGamma = true;
- gReflectionMipProgram.mFeatures.hasAtmospherics = true;
- gReflectionMipProgram.mFeatures.calculatesAtmospherics = true;
- gReflectionMipProgram.mShaderFiles.clear();
- gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
- gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
- gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gReflectionMipProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gGaussianProgram.mName = "Reflection Mip Shader";
- gGaussianProgram.mFeatures.isDeferred = true;
- gGaussianProgram.mFeatures.hasGamma = true;
- gGaussianProgram.mFeatures.hasAtmospherics = true;
- gGaussianProgram.mFeatures.calculatesAtmospherics = true;
- gGaussianProgram.mShaderFiles.clear();
- gGaussianProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
- gGaussianProgram.mShaderFiles.push_back(make_pair("interface/gaussianF.glsl", GL_FRAGMENT_SHADER));
- gGaussianProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gGaussianProgram.createShader(NULL, NULL);
- }
-
- if (success && gGLManager.mHasCubeMapArray)
- {
- gRadianceGenProgram.mName = "Radiance Gen Shader";
- gRadianceGenProgram.mShaderFiles.clear();
- gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
- gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
- gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gRadianceGenProgram.createShader(NULL, NULL);
- }
-
- if (success && gGLManager.mHasCubeMapArray)
- {
- gIrradianceGenProgram.mName = "Irradiance Gen Shader";
- gIrradianceGenProgram.mShaderFiles.clear();
- gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER));
- gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER));
- gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gIrradianceGenProgram.createShader(NULL, NULL);
- }
-
- if( !success )
- {
- mShaderLevel[SHADER_INTERFACE] = 0;
- return false;
- }
-
- return true;
-}
-
-
-std::string LLViewerShaderMgr::getShaderDirPrefix(void)
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
-}
-
-void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
-{
- LLEnvironment::instance().updateShaderUniforms(shader);
-}
-
-LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const
-{
- return mShaderList.begin();
-}
-
-LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
-{
- return mShaderList.end();
-}
-
+/**
+ * @file llviewershadermgr.cpp
+ * @brief Viewer shader manager implementation.
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "llfeaturemanager.h"
+#include "llviewershadermgr.h"
+#include "llviewercontrol.h"
+#include "llversioninfo.h"
+
+#include "llrender.h"
+#include "llenvironment.h"
+#include "llerrorcontrol.h"
+#include "llatmosphere.h"
+#include "llworld.h"
+#include "llsky.h"
+
+#include "pipeline.h"
+
+#include "llfile.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
+
+#include "lljoint.h"
+#include "llskinningutil.h"
+
+static LLStaticHashedString sTexture0("texture0");
+static LLStaticHashedString sTexture1("texture1");
+static LLStaticHashedString sTex0("tex0");
+static LLStaticHashedString sTex1("tex1");
+static LLStaticHashedString sDitherTex("dither_tex");
+static LLStaticHashedString sGlowMap("glowMap");
+static LLStaticHashedString sScreenMap("screenMap");
+
+// Lots of STL stuff in here, using namespace std to keep things more readable
+using std::vector;
+using std::pair;
+using std::make_pair;
+using std::string;
+
+bool LLViewerShaderMgr::sInitialized = false;
+bool LLViewerShaderMgr::sSkipReload = false;
+
+LLVector4 gShinyOrigin;
+
+//utility shaders
+LLGLSLShader gOcclusionProgram;
+LLGLSLShader gSkinnedOcclusionProgram;
+LLGLSLShader gOcclusionCubeProgram;
+LLGLSLShader gGlowCombineProgram;
+LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gGaussianProgram;
+LLGLSLShader gRadianceGenProgram;
+LLGLSLShader gIrradianceGenProgram;
+LLGLSLShader gGlowCombineFXAAProgram;
+LLGLSLShader gTwoTextureCompareProgram;
+LLGLSLShader gOneTextureFilterProgram;
+LLGLSLShader gDebugProgram;
+LLGLSLShader gSkinnedDebugProgram;
+LLGLSLShader gClipProgram;
+LLGLSLShader gAlphaMaskProgram;
+LLGLSLShader gBenchmarkProgram;
+LLGLSLShader gReflectionProbeDisplayProgram;
+LLGLSLShader gCopyProgram;
+LLGLSLShader gCopyDepthProgram;
+
+//object shaders
+LLGLSLShader gObjectPreviewProgram;
+LLGLSLShader gSkinnedObjectPreviewProgram;
+LLGLSLShader gPhysicsPreviewProgram;
+LLGLSLShader gObjectFullbrightAlphaMaskProgram;
+LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
+LLGLSLShader gObjectBumpProgram;
+LLGLSLShader gSkinnedObjectBumpProgram;
+LLGLSLShader gObjectAlphaMaskNoColorProgram;
+
+//environment shaders
+LLGLSLShader gWaterProgram;
+LLGLSLShader gWaterEdgeProgram;
+LLGLSLShader gUnderWaterProgram;
+
+//interface shaders
+LLGLSLShader gHighlightProgram;
+LLGLSLShader gSkinnedHighlightProgram;
+LLGLSLShader gHighlightNormalProgram;
+LLGLSLShader gHighlightSpecularProgram;
+
+LLGLSLShader gDeferredHighlightProgram;
+
+LLGLSLShader gPathfindingProgram;
+LLGLSLShader gPathfindingNoNormalsProgram;
+
+//avatar shader handles
+LLGLSLShader gAvatarProgram;
+LLGLSLShader gAvatarEyeballProgram;
+LLGLSLShader gImpostorProgram;
+
+// Effects Shaders
+LLGLSLShader gGlowProgram;
+LLGLSLShader gGlowExtractProgram;
+LLGLSLShader gPostScreenSpaceReflectionProgram;
+
+// Deferred rendering shaders
+LLGLSLShader gDeferredImpostorProgram;
+LLGLSLShader gDeferredDiffuseProgram;
+LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
+LLGLSLShader gDeferredSkinnedDiffuseProgram;
+LLGLSLShader gDeferredSkinnedBumpProgram;
+LLGLSLShader gDeferredBumpProgram;
+LLGLSLShader gDeferredTerrainProgram;
+LLGLSLShader gDeferredTreeProgram;
+LLGLSLShader gDeferredTreeShadowProgram;
+LLGLSLShader gDeferredSkinnedTreeShadowProgram;
+LLGLSLShader gDeferredAvatarProgram;
+LLGLSLShader gDeferredAvatarAlphaProgram;
+LLGLSLShader gDeferredLightProgram;
+LLGLSLShader gDeferredMultiLightProgram[16];
+LLGLSLShader gDeferredSpotLightProgram;
+LLGLSLShader gDeferredMultiSpotLightProgram;
+LLGLSLShader gDeferredSunProgram;
+LLGLSLShader gHazeProgram;
+LLGLSLShader gHazeWaterProgram;
+LLGLSLShader gDeferredBlurLightProgram;
+LLGLSLShader gDeferredSoftenProgram;
+LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredSkinnedShadowProgram;
+LLGLSLShader gDeferredShadowCubeProgram;
+LLGLSLShader gDeferredShadowAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram;
+LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
+LLGLSLShader gDeferredSkinnedShadowGLTFAlphaBlendProgram;
+LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredAvatarShadowProgram;
+LLGLSLShader gDeferredAvatarAlphaShadowProgram;
+LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
+LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gHUDAlphaProgram;
+LLGLSLShader gDeferredSkinnedAlphaProgram;
+LLGLSLShader gDeferredAlphaImpostorProgram;
+LLGLSLShader gDeferredSkinnedAlphaImpostorProgram;
+LLGLSLShader gDeferredAvatarEyesProgram;
+LLGLSLShader gDeferredFullbrightProgram;
+LLGLSLShader gHUDFullbrightProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gDeferredEmissiveProgram;
+LLGLSLShader gDeferredSkinnedEmissiveProgram;
+LLGLSLShader gDeferredPostProgram;
+LLGLSLShader gDeferredCoFProgram;
+LLGLSLShader gDeferredDoFCombineProgram;
+LLGLSLShader gDeferredPostGammaCorrectProgram;
+LLGLSLShader gNoPostGammaCorrectProgram;
+LLGLSLShader gLegacyPostGammaCorrectProgram;
+LLGLSLShader gExposureProgram;
+LLGLSLShader gLuminanceProgram;
+LLGLSLShader gFXAAProgram;
+LLGLSLShader gDeferredPostNoDoFProgram;
+LLGLSLShader gDeferredWLSkyProgram;
+LLGLSLShader gDeferredWLCloudProgram;
+LLGLSLShader gDeferredWLSunProgram;
+LLGLSLShader gDeferredWLMoonProgram;
+LLGLSLShader gDeferredStarProgram;
+LLGLSLShader gDeferredFullbrightShinyProgram;
+LLGLSLShader gHUDFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightProgram;
+LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gDeferredGenBrdfLutProgram;
+LLGLSLShader gDeferredBufferVisualProgram;
+
+// Deferred materials shaders
+LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gHUDPBROpaqueProgram;
+LLGLSLShader gPBRGlowProgram;
+LLGLSLShader gPBRGlowSkinnedProgram;
+LLGLSLShader gDeferredPBROpaqueProgram;
+LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
+LLGLSLShader gHUDPBRAlphaProgram;
+LLGLSLShader gDeferredPBRAlphaProgram;
+LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
+
+//helper for making a rigged variant of a given shader
+bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
+{
+ riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
+ riggedShader.mFeatures = shader.mFeatures;
+ riggedShader.mFeatures.hasObjectSkinning = true;
+ riggedShader.mDefines = shader.mDefines; // NOTE: Must come before addPermutation
+ riggedShader.addPermutation("HAS_SKIN", "1");
+ riggedShader.mShaderFiles = shader.mShaderFiles;
+ riggedShader.mShaderLevel = shader.mShaderLevel;
+ riggedShader.mShaderGroup = shader.mShaderGroup;
+
+ shader.mRiggedVariant = &riggedShader;
+ return riggedShader.createShader(NULL, NULL);
+}
+
+LLViewerShaderMgr::LLViewerShaderMgr() :
+ mShaderLevel(SHADER_COUNT, 0),
+ mMaxAvatarShaderLevel(0)
+{
+ //ONLY shaders that need WL Param management should be added here
+ mShaderList.push_back(&gAvatarProgram);
+ mShaderList.push_back(&gWaterProgram);
+ mShaderList.push_back(&gWaterEdgeProgram);
+ mShaderList.push_back(&gAvatarEyeballProgram);
+ mShaderList.push_back(&gImpostorProgram);
+ mShaderList.push_back(&gObjectBumpProgram);
+ mShaderList.push_back(&gSkinnedObjectBumpProgram);
+ mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
+ mShaderList.push_back(&gUnderWaterProgram);
+ mShaderList.push_back(&gDeferredSunProgram);
+ mShaderList.push_back(&gHazeProgram);
+ mShaderList.push_back(&gHazeWaterProgram);
+ mShaderList.push_back(&gDeferredSoftenProgram);
+ mShaderList.push_back(&gDeferredAlphaProgram);
+ mShaderList.push_back(&gHUDAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
+ mShaderList.push_back(&gDeferredAlphaImpostorProgram);
+ mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
+ mShaderList.push_back(&gDeferredFullbrightProgram);
+ mShaderList.push_back(&gHUDFullbrightProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
+ mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
+ mShaderList.push_back(&gDeferredFullbrightShinyProgram);
+ mShaderList.push_back(&gHUDFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
+ mShaderList.push_back(&gDeferredEmissiveProgram);
+ mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
+ mShaderList.push_back(&gDeferredAvatarEyesProgram);
+ mShaderList.push_back(&gDeferredAvatarAlphaProgram);
+ mShaderList.push_back(&gDeferredWLSkyProgram);
+ mShaderList.push_back(&gDeferredWLCloudProgram);
+ mShaderList.push_back(&gDeferredWLMoonProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredPBRAlphaProgram);
+ mShaderList.push_back(&gHUDPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
+ mShaderList.push_back(&gNoPostGammaCorrectProgram);
+ mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
+
+}
+
+LLViewerShaderMgr::~LLViewerShaderMgr()
+{
+ mShaderLevel.clear();
+ mShaderList.clear();
+}
+
+// static
+LLViewerShaderMgr * LLViewerShaderMgr::instance()
+{
+ if(NULL == sInstance)
+ {
+ sInstance = new LLViewerShaderMgr();
+ }
+
+ return static_cast<LLViewerShaderMgr*>(sInstance);
+}
+
+// static
+void LLViewerShaderMgr::releaseInstance()
+{
+ if (sInstance != NULL)
+ {
+ delete sInstance;
+ sInstance = NULL;
+ }
+}
+
+void LLViewerShaderMgr::initAttribsAndUniforms(void)
+{
+ if (mReservedAttribs.empty())
+ {
+ LLShaderMgr::initAttribsAndUniforms();
+ }
+}
+
+
+//============================================================================
+// Set Levels
+
+S32 LLViewerShaderMgr::getShaderLevel(S32 type)
+{
+ return mShaderLevel[type];
+}
+
+//============================================================================
+// Shader Management
+
+void LLViewerShaderMgr::setShaders()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //setShaders might be called redundantly by gSavedSettings, so return on reentrance
+ static bool reentrance = false;
+
+ if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
+ {
+ return;
+ }
+
+ if (!gGLManager.mHasRequirements)
+ {
+ // Viewer will show 'hardware requirements' warning later
+ LL_INFOS("ShaderLoading") << "Not supported hardware/software" << LL_ENDL;
+ return;
+ }
+
+ {
+ static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true);
+ static LLUUID old_cache_version;
+ static LLUUID current_cache_version;
+ if (current_cache_version.isNull())
+ {
+ HBXXH128 hash_obj;
+ hash_obj.update(LLVersionInfo::instance().getVersion());
+ current_cache_version = hash_obj.digest();
+
+ old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion"));
+ gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
+ }
+
+ initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
+ }
+
+ static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+
+ // when using indexed texture rendering, leave some texture units available for shadow and reflection maps
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
+
+ reentrance = true;
+
+ // Make sure the compiled shader map is cleared before we recompile shaders.
+ mVertexShaderObjects.clear();
+ mFragmentShaderObjects.clear();
+
+ initAttribsAndUniforms();
+ gPipeline.releaseGLBuffers();
+
+ unloadShaders();
+
+ LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
+
+ if (gViewerWindow)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ }
+
+ // Shaders
+ LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
+ LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
+
+ for (S32 i = 0; i < SHADER_COUNT; i++)
+ {
+ mShaderLevel[i] = 0;
+ }
+ mMaxAvatarShaderLevel = 0;
+
+ LLVertexBuffer::unbind();
+
+ llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
+
+
+ S32 light_class = 3;
+ S32 interface_class = 2;
+ S32 env_class = 2;
+ S32 obj_class = 2;
+ S32 effect_class = 2;
+ S32 wl_class = 2;
+ S32 water_class = 3;
+ S32 deferred_class = 3;
+
+ // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
+ if (!wl_class || (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()))
+ {
+ gSky.mVOSkyp->forceSkyUpdate();
+ }
+
+ // Load lighting shaders
+ mShaderLevel[SHADER_LIGHTING] = light_class;
+ mShaderLevel[SHADER_INTERFACE] = interface_class;
+ mShaderLevel[SHADER_ENVIRONMENT] = env_class;
+ mShaderLevel[SHADER_WATER] = water_class;
+ mShaderLevel[SHADER_OBJECT] = obj_class;
+ mShaderLevel[SHADER_EFFECT] = effect_class;
+ mShaderLevel[SHADER_WINDLIGHT] = wl_class;
+ mShaderLevel[SHADER_DEFERRED] = deferred_class;
+
+ std::string shader_name = loadBasicShaders();
+ if (shader_name.empty())
+ {
+ LL_INFOS("Shader") << "Loaded basic shaders." << LL_ENDL;
+ }
+ else
+ {
+ // "ShaderLoading" and "Shader" need to be logged
+ LLError::ELevel lvl = LLError::getDefaultLevel();
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ loadBasicShaders();
+ LLError::setDefaultLevel(lvl);
+ LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
+ reentrance = false; // For hygiene only, re-try probably helps nothing
+ return;
+ }
+
+ gPipeline.mShadersLoaded = true;
+
+ bool loaded = loadShadersWater();
+
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded water shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ // Load max avatar shaders to set the max level
+ mShaderLevel[SHADER_AVATAR] = 3;
+ mMaxAvatarShaderLevel = 3;
+
+ if (loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
+ // cloth is a class3 shader
+ S32 avatar_class = 1;
+
+ // Set the actual level
+ mShaderLevel[SHADER_AVATAR] = avatar_class;
+
+ loaded = loadShadersAvatar();
+ llassert(loaded);
+ }
+ else
+ { //hardware skinning not possible, neither is deferred rendering
+ llassert(false); // SHOULD NOT BE POSSIBLE
+ }
+ }
+
+ llassert(loaded);
+ loaded = loaded && loadShadersDeferred();
+ llassert(loaded);
+
+ persistShaderCacheMetadata();
+
+ if (gViewerWindow)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ }
+ gPipeline.createGLBuffers();
+
+ reentrance = false;
+}
+
+void LLViewerShaderMgr::unloadShaders()
+{
+ while (!LLGLSLShader::sInstances.empty())
+ {
+ LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
+ shader->unload();
+ }
+
+ mShaderLevel[SHADER_LIGHTING] = 0;
+ mShaderLevel[SHADER_OBJECT] = 0;
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mShaderLevel[SHADER_WATER] = 0;
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ mShaderLevel[SHADER_EFFECT] = 0;
+ mShaderLevel[SHADER_WINDLIGHT] = 0;
+
+ gPipeline.mShadersLoaded = false;
+}
+
+std::string LLViewerShaderMgr::loadBasicShaders()
+{
+ // Load basic dependency shaders first
+ // All of these have to load for any shaders to function
+
+ S32 sum_lights_class = 3;
+
+#if LL_DARWIN
+ // Work around driver crashes on older Macs when using deferred rendering
+ // NORSPEC-59
+ //
+ if (gGLManager.mIsMobileGF)
+ sum_lights_class = 3;
+#endif
+
+ // Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
+ S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
+ sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
+
+ // Load the Basic Vertex Shaders at the appropriate level.
+ // (in order of shader function call depth for reference purposes, deepest level first)
+
+ vector< pair<string, S32> > shaders;
+ shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
+ shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
+ shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
+ shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
+ if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
+ {
+ shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
+ }
+ shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
+
+ std::map<std::string, std::string> attribs;
+ attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
+ std::to_string(LLSkinningUtil::getMaxJointCount());
+
+ bool ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
+
+ bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
+
+ S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3);
+
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+
+ if (shadow_detail >= 1)
+ {
+ attribs["SUN_SHADOW"] = "1";
+
+ if (shadow_detail >= 2)
+ {
+ attribs["SPOT_SHADOW"] = "1";
+ }
+ }
+
+ if (ssr)
+ {
+ attribs["SSR"] = "1";
+ }
+
+ if (has_reflection_probes)
+ {
+ attribs["REFMAP_LEVEL"] = std::to_string(probe_level);
+ attribs["REF_SAMPLE_COUNT"] = "32";
+ }
+
+ LLGLSLShader::sGlobalDefines = attribs;
+
+ // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
+ }
+ }
+
+ // Load the Basic Fragment Shaders at the appropriate level.
+ // (in order of shader function call depth for reference purposes, deepest level first)
+
+ shaders.clear();
+ S32 ch = 1;
+
+ if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
+ { //use indexed texture rendering for GLSL >= 1.30
+ ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
+ }
+
+
+ std::vector<S32> index_channels;
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+
+ for (U32 i = 0; i < shaders.size(); i++)
+ {
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
+ {
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
+ }
+ }
+
+ return std::string();
+}
+
+bool LLViewerShaderMgr::loadShadersWater()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ bool success = true;
+ bool terrainWaterSuccess = true;
+
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
+
+ if (mShaderLevel[SHADER_WATER] == 0)
+ {
+ gWaterProgram.unload();
+ gWaterEdgeProgram.unload();
+ gUnderWaterProgram.unload();
+ return true;
+ }
+
+ if (success)
+ {
+ // load water shader
+ gWaterProgram.mName = "Water Shader";
+ gWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterProgram.mFeatures.hasAtmospherics = true;
+ gWaterProgram.mFeatures.hasGamma = true;
+ gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasReflectionProbes = true;
+ gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+ gWaterProgram.mShaderFiles.clear();
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ gWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ success = gWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ // load water shader
+ gWaterEdgeProgram.mName = "Water Edge Shader";
+ gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasGamma = true;
+ gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
+ gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
+ gWaterEdgeProgram.mShaderFiles.clear();
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterEdgeProgram.clearPermutations();
+ gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+ gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ success = gWaterEdgeProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ //load under water vertex shader
+ gUnderWaterProgram.mName = "Underwater Shader";
+ gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gUnderWaterProgram.mFeatures.hasAtmospherics = true;
+ gUnderWaterProgram.mShaderFiles.clear();
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
+ gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gUnderWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
+ success = gUnderWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ /// Keep track of water shader levels
+ if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
+ || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
+ {
+ mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
+ }
+
+ if (!success)
+ {
+ mShaderLevel[SHADER_WATER] = 0;
+ return false;
+ }
+
+ // if we failed to load the terrain water shaders and we need them (using class2 water),
+ // then drop down to class1 water.
+ if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
+ {
+ mShaderLevel[SHADER_WATER]--;
+ return loadShadersWater();
+ }
+
+ LLWorld::getInstance()->updateWaterObjects();
+
+ return true;
+}
+
+bool LLViewerShaderMgr::loadShadersEffects()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ bool success = true;
+
+ if (mShaderLevel[SHADER_EFFECT] == 0)
+ {
+ gGlowProgram.unload();
+ gGlowExtractProgram.unload();
+ return true;
+ }
+
+ if (success)
+ {
+ gGlowProgram.mName = "Glow Shader (Post)";
+ gGlowProgram.mShaderFiles.clear();
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
+ gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+ success = gGlowProgram.createShader(NULL, NULL);
+ if (!success)
+ {
+ LLPipeline::sRenderGlow = false;
+ }
+ }
+
+ if (success)
+ {
+ const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise");
+ const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : "";
+
+ gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
+ gGlowExtractProgram.mShaderFiles.clear();
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
+ gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+
+ if (use_glow_noise)
+ {
+ gGlowExtractProgram.addPermutation("HAS_NOISE", "1");
+ }
+
+ success = gGlowExtractProgram.createShader(NULL, NULL);
+ if (!success)
+ {
+ LLPipeline::sRenderGlow = false;
+ }
+ }
+
+ return success;
+
+}
+
+bool LLViewerShaderMgr::loadShadersDeferred()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
+
+ if (mShaderLevel[SHADER_DEFERRED] == 0)
+ {
+ gDeferredTreeProgram.unload();
+ gDeferredTreeShadowProgram.unload();
+ gDeferredSkinnedTreeShadowProgram.unload();
+ gDeferredDiffuseProgram.unload();
+ gDeferredSkinnedDiffuseProgram.unload();
+ gDeferredDiffuseAlphaMaskProgram.unload();
+ gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
+ gDeferredBumpProgram.unload();
+ gDeferredSkinnedBumpProgram.unload();
+ gDeferredImpostorProgram.unload();
+ gDeferredTerrainProgram.unload();
+ gDeferredLightProgram.unload();
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
+ {
+ gDeferredMultiLightProgram[i].unload();
+ }
+ gDeferredSpotLightProgram.unload();
+ gDeferredMultiSpotLightProgram.unload();
+ gDeferredSunProgram.unload();
+ gDeferredBlurLightProgram.unload();
+ gDeferredSoftenProgram.unload();
+ gDeferredShadowProgram.unload();
+ gDeferredSkinnedShadowProgram.unload();
+ gDeferredShadowCubeProgram.unload();
+ gDeferredShadowAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowAlphaMaskProgram.unload();
+ gDeferredShadowGLTFAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowGLTFAlphaMaskProgram.unload();
+ gDeferredShadowFullbrightAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();
+ gDeferredAvatarShadowProgram.unload();
+ gDeferredAvatarAlphaShadowProgram.unload();
+ gDeferredAvatarAlphaMaskShadowProgram.unload();
+ gDeferredAvatarProgram.unload();
+ gDeferredAvatarAlphaProgram.unload();
+ gDeferredAlphaProgram.unload();
+ gHUDAlphaProgram.unload();
+ gDeferredSkinnedAlphaProgram.unload();
+ gDeferredFullbrightProgram.unload();
+ gHUDFullbrightProgram.unload();
+ gDeferredFullbrightAlphaMaskProgram.unload();
+ gHUDFullbrightAlphaMaskProgram.unload();
+ gDeferredFullbrightAlphaMaskAlphaProgram.unload();
+ gHUDFullbrightAlphaMaskAlphaProgram.unload();
+ gDeferredEmissiveProgram.unload();
+ gDeferredSkinnedEmissiveProgram.unload();
+ gDeferredAvatarEyesProgram.unload();
+ gDeferredPostProgram.unload();
+ gDeferredCoFProgram.unload();
+ gDeferredDoFCombineProgram.unload();
+ gExposureProgram.unload();
+ gLuminanceProgram.unload();
+ gDeferredPostGammaCorrectProgram.unload();
+ gNoPostGammaCorrectProgram.unload();
+ gLegacyPostGammaCorrectProgram.unload();
+ gFXAAProgram.unload();
+ gDeferredWLSkyProgram.unload();
+ gDeferredWLCloudProgram.unload();
+ gDeferredWLSunProgram.unload();
+ gDeferredWLMoonProgram.unload();
+ gDeferredStarProgram.unload();
+ gDeferredFullbrightShinyProgram.unload();
+ gHUDFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightProgram.unload();
+ gDeferredSkinnedFullbrightAlphaMaskProgram.unload();
+ gDeferredSkinnedFullbrightAlphaMaskAlphaProgram.unload();
+
+ gDeferredHighlightProgram.unload();
+
+ gNormalMapGenProgram.unload();
+ gDeferredGenBrdfLutProgram.unload();
+ gDeferredBufferVisualProgram.unload();
+
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ gDeferredMaterialProgram[i].unload();
+ }
+
+ gHUDPBROpaqueProgram.unload();
+ gPBRGlowProgram.unload();
+ gDeferredPBROpaqueProgram.unload();
+ gDeferredSkinnedPBROpaqueProgram.unload();
+ gDeferredPBRAlphaProgram.unload();
+ gDeferredSkinnedPBRAlphaProgram.unload();
+
+ return true;
+ }
+
+ bool success = true;
+
+ if (success)
+ {
+ gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
+ gDeferredHighlightProgram.mShaderFiles.clear();
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gDeferredHighlightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
+ gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
+ gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
+ gDeferredDiffuseProgram.mShaderFiles.clear();
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
+ success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
+ gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
+ success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredBumpProgram.mName = "Deferred Bump Shader";
+ gDeferredBumpProgram.mFeatures.encodesNormal = true;
+ gDeferredBumpProgram.mShaderFiles.clear();
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
+ success = success && gDeferredBumpProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ if (success)
+ {
+ mShaderList.push_back(&gDeferredMaterialProgram[i]);
+
+ gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
+
+ U32 alpha_mode = i & 0x3;
+
+ gDeferredMaterialProgram[i].mShaderFiles.clear();
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ gDeferredMaterialProgram[i].clearPermutations();
+
+ bool has_normal_map = (i & 0x8) > 0;
+ bool has_specular_map = (i & 0x4) > 0;
+
+ if (has_normal_map)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+ }
+
+ if (has_specular_map)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
+ }
+
+ gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ bool has_skin = i & 0x10;
+ gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
+ gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
+ gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
+ gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
+ gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
+ gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
+ gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true;
+
+ if (has_skin)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
+ gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+ else
+ {
+ gDeferredMaterialProgram[i].mRiggedVariant = &gDeferredMaterialProgram[i + 0x10];
+ }
+
+ success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
+ llassert(success);
+ }
+ }
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+
+ if (success)
+ {
+ gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
+ gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
+ gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
+
+ gDeferredPBROpaqueProgram.mShaderFiles.clear();
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredPBROpaqueProgram.clearPermutations();
+
+ success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
+ if (success)
+ {
+ success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gPBRGlowProgram.mName = " PBR Glow Shader";
+ gPBRGlowProgram.mFeatures.hasSrgb = true;
+ gPBRGlowProgram.mShaderFiles.clear();
+ gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowV.glsl", GL_VERTEX_SHADER));
+ gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowF.glsl", GL_FRAGMENT_SHADER));
+ gPBRGlowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = make_rigged_variant(gPBRGlowProgram, gPBRGlowSkinnedProgram);
+ if (success)
+ {
+ success = gPBRGlowProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDPBROpaqueProgram.mName = "HUD PBR Opaque Shader";
+ gHUDPBROpaqueProgram.mFeatures.hasSrgb = true;
+ gHUDPBROpaqueProgram.mShaderFiles.clear();
+ gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gHUDPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDPBROpaqueProgram.clearPermutations();
+ gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1");
+
+ success = gHUDPBROpaqueProgram.createShader(NULL, NULL);
+
+ llassert(success);
+ }
+
+
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
+ shader->mName = "Deferred PBR Alpha Shader";
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.isDeferred = true; // include deferredUtils
+ shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ shader->addPermutation("HAS_NORMAL_MAP", "1");
+ shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
+ shader->addPermutation("HAS_EMISSIVE_MAP", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram);
+ if (success)
+ {
+ success = shader->createShader(NULL, NULL);
+ }
+ llassert(success);
+
+ // Alpha Shader Hack
+ // See: LLRender::syncMatrices()
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+
+ shader->mRiggedVariant->mFeatures.calculatesLighting = true;
+ shader->mRiggedVariant->mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gHUDPBRAlphaProgram;
+ shader->mName = "HUD PBR Alpha Shader";
+
+ shader->mFeatures.hasSrgb = true;
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ shader->addPermutation("IS_HUD", "1");
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredTreeProgram.mName = "Deferred Tree Shader";
+ gDeferredTreeProgram.mShaderFiles.clear();
+ gDeferredTreeProgram.mFeatures.encodesNormal = true;
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredTreeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
+ gDeferredTreeShadowProgram.mShaderFiles.clear();
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
+ success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader";
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear();
+ gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
+ gDeferredImpostorProgram.mFeatures.hasSrgb = true;
+ gDeferredImpostorProgram.mFeatures.encodesNormal = true;
+ //gDeferredImpostorProgram.mFeatures.isDeferred = true;
+ gDeferredImpostorProgram.mShaderFiles.clear();
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredImpostorProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredLightProgram.mName = "Deferred Light Shader";
+ gDeferredLightProgram.mFeatures.isDeferred = true;
+ gDeferredLightProgram.mFeatures.hasShadows = true;
+ gDeferredLightProgram.mFeatures.hasSrgb = true;
+
+ gDeferredLightProgram.mShaderFiles.clear();
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ gDeferredLightProgram.clearPermutations();
+
+ success = gDeferredLightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
+ {
+ if (success)
+ {
+ gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mFeatures.isDeferred = true;
+ gDeferredMultiLightProgram[i].mFeatures.hasShadows = true;
+ gDeferredMultiLightProgram[i].mFeatures.hasSrgb = true;
+
+ gDeferredMultiLightProgram[i].clearPermutations();
+ gDeferredMultiLightProgram[i].mShaderFiles.clear();
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+
+ success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+ llassert(success);
+ }
+ }
+
+ if (success)
+ {
+ gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
+ gDeferredSpotLightProgram.mShaderFiles.clear();
+ gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredSpotLightProgram.mFeatures.isDeferred = true;
+ gDeferredSpotLightProgram.mFeatures.hasShadows = true;
+
+ gDeferredSpotLightProgram.clearPermutations();
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredSpotLightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
+ gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true;
+ gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
+
+ gDeferredMultiSpotLightProgram.clearPermutations();
+ gDeferredMultiSpotLightProgram.addPermutation("MULTI_SPOTLIGHT", "1");
+ gDeferredMultiSpotLightProgram.mShaderFiles.clear();
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ std::string fragment;
+ std::string vertex = "deferred/sunLightV.glsl";
+
+ bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO");
+
+ if (use_ao)
+ {
+ fragment = "deferred/sunLightSSAOF.glsl";
+ }
+ else
+ {
+ fragment = "deferred/sunLightF.glsl";
+ if (mShaderLevel[SHADER_DEFERRED] == 1)
+ { //no shadows, no SSAO, no frag coord
+ vertex = "deferred/sunLightNoFragCoordV.glsl";
+ }
+ }
+
+ gDeferredSunProgram.mName = "Deferred Sun Shader";
+ gDeferredSunProgram.mFeatures.isDeferred = true;
+ gDeferredSunProgram.mFeatures.hasShadows = true;
+ gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
+
+ gDeferredSunProgram.mShaderFiles.clear();
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
+ gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredSunProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
+ gDeferredBlurLightProgram.mFeatures.isDeferred = true;
+
+ gDeferredBlurLightProgram.mShaderFiles.clear();
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredBlurLightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ for (int i = 0; i < 3 && success; ++i)
+ {
+ LLGLSLShader* shader = nullptr;
+ bool rigged = (i == 1);
+ bool hud = (i == 2);
+
+ if (hud)
+ {
+ shader = &gHUDAlphaProgram;
+ shader->mName = "HUD Alpha Shader";
+ }
+ else if (!rigged)
+ {
+ shader = &gDeferredAlphaProgram;
+ shader->mName = "Deferred Alpha Shader";
+ shader->mRiggedVariant = &gDeferredSkinnedAlphaProgram;
+ }
+ else
+ {
+ shader = &gDeferredSkinnedAlphaProgram;
+ shader->mName = "Skinned Deferred Alpha Shader";
+ shader->mFeatures.hasObjectSkinning = true;
+ }
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+ shader->addPermutation("HAS_ALPHA_MASK", "1");
+ shader->addPermutation("USE_INDEXED_TEX", "1");
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ if (rigged)
+ {
+ shader->addPermutation("HAS_SKIN", "1");
+ }
+
+ if (hud)
+ {
+ shader->addPermutation("IS_HUD", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
+
+ // Hack
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+ }
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shaders[] = {
+ &gDeferredAlphaImpostorProgram,
+ &gDeferredSkinnedAlphaImpostorProgram
+ };
+
+ for (int i = 0; i < 2 && success; ++i)
+ {
+ bool rigged = i == 1;
+ LLGLSLShader* shader = shaders[i];
+
+ shader->mName = rigged ? "Skinned Deferred Alpha Impostor Shader" : "Deferred Alpha Impostor Shader";
+
+ // Begin Hack
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+ shader->addPermutation("USE_INDEXED_TEX", "1");
+ shader->addPermutation("FOR_IMPOSTOR", "1");
+ shader->addPermutation("HAS_ALPHA_MASK", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+ if (rigged)
+ {
+ shader->mFeatures.hasObjectSkinning = true;
+ shader->addPermutation("HAS_SKIN", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (!rigged)
+ {
+ shader->mRiggedVariant = shaders[1];
+ }
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
+
+ // End Hack
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+ }
+ }
+
+ if (success)
+ {
+ gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
+ gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
+
+ gDeferredAvatarEyesProgram.mShaderFiles.clear();
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";
+ gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightProgram.mShaderFiles.clear();
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
+ success = gDeferredFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDFullbrightProgram.mName = "HUD Fullbright Shader";
+ gHUDFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightProgram.mShaderFiles.clear();
+ gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDFullbrightProgram.clearPermutations();
+ gHUDFullbrightProgram.addPermutation("IS_HUD", "1");
+ success = gHUDFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.clearPermutations();
+ gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
+ success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDFullbrightAlphaMaskProgram.mName = "HUD Fullbright Alpha Masking Shader";
+ gHUDFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightAlphaMaskProgram.clearPermutations();
+ gHUDFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gHUDFullbrightAlphaMaskProgram.addPermutation("IS_HUD", "1");
+ gHUDFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gHUDFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskAlphaProgram.mName = "Deferred Fullbright Alpha Masking Alpha Shader";
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightAlphaMaskAlphaProgram.clearPermutations();
+ gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredFullbrightAlphaMaskAlphaProgram, gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
+ success = success && gDeferredFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDFullbrightAlphaMaskAlphaProgram.mName = "HUD Fullbright Alpha Masking Alpha Shader";
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightAlphaMaskAlphaProgram.clearPermutations();
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_HUD", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = success && gHUDFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
+ gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightShinyProgram.mShaderFiles.clear();
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
+ success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
+ success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDFullbrightShinyProgram.mName = "HUD FullbrightShiny Shader";
+ gHUDFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightShinyProgram.mShaderFiles.clear();
+ gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
+ gHUDFullbrightShinyProgram.clearPermutations();
+ gHUDFullbrightShinyProgram.addPermutation("IS_HUD", "1");
+ success = gHUDFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
+ gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredEmissiveProgram.mFeatures.hasGamma = true;
+ gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true;
+ gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredEmissiveProgram.mShaderFiles.clear();
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
+ success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredSoftenProgram.mName = "Deferred Soften Shader";
+ gDeferredSoftenProgram.mShaderFiles.clear();
+ gDeferredSoftenProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasGamma = true;
+ gDeferredSoftenProgram.mFeatures.isDeferred = true;
+ gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+
+ gDeferredSoftenProgram.clearPermutations();
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
+
+ gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ if (use_sun_shadow)
+ {
+ gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ { //if using SSAO, take screen space light map into account as if shadows are enabled
+ gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
+ gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
+ }
+
+ success = gDeferredSoftenProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHazeProgram.mName = "Haze Shader";
+ gHazeProgram.mShaderFiles.clear();
+ gHazeProgram.mFeatures.hasSrgb = true;
+ gHazeProgram.mFeatures.calculatesAtmospherics = true;
+ gHazeProgram.mFeatures.hasAtmospherics = true;
+ gHazeProgram.mFeatures.hasGamma = true;
+ gHazeProgram.mFeatures.isDeferred = true;
+ gHazeProgram.mFeatures.hasShadows = use_sun_shadow;
+ gHazeProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+
+ gHazeProgram.clearPermutations();
+ gHazeProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gHazeProgram.mShaderFiles.push_back(make_pair("deferred/hazeF.glsl", GL_FRAGMENT_SHADER));
+
+ gHazeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gHazeProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+
+ if (success)
+ {
+ gHazeWaterProgram.mName = "Water Haze Shader";
+ gHazeWaterProgram.mShaderFiles.clear();
+ gHazeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gHazeWaterProgram.mFeatures.hasSrgb = true;
+ gHazeWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gHazeWaterProgram.mFeatures.hasAtmospherics = true;
+ gHazeWaterProgram.mFeatures.hasGamma = true;
+ gHazeWaterProgram.mFeatures.isDeferred = true;
+ gHazeWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+ gHazeWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+
+ gHazeWaterProgram.clearPermutations();
+ gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeV.glsl", GL_VERTEX_SHADER));
+ gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeF.glsl", GL_FRAGMENT_SHADER));
+
+ gHazeWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gHazeWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+
+ if (success)
+ {
+ gDeferredShadowProgram.mName = "Deferred Shadow Shader";
+ gDeferredShadowProgram.mShaderFiles.clear();
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
+ success = gDeferredShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedShadowProgram.mName = "Deferred Skinned Shadow Shader";
+ gDeferredSkinnedShadowProgram.mFeatures.isDeferred = true;
+ gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
+ gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedShadowProgram.mShaderFiles.clear();
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
+ success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+ gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
+ gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
+ gDeferredShadowCubeProgram.mShaderFiles.clear();
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
+ gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader";
+ gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+
+ gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredShadowFullbrightAlphaMaskProgram, gDeferredSkinnedShadowFullbrightAlphaMaskProgram);
+ success = success && gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
+ gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredShadowAlphaMaskProgram, gDeferredSkinnedShadowAlphaMaskProgram);
+ success = success && gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+
+ if (success)
+ {
+ gDeferredShadowGLTFAlphaMaskProgram.mName = "Deferred GLTF Shadow Alpha Mask Shader";
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowGLTFAlphaMaskProgram.clearPermutations();
+ success = make_rigged_variant(gDeferredShadowGLTFAlphaMaskProgram, gDeferredSkinnedShadowGLTFAlphaMaskProgram);
+ success = success && gDeferredShadowGLTFAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowGLTFAlphaBlendProgram.mName = "Deferred GLTF Shadow Alpha Blend Shader";
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.clear();
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaBlendF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowGLTFAlphaBlendProgram.clearPermutations();
+ success = make_rigged_variant(gDeferredShadowGLTFAlphaBlendProgram, gDeferredSkinnedShadowGLTFAlphaBlendProgram);
+ success = success && gDeferredShadowGLTFAlphaBlendProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
+ gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
+
+ gDeferredAvatarShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
+ gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+ if (success)
+ {
+ gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
+ gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
+ gDeferredTerrainProgram.mFeatures.encodesNormal = true;
+ gDeferredTerrainProgram.mFeatures.hasSrgb = true;
+ gDeferredTerrainProgram.mFeatures.calculatesLighting = false;
+ gDeferredTerrainProgram.mFeatures.hasLighting = false;
+ gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
+ gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasGamma = true;
+
+ gDeferredTerrainProgram.mShaderFiles.clear();
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredTerrainProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
+ gDeferredAvatarProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarProgram.mFeatures.encodesNormal = true;
+ gDeferredAvatarProgram.mShaderFiles.clear();
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredAvatarProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";
+ gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
+ gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
+ gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
+
+ gDeferredAvatarAlphaProgram.mShaderFiles.clear();
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
+
+ gDeferredAvatarAlphaProgram.clearPermutations();
+ gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
+ if (use_sun_shadow)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ gExposureProgram.mName = "Exposure";
+ gExposureProgram.mFeatures.hasSrgb = true;
+ gExposureProgram.mFeatures.isDeferred = true;
+ gExposureProgram.mShaderFiles.clear();
+ gExposureProgram.clearPermutations();
+ gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
+ gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gExposureProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gLuminanceProgram.mName = "Luminance";
+ gLuminanceProgram.mShaderFiles.clear();
+ gLuminanceProgram.clearPermutations();
+ gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER));
+ gLuminanceProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gLuminanceProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
+ gDeferredPostGammaCorrectProgram.clearPermutations();
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process";
+ gNoPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gNoPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gNoPostGammaCorrectProgram.mShaderFiles.clear();
+ gNoPostGammaCorrectProgram.clearPermutations();
+ gNoPostGammaCorrectProgram.addPermutation("NO_POST", "1");
+ gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gNoPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gNoPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gLegacyPostGammaCorrectProgram.mName = "Legacy Gamma Correction Post Process";
+ gLegacyPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gLegacyPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gLegacyPostGammaCorrectProgram.mShaderFiles.clear();
+ gLegacyPostGammaCorrectProgram.clearPermutations();
+ gLegacyPostGammaCorrectProgram.addPermutation("LEGACY_GAMMA", "1");
+ gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gLegacyPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gLegacyPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+
+ if (success && gGLManager.mGLVersion > 3.9f)
+ {
+ gFXAAProgram.mName = "FXAA Shader";
+ gFXAAProgram.mFeatures.isDeferred = true;
+ gFXAAProgram.mShaderFiles.clear();
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
+ gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gFXAAProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredPostProgram.mName = "Deferred Post Shader";
+ gDeferredPostProgram.mFeatures.isDeferred = true;
+ gDeferredPostProgram.mShaderFiles.clear();
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredCoFProgram.mName = "Deferred CoF Shader";
+ gDeferredCoFProgram.mShaderFiles.clear();
+ gDeferredCoFProgram.mFeatures.isDeferred = true;
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredCoFProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
+ gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
+ gDeferredDoFCombineProgram.mShaderFiles.clear();
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";
+ gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
+ gDeferredPostNoDoFProgram.mShaderFiles.clear();
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
+ gDeferredWLSkyProgram.mShaderFiles.clear();
+ gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLSkyProgram.mFeatures.hasGamma = true;
+ gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
+
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+
+ success = gDeferredWLSkyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
+ gDeferredWLCloudProgram.mShaderFiles.clear();
+ gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLCloudProgram.mFeatures.hasGamma = true;
+ gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
+
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
+ success = gDeferredWLCloudProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
+ gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLSunProgram.mFeatures.hasGamma = true;
+ gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLSunProgram.mFeatures.disableTextureIndex = true;
+ gDeferredWLSunProgram.mFeatures.hasSrgb = true;
+ gDeferredWLSunProgram.mShaderFiles.clear();
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gDeferredWLSunProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLMoonProgram.mName = "Deferred Windlight Moon Program";
+ gDeferredWLMoonProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLMoonProgram.mFeatures.hasGamma = true;
+ gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLMoonProgram.mFeatures.hasSrgb = true;
+ gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
+
+ gDeferredWLMoonProgram.mShaderFiles.clear();
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
+ success = gDeferredWLMoonProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredStarProgram.mName = "Deferred Star Program";
+ gDeferredStarProgram.mShaderFiles.clear();
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
+ success = gDeferredStarProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gNormalMapGenProgram.mName = "Normal Map Generation Program";
+ gNormalMapGenProgram.mShaderFiles.clear();
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
+ gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gNormalMapGenProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
+ gDeferredGenBrdfLutProgram.mShaderFiles.clear();
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
+ }
+
+ if (success) {
+ gPostScreenSpaceReflectionProgram.mName = "Screen Space Reflection Post";
+ gPostScreenSpaceReflectionProgram.mShaderFiles.clear();
+ gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostV.glsl", GL_VERTEX_SHADER));
+ gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostF.glsl", GL_FRAGMENT_SHADER));
+ gPostScreenSpaceReflectionProgram.mFeatures.hasScreenSpaceReflections = true;
+ gPostScreenSpaceReflectionProgram.mFeatures.isDeferred = true;
+ gPostScreenSpaceReflectionProgram.mShaderLevel = 3;
+ success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL);
+ }
+
+ if (success) {
+ gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
+ gDeferredBufferVisualProgram.mShaderFiles.clear();
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
+ }
+
+ return success;
+}
+
+bool LLViewerShaderMgr::loadShadersObject()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ bool success = true;
+
+ if (success)
+ {
+ gObjectBumpProgram.mName = "Bump Shader";
+ gObjectBumpProgram.mFeatures.encodesNormal = true;
+ gObjectBumpProgram.mShaderFiles.clear();
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
+ success = success && gObjectBumpProgram.createShader(NULL, NULL);
+ if (success)
+ { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
+ LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
+ for (int i = 0; i < 2; ++i)
+ {
+ shader[i]->bind();
+ shader[i]->uniform1i(sTexture0, 0);
+ shader[i]->uniform1i(sTexture1, 1);
+ shader[i]->unbind();
+ }
+ }
+ }
+
+ if (success)
+ {
+ gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader";
+ gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
+ gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gImpostorProgram.mName = "Impostor Shader";
+ gImpostorProgram.mFeatures.disableTextureIndex = true;
+ gImpostorProgram.mFeatures.hasSrgb = true;
+ gImpostorProgram.mShaderFiles.clear();
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
+ gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gImpostorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectPreviewProgram.mName = "Object Preview Shader";
+ gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
+ gObjectPreviewProgram.mShaderFiles.clear();
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
+ gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram);
+ success = gObjectPreviewProgram.createShader(NULL, NULL);
+ gObjectPreviewProgram.mFeatures.hasLighting = true;
+ gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ gPhysicsPreviewProgram.mName = "Preview Physics Shader";
+ gPhysicsPreviewProgram.mFeatures.calculatesLighting = false;
+ gPhysicsPreviewProgram.mFeatures.calculatesAtmospherics = false;
+ gPhysicsPreviewProgram.mFeatures.hasGamma = false;
+ gPhysicsPreviewProgram.mFeatures.hasAtmospherics = false;
+ gPhysicsPreviewProgram.mFeatures.hasLighting = false;
+ gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
+ gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
+ gPhysicsPreviewProgram.mShaderFiles.clear();
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
+ gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gPhysicsPreviewProgram.createShader(NULL, NULL);
+ gPhysicsPreviewProgram.mFeatures.hasLighting = false;
+ }
+
+ if (!success)
+ {
+ mShaderLevel[SHADER_OBJECT] = 0;
+ return false;
+ }
+
+ return true;
+}
+
+bool LLViewerShaderMgr::loadShadersAvatar()
+{
+ LL_PROFILE_ZONE_SCOPED;
+#if 1 // DEPRECATED -- forward rendering is deprecated
+ bool success = true;
+
+ if (mShaderLevel[SHADER_AVATAR] == 0)
+ {
+ gAvatarProgram.unload();
+ gAvatarEyeballProgram.unload();
+ return true;
+ }
+
+ if (success)
+ {
+ gAvatarProgram.mName = "Avatar Shader";
+ gAvatarProgram.mFeatures.hasSkinning = true;
+ gAvatarProgram.mFeatures.calculatesAtmospherics = true;
+ gAvatarProgram.mFeatures.calculatesLighting = true;
+ gAvatarProgram.mFeatures.hasGamma = true;
+ gAvatarProgram.mFeatures.hasAtmospherics = true;
+ gAvatarProgram.mFeatures.hasLighting = true;
+ gAvatarProgram.mFeatures.hasAlphaMask = true;
+ gAvatarProgram.mFeatures.disableTextureIndex = true;
+ gAvatarProgram.mShaderFiles.clear();
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
+ gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
+ success = gAvatarProgram.createShader(NULL, NULL);
+
+ /// Keep track of avatar levels
+ if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
+ {
+ mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
+ }
+ }
+
+ if (success)
+ {
+ gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
+ gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
+ gAvatarEyeballProgram.mFeatures.isSpecular = true;
+ gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
+ gAvatarEyeballProgram.mFeatures.hasGamma = true;
+ gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
+ gAvatarEyeballProgram.mFeatures.hasLighting = true;
+ gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
+ gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
+ gAvatarEyeballProgram.mShaderFiles.clear();
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
+ gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
+ success = gAvatarEyeballProgram.createShader(NULL, NULL);
+ }
+
+ if( !success )
+ {
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mMaxAvatarShaderLevel = 0;
+ return false;
+ }
+#endif
+ return true;
+}
+
+bool LLViewerShaderMgr::loadShadersInterface()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ bool success = true;
+
+ if (success)
+ {
+ gHighlightProgram.mName = "Highlight Shader";
+ gHighlightProgram.mShaderFiles.clear();
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
+ success = success && gHighlightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gHighlightNormalProgram.mName = "Highlight Normals Shader";
+ gHighlightNormalProgram.mShaderFiles.clear();
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gHighlightNormalProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gHighlightSpecularProgram.mName = "Highlight Spec Shader";
+ gHighlightSpecularProgram.mShaderFiles.clear();
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
+ gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gHighlightSpecularProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gUIProgram.mName = "UI Shader";
+ gUIProgram.mShaderFiles.clear();
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
+ gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gUIProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gPathfindingProgram.mName = "Pathfinding Shader";
+ gPathfindingProgram.mShaderFiles.clear();
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
+ gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
+ gPathfindingNoNormalsProgram.mShaderFiles.clear();
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
+ gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gGlowCombineProgram.mName = "Glow Combine Shader";
+ gGlowCombineProgram.mShaderFiles.clear();
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
+ gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGlowCombineProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gGlowCombineProgram.bind();
+ gGlowCombineProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineProgram.uniform1i(sScreenMap, 1);
+ gGlowCombineProgram.unbind();
+ }
+ }
+
+ if (success)
+ {
+ gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
+ gGlowCombineFXAAProgram.mShaderFiles.clear();
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
+ gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gGlowCombineFXAAProgram.bind();
+ gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
+ gGlowCombineFXAAProgram.unbind();
+ }
+ }
+
+#ifdef LL_WINDOWS
+ if (success)
+ {
+ gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
+ gTwoTextureCompareProgram.mShaderFiles.clear();
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
+ gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gTwoTextureCompareProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gTwoTextureCompareProgram.bind();
+ gTwoTextureCompareProgram.uniform1i(sTex0, 0);
+ gTwoTextureCompareProgram.uniform1i(sTex1, 1);
+ gTwoTextureCompareProgram.uniform1i(sDitherTex, 2);
+ }
+ }
+
+ if (success)
+ {
+ gOneTextureFilterProgram.mName = "One Texture Filter Shader";
+ gOneTextureFilterProgram.mShaderFiles.clear();
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
+ gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gOneTextureFilterProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gOneTextureFilterProgram.bind();
+ gOneTextureFilterProgram.uniform1i(sTex0, 0);
+ }
+ }
+#endif
+
+ if (success)
+ {
+ gSolidColorProgram.mName = "Solid Color Shader";
+ gSolidColorProgram.mShaderFiles.clear();
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
+ gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gSolidColorProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gSolidColorProgram.bind();
+ gSolidColorProgram.uniform1i(sTex0, 0);
+ gSolidColorProgram.unbind();
+ }
+ }
+
+ if (success)
+ {
+ gOcclusionProgram.mName = "Occlusion Shader";
+ gOcclusionProgram.mShaderFiles.clear();
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
+ gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
+ success = gOcclusionProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
+ gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedOcclusionProgram.mShaderFiles.clear();
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
+ gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
+ gOcclusionCubeProgram.mShaderFiles.clear();
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
+ gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gOcclusionCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDebugProgram.mName = "Debug Shader";
+ gDebugProgram.mShaderFiles.clear();
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
+ gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
+ gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
+ success = success && gDebugProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gClipProgram.mName = "Clip Shader";
+ gClipProgram.mShaderFiles.clear();
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
+ gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gClipProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gBenchmarkProgram.mName = "Benchmark Shader";
+ gBenchmarkProgram.mShaderFiles.clear();
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
+ gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gBenchmarkProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gReflectionProbeDisplayProgram.mName = "Reflection Probe Display Shader";
+ gReflectionProbeDisplayProgram.mFeatures.hasReflectionProbes = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasSrgb = true;
+ gReflectionProbeDisplayProgram.mFeatures.calculatesAtmospherics = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasAtmospherics = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasGamma = true;
+ gReflectionProbeDisplayProgram.mFeatures.isDeferred = true;
+ gReflectionProbeDisplayProgram.mShaderFiles.clear();
+ gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeV.glsl", GL_VERTEX_SHADER));
+ gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionProbeDisplayProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gCopyProgram.mName = "Copy Shader";
+ gCopyProgram.mShaderFiles.clear();
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gCopyDepthProgram.mName = "Copy Depth Shader";
+ gCopyDepthProgram.mShaderFiles.clear();
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyDepthProgram.clearPermutations();
+ gCopyDepthProgram.addPermutation("COPY_DEPTH", "1");
+ gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyDepthProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gAlphaMaskProgram.mName = "Alpha Mask Shader";
+ gAlphaMaskProgram.mShaderFiles.clear();
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
+ gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gAlphaMaskProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gReflectionMipProgram.mName = "Reflection Mip Shader";
+ gReflectionMipProgram.mFeatures.isDeferred = true;
+ gReflectionMipProgram.mFeatures.hasGamma = true;
+ gReflectionMipProgram.mFeatures.hasAtmospherics = true;
+ gReflectionMipProgram.mFeatures.calculatesAtmospherics = true;
+ gReflectionMipProgram.mShaderFiles.clear();
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionMipProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gGaussianProgram.mName = "Reflection Mip Shader";
+ gGaussianProgram.mFeatures.isDeferred = true;
+ gGaussianProgram.mFeatures.hasGamma = true;
+ gGaussianProgram.mFeatures.hasAtmospherics = true;
+ gGaussianProgram.mFeatures.calculatesAtmospherics = true;
+ gGaussianProgram.mShaderFiles.clear();
+ gGaussianProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gGaussianProgram.mShaderFiles.push_back(make_pair("interface/gaussianF.glsl", GL_FRAGMENT_SHADER));
+ gGaussianProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGaussianProgram.createShader(NULL, NULL);
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gRadianceGenProgram.mName = "Radiance Gen Shader";
+ gRadianceGenProgram.mShaderFiles.clear();
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gRadianceGenProgram.createShader(NULL, NULL);
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gIrradianceGenProgram.mName = "Irradiance Gen Shader";
+ gIrradianceGenProgram.mShaderFiles.clear();
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER));
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gIrradianceGenProgram.createShader(NULL, NULL);
+ }
+
+ if( !success )
+ {
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ return false;
+ }
+
+ return true;
+}
+
+
+std::string LLViewerShaderMgr::getShaderDirPrefix(void)
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
+}
+
+void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
+{
+ LLEnvironment::instance().updateShaderUniforms(shader);
+}
+
+LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const
+{
+ return mShaderList.begin();
+}
+
+LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
+{
+ return mShaderList.end();
+}
+