diff --git a/doc/testplans/pbr_terrain_feature_gating.md b/doc/testplans/pbr_terrain_feature_gating.md
new file mode 100644
index 0000000000..13108c1534
--- /dev/null
+++ b/doc/testplans/pbr_terrain_feature_gating.md
@@ -0,0 +1,22 @@
+# PBR Terrain Feature Gating
+
+PBR terrain should have lower detail on lower graphics settings. PBR terrain will also not show emissive textures on some machines (like Macs) which do not support more than 16 textures.
+
+## Triplanar Mapping
+
+Triplanar mapping improves the texture repeats on the sides of terrain slopes.
+
+Availability of Triplanar mapping:
+
+- Medium-High and below: No triplanar mapping
+- High and above: Triplanar mapping
+
+## PBR Textures
+
+At the highest graphics support level, PBR terrain supports all PBR textures.
+
+Availability of PBR textures varies by machine and graphics setting:
+
+- Low: Base color only (looks similar to texture terrain)
+- Medium-Low, and machines that do not support greater than 16 textures such as Macs: All PBR textures enabled except emissive textures.
+- Medium: All PBR textures enabled
diff --git a/doc/testplans/terrain_loading.md b/doc/testplans/terrain_loading.md
new file mode 100644
index 0000000000..b84daf6f73
--- /dev/null
+++ b/doc/testplans/terrain_loading.md
@@ -0,0 +1,4 @@
+- Texture terrain should load
+- PBR terrain should load if enabled
+- Related subsystem: A change to the PBR terrain loading system may affect the texture terrain loading system and vice-versa
+- Related subsystem: Minimaps should load if terrain loads (may take longer)
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 6e05fe4ffd..13c6fa1c5e 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1839,40 +1839,6 @@ bool LLLightParams::fromLLSD(LLSD& sd)
//============================================================================
-LLMirrorParams::LLMirrorParams()
-{
- mType = PARAMS_MIRROR;
-}
-
-BOOL LLMirrorParams::pack(LLDataPacker &dp) const
-{
- return TRUE;
-}
-
-BOOL LLMirrorParams::unpack(LLDataPacker &dp)
-{
- return TRUE;
-}
-
-bool LLMirrorParams::operator==(const LLNetworkData& data) const
-{
- if (data.mType != PARAMS_REFLECTION_PROBE)
- {
- return false;
- }
- return true;
-}
-
-void LLMirrorParams::copy(const LLNetworkData& data)
-{
- const LLMirrorParams *param = (LLMirrorParams*)&data;
- mType = param->mType;
-}
-
-//============================================================================
-
-//============================================================================
-
LLReflectionProbeParams::LLReflectionProbeParams()
{
mType = PARAMS_REFLECTION_PROBE;
@@ -1982,6 +1948,19 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic)
}
}
+
+void LLReflectionProbeParams::setIsMirror(bool is_mirror)
+{
+ if (is_mirror)
+ {
+ mFlags |= FLAG_MIRROR;
+ }
+ else
+ {
+ mFlags &= ~FLAG_MIRROR;
+ }
+}
+
//============================================================================
LLFlexibleObjectData::LLFlexibleObjectData()
{
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index f3a01fbe84..7527d160fd 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -117,7 +117,6 @@ public:
PARAMS_EXTENDED_MESH = 0x70,
PARAMS_RENDER_MATERIAL = 0x80,
PARAMS_REFLECTION_PROBE = 0x90,
- PARAMS_MIRROR = 0x100,
};
public:
@@ -181,16 +180,6 @@ public:
F32 getCutoff() const { return mCutoff; }
};
-class LLMirrorParams : public LLNetworkData
-{
-public:
- LLMirrorParams();
- /*virtual*/ BOOL pack(LLDataPacker &dp) const;
- /*virtual*/ BOOL unpack(LLDataPacker &dp);
- /*virtual*/ bool operator==(const LLNetworkData& data) const;
- /*virtual*/ void copy(const LLNetworkData& data);
-};
-
extern const F32 REFLECTION_PROBE_MIN_AMBIANCE;
extern const F32 REFLECTION_PROBE_MAX_AMBIANCE;
extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE;
@@ -205,6 +194,7 @@ public:
{
FLAG_BOX_VOLUME = 0x01, // use a box influence volume
FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe
+ FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors.
};
protected:
@@ -228,11 +218,13 @@ public:
void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); }
void setIsBox(bool is_box);
void setIsDynamic(bool is_dynamic);
+ void setIsMirror(bool is_mirror);
F32 getAmbiance() const { return mAmbiance; }
F32 getClipDistance() const { return mClipDistance; }
bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; }
bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; }
+ bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; }
};
//-------------------------------------------------
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b30e96c384..b1529c76f0 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -44,6 +44,7 @@ using std::make_pair;
using std::string;
LLShaderMgr * LLShaderMgr::sInstance = NULL;
+bool LLShaderMgr::sMirrorsEnabled = false;
LLShaderMgr::LLShaderMgr()
{
@@ -183,7 +184,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// Attach Fragment Shader Features Next
///////////////////////////////////////
-// NOTE order of shader object attaching is VERY IMPORTANT!!!
+ // NOTE order of shader object attaching is VERY IMPORTANT!!!
+
+ if (!shader->attachFragmentObject("deferred/globalF.glsl"))
+ {
+ return FALSE;
+ }
+
if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred)
{
if (!shader->attachFragmentObject("environment/srgbF.glsl"))
@@ -224,14 +231,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
-
- if (features->hasHeroProbes)
- {
- if (!shader->attachFragmentObject("deferred/heroProbesUtil.glsl"))
- {
- return FALSE;
- }
- }
if (features->hasShadows)
{
@@ -615,6 +614,11 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
}
+ if (sMirrorsEnabled)
+ {
+ extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n");
+ }
+
// Use alpha float to store bit flags
// See: C++: addDeferredAttachment(), shader: frag_data[2]
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 170f7f1a15..97ba4427af 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -381,6 +381,7 @@ public:
bool mShaderCacheInitialized = false;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
+ static bool sMirrorsEnabled;
protected:
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4df7a525f2..778219cd62 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11626,7 +11626,7 @@ Change of this parameter will affect the layout of buttons in notification toast
OctreeAlphaDistanceFactor
- RenderHeroProbeNearClipOffset
-
RenderReflectionProbeVolumes
+ RenderTerrainPBRForce
+
RenderTerrainPBRDetail
+ UIPreviewMaterial
+
UIResizeBarHeight