Merge branch 'release/materials_featurette' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/newview/app_settings/settings.xml
#	indra/newview/lltexturectrl.cpp
#	indra/newview/llviewermenu.cpp
#	indra/newview/llviewerregion.cpp
#	indra/newview/skins/default/xui/en/floater_tools.xml
master
Ansariel 2024-02-12 12:54:03 +01:00
commit 9f2be1de74
70 changed files with 1101 additions and 617 deletions

View File

@ -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

View File

@ -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)

View File

@ -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()
{

View File

@ -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; }
};
//-------------------------------------------------

View File

@ -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

View File

@ -381,6 +381,7 @@ public:
bool mShaderCacheInitialized = false;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
static bool sMirrorsEnabled;
protected:

View File

@ -11626,7 +11626,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>OctreeAlphaDistanceFactor</key>
<map>
<key>Comment</key>
<string>Multiplier on alpha object distance for determining octree node size </string>
<string>Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -11635,7 +11635,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<array>
<real>0.1</real>
<real>0.0</real>
<real>0.0</real>
<real>64.0</real>
</array>
<key>Backup</key>
<integer>0</integer>
@ -13482,18 +13482,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>16</real>
</map>
<key>RenderHeroProbeNearClipOffset</key>
<map>
<key>Comment</key>
<string>Distance offset in meters for hero probes to near clip.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>2.1</real>
<real>8</real>
</map>
<key>RenderReflectionProbeVolumes</key>
<map>
@ -13961,10 +13950,21 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderTerrainPBRForce</key>
<map>
<key>Comment</key>
<string>Force-load PBR terrain if enabled</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderTerrainPBRDetail</key>
<map>
<key>Comment</key>
<string>Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features in accordance with the GLTF specification, which reduces the number of texture binds. Some Intel and Mac graphics drivers do not support more than 16 texture binds. Because PBR terrain exceeds this limit at the highest detail level, reducing texture binds is necessary for compatibility.</string>
<string>Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features, in accordance with the GLTF specification when possible, which reduces the number of texture binds.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -17077,6 +17077,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>2</integer>
</map>
<key>UIPreviewMaterial</key>
<map>
<key>Comment</key>
<string>Whether or not PBR material swatch is enabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<real>0</real>
</map>
<key>UIResizeBarHeight</key>
<map>
<key>Comment</key>

View File

@ -33,11 +33,15 @@ uniform float minimum_alpha;
in vec3 vary_normal;
in vec2 vary_texcoord0;
in vec3 vary_position;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec4 diff = texture(diffuseMap, vary_texcoord0.xy);
if (diff.a < minimum_alpha)

View File

@ -35,6 +35,7 @@ in vec4 weight;
out vec3 vary_normal;
out vec2 vary_texcoord0;
out vec3 vary_position;
void main()
{
@ -57,6 +58,7 @@ void main()
vary_normal = norm;
vary_position = pos.xyz;
gl_Position = projection_matrix * pos;
}

View File

@ -37,11 +37,15 @@ in vec3 vary_mat2;
in vec4 vertex_color;
in vec2 vary_texcoord0;
in vec3 vary_position;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if(col.a < minimum_alpha)

View File

@ -23,6 +23,7 @@
* $/LicenseInfo$
*/
uniform mat4 modelview_matrix;
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
@ -38,11 +39,11 @@ out vec3 vary_mat1;
out vec3 vary_mat2;
out vec4 vertex_color;
out vec2 vary_texcoord0;
out vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
#endif
void main()
@ -52,11 +53,13 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
vary_position = pos;
gl_Position = projection_matrix*vec4(pos, 1.0);
vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
#else
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vec3 n = normalize(normal_matrix * normal);
vec3 t = normalize(normal_matrix * tangent.xyz);

View File

@ -31,14 +31,20 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
in vec3 vary_position;
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;
if (col.a < minimum_alpha)

View File

@ -28,6 +28,7 @@
out vec4 frag_data[4];
in vec3 vary_normal;
in vec3 vary_position;
uniform float minimum_alpha;
@ -36,8 +37,12 @@ in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
if (col.a < minimum_alpha)

View File

@ -32,11 +32,14 @@ uniform sampler2D diffuseMap;
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
in vec3 vary_position;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vertex_color.aaaa; // spec

View File

@ -30,12 +30,15 @@ out vec4 frag_data[4];
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
in vec3 vary_position;
void mirrorClip(vec3 pos);
vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
void main()
{
mirrorClip(vary_position);
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
vec3 spec;

View File

@ -36,13 +36,16 @@ out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
out vec3 vary_position;
void passTextureIndex();
uniform mat4 modelview_matrix;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
#endif
void main()
@ -51,9 +54,11 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
vary_position = pos.xyz;
gl_Position = projection_matrix * pos;
vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#else
vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_normal = normalize(normal_matrix * normal);
#endif

View File

@ -50,9 +50,11 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
#endif
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
#ifdef IS_ALPHA
waterClip(vary_position.xyz);
#endif

View File

@ -0,0 +1,45 @@
/**
* @file class1/deferred/globalF.glsl
*
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2024, 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$
*/
// Global helper functions included in every fragment shader
// DO NOT declare sampler uniforms here as OS X doesn't compile
// them out
uniform float mirror_flag;
uniform vec4 clipPlane;
uniform float clipSign;
void mirrorClip(vec3 pos)
{
if (mirror_flag > 0)
{
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0)
{
discard;
}
}
}

View File

@ -78,9 +78,7 @@ void main()
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
vary_position = pos;
#endif
gl_Position = projection_matrix*vec4(pos,1.0);
@ -127,7 +125,7 @@ void main()
vertex_color = diffuse_color;
#if !defined(HAS_SKIN)
vary_position = (projection_matrix*vec4(position.xyz, 1.0)).xyz;
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
#endif
}

View File

@ -60,34 +60,14 @@ vec3 srgb_to_linear(vec3 c);
uniform vec4 clipPlane;
uniform float clipSign;
uniform float mirror_flag;
void applyClip(vec3 pos)
{
if (mirror_flag > 0)
{
// TODO: make this less branchy
if (clipSign > 0)
{
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0)
{
discard;
}
}
else
{
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0)
{
discard;
}
}
}
}
void mirrorClip(vec3 pos);
uniform mat3 normal_matrix;
void main()
{
applyClip(vary_position);
mirrorClip(vary_position);
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
if (basecolor.a < minimum_alpha)

View File

@ -28,8 +28,9 @@
//deferred opaque implementation
#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
#ifdef HAS_SKIN
uniform mat4 projection_matrix;
mat4 getObjectSkinnedTransform();
#else
@ -59,6 +60,7 @@ out vec4 vertex_color;
out vec3 vary_tangent;
flat out float vary_sign;
out vec3 vary_normal;
out vec3 vary_position;
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
@ -71,10 +73,11 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
vary_position = pos;
gl_Position = projection_matrix*vec4(pos,1.0);
#else
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
//transform vertex
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif

View File

@ -26,6 +26,9 @@
/*[EXTRA_CODE_HERE]*/
#define TERRAIN_PBR_DETAIL_EMISSIVE 0
#define TERRAIN_PBR_DETAIL_OCCLUSION -1
#define TERRAIN_PBR_DETAIL_NORMAL -2
#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
#define TerrainCoord vec4[2]
@ -38,7 +41,6 @@
#define MIX_Z 1 << 5
#define MIX_W 1 << 6
// TODO: Decide if this struct needs to be declared
struct TerrainMix
{
vec4 weight;
@ -47,12 +49,17 @@ struct TerrainMix
TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal);
// TODO: Decide if this struct needs to be declared
struct PBRMix
{
vec4 col; // RGB color with alpha, linear space
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
vec3 orm; // Occlusion, roughness, metallic
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
vec2 rm; // Roughness, metallic
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
vec3 vNt; // Unpacked normal texture sample, vector
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
vec3 emissive; // RGB emissive color, linear space
#endif
@ -63,13 +70,21 @@ PBRMix init_pbr_mix();
PBRMix terrain_sample_and_multiply_pbr(
TerrainCoord terrain_coord
, sampler2D tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, sampler2D tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, sampler2D tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, sampler2D tex_emissive
#endif
, vec4 factor_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, vec3 factor_orm
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, vec2 factor_rm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, vec3 factor_emissive
#endif
@ -81,21 +96,23 @@ out vec4 frag_data[4];
uniform sampler2D alpha_ramp;
// *TODO: More configurable quality level which disables PBR features on machines
// with limited texture availability
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
uniform sampler2D detail_0_base_color;
uniform sampler2D detail_1_base_color;
uniform sampler2D detail_2_base_color;
uniform sampler2D detail_3_base_color;
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
uniform sampler2D detail_0_normal;
uniform sampler2D detail_1_normal;
uniform sampler2D detail_2_normal;
uniform sampler2D detail_3_normal;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
uniform sampler2D detail_0_metallic_roughness;
uniform sampler2D detail_1_metallic_roughness;
uniform sampler2D detail_2_metallic_roughness;
uniform sampler2D detail_3_metallic_roughness;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
uniform sampler2D detail_0_emissive;
uniform sampler2D detail_1_emissive;
@ -104,8 +121,10 @@ uniform sampler2D detail_3_emissive;
#endif
uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
uniform vec4 metallicFactors;
uniform vec4 roughnessFactors;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
uniform vec3[4] emissiveColors;
#endif
@ -139,6 +158,7 @@ void main()
TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
// RGB = Occlusion, Roughness, Metal
// default values, see LLViewerTexture::sDefaultPBRORMImagep
// occlusion 1.0
@ -149,6 +169,13 @@ void main()
orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y);
orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z);
orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w);
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
vec2[4] rm_factors;
rm_factors[0] = vec2(roughnessFactors.x, metallicFactors.x);
rm_factors[1] = vec2(roughnessFactors.y, metallicFactors.y);
rm_factors[2] = vec2(roughnessFactors.z, metallicFactors.z);
rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w);
#endif
PBRMix mix = init_pbr_mix();
PBRMix mix2;
@ -158,13 +185,21 @@ void main()
mix2 = terrain_sample_and_multiply_pbr(
terrain_texcoord
, detail_0_base_color
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, detail_0_metallic_roughness
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, detail_0_normal
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, detail_0_emissive
#endif
, baseColorFactors[0]
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, orm_factors[0]
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, rm_factors[0]
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, emissiveColors[0]
#endif
@ -180,13 +215,21 @@ void main()
mix2 = terrain_sample_and_multiply_pbr(
terrain_texcoord
, detail_1_base_color
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, detail_1_metallic_roughness
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, detail_1_normal
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, detail_1_emissive
#endif
, baseColorFactors[1]
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, orm_factors[1]
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, rm_factors[1]
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, emissiveColors[1]
#endif
@ -202,13 +245,21 @@ void main()
mix2 = terrain_sample_and_multiply_pbr(
terrain_texcoord
, detail_2_base_color
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, detail_2_metallic_roughness
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, detail_2_normal
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, detail_2_emissive
#endif
, baseColorFactors[2]
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, orm_factors[2]
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, rm_factors[2]
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, emissiveColors[2]
#endif
@ -224,13 +275,21 @@ void main()
mix2 = terrain_sample_and_multiply_pbr(
terrain_texcoord
, detail_3_base_color
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, detail_3_metallic_roughness
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, detail_3_normal
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, detail_3_emissive
#endif
, baseColorFactors[3]
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, orm_factors[3]
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, rm_factors[3]
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, emissiveColors[3]
#endif
@ -248,6 +307,7 @@ void main()
}
float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z));
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
// from mikktspace.com
vec3 vNt = mix.vNt;
vec3 vN = vary_normal;
@ -257,15 +317,27 @@ void main()
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
#else
vec3 tnorm = vary_normal;
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
#define emissive mix.emissive
#else
#define emissive vec3(0)
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
#define orm mix.orm
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
#define orm vec3(1.0, mix.rm)
#else
// Matte plastic potato terrain
#define orm vec3(1.0, 1.0, 0.0)
#endif
frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse
frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
frag_data[1] = max(vec4(orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
}

View File

@ -47,6 +47,9 @@
*/
#define TERRAIN_PBR_DETAIL_EMISSIVE 0
#define TERRAIN_PBR_DETAIL_OCCLUSION -1
#define TERRAIN_PBR_DETAIL_NORMAL -2
#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3
in vec3 vary_vertex_normal;
@ -75,8 +78,14 @@ vec3 srgb_to_linear(vec3 c);
struct PBRMix
{
vec4 col; // RGB color with alpha, linear space
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
vec3 orm; // Occlusion, roughness, metallic
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
vec2 rm; // Roughness, metallic
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
vec3 vNt; // Unpacked normal texture sample, vector
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
vec3 emissive; // RGB emissive color, linear space
#endif
@ -86,8 +95,14 @@ PBRMix init_pbr_mix()
{
PBRMix mix;
mix.col = vec4(0);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
mix.orm = vec3(0);
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
mix.rm = vec2(0);
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
mix.vNt = vec3(0);
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
mix.emissive = vec3(0);
#endif
@ -105,8 +120,14 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight)
{
PBRMix mix;
mix.col = mix1.col + (mix2.col * mix2_weight);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
mix.orm = mix1.orm + (mix2.orm * mix2_weight);
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
mix.rm = mix1.rm + (mix2.rm * mix2_weight);
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight);
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight);
#endif
@ -116,8 +137,12 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight)
PBRMix sample_pbr(
vec2 uv
, sampler2D tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, sampler2D tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, sampler2D tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, sampler2D tex_emissive
#endif
@ -126,8 +151,14 @@ PBRMix sample_pbr(
PBRMix mix;
mix.col = texture(tex_col, uv);
mix.col.rgb = srgb_to_linear(mix.col.rgb);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
mix.orm = texture(tex_orm, uv).xyz;
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
mix.rm = texture(tex_orm, uv).yz;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz);
#endif
@ -254,8 +285,12 @@ PBRMix terrain_sample_pbr(
TerrainCoord terrain_coord
, TerrainTriplanar tw
, sampler2D tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, sampler2D tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, sampler2D tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, sampler2D tex_emissive
#endif
@ -272,14 +307,20 @@ PBRMix terrain_sample_pbr(
PBRMix mix_x = sample_pbr(
get_uv_x()
, tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, tex_emissive
#endif
);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
// Triplanar-specific normal texture fix
mix_x.vNt = _t_normal_post_x(mix_x.vNt);
#endif
mix = mix_pbr(mix, mix_x, tw.weight.x);
break;
default:
@ -292,14 +333,20 @@ PBRMix terrain_sample_pbr(
PBRMix mix_y = sample_pbr(
get_uv_y()
, tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, tex_emissive
#endif
);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
// Triplanar-specific normal texture fix
mix_y.vNt = _t_normal_post_y(mix_y.vNt);
#endif
mix = mix_pbr(mix, mix_y, tw.weight.y);
break;
default:
@ -312,15 +359,21 @@ PBRMix terrain_sample_pbr(
PBRMix mix_z = sample_pbr(
get_uv_z()
, tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, tex_emissive
#endif
);
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
// Triplanar-specific normal texture fix
// *NOTE: Bottom face has not been tested
mix_z.vNt = _t_normal_post_z(mix_z.vNt);
#endif
mix = mix_pbr(mix, mix_z, tw.weight.z);
break;
default:
@ -341,7 +394,11 @@ PBRMix terrain_sample_pbr(
PBRMix multiply_factors_pbr(
PBRMix mix_in
, vec4 factor_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, vec3 factor_orm
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, vec2 factor_rm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, vec3 factor_emissive
#endif
@ -349,7 +406,11 @@ PBRMix multiply_factors_pbr(
{
PBRMix mix = mix_in;
mix.col *= factor_col;
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
mix.orm *= factor_orm;
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
mix.rm *= factor_rm;
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
mix.emissive *= factor_emissive;
#endif
@ -359,13 +420,21 @@ PBRMix multiply_factors_pbr(
PBRMix terrain_sample_and_multiply_pbr(
TerrainCoord terrain_coord
, sampler2D tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, sampler2D tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, sampler2D tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, sampler2D tex_emissive
#endif
, vec4 factor_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, vec3 factor_orm
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, vec2 factor_rm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, vec3 factor_emissive
#endif
@ -377,8 +446,12 @@ PBRMix terrain_sample_and_multiply_pbr(
, _t_triplanar()
#endif
, tex_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, tex_orm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)
, tex_vNt
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, tex_emissive
#endif
@ -386,7 +459,11 @@ PBRMix terrain_sample_and_multiply_pbr(
mix = multiply_factors_pbr(mix
, factor_col
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)
, factor_orm
#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
, factor_rm
#endif
#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE)
, factor_emissive
#endif

View File

@ -39,9 +39,11 @@ in vec4 vary_texcoord0;
in vec4 vary_texcoord1;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 position);
void main()
{
mirrorClip(pos);
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
vec4 color0 = texture(detail_0, vary_texcoord0.xy);

View File

@ -25,6 +25,7 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
in vec3 position;
@ -59,7 +60,7 @@ void main()
vec4 t_pos = modelview_projection_matrix * pre_pos;
gl_Position = t_pos;
pos = t_pos.xyz;
pos = (modelview_matrix*pre_pos).xyz;
vary_normal = normalize(normal_matrix * normal);

View File

@ -32,13 +32,16 @@ uniform sampler2D diffuseMap;
in vec4 vertex_color;
in vec3 vary_normal;
in vec2 vary_texcoord0;
in vec3 vary_position;
uniform float minimum_alpha;
vec2 encode_normal(vec3 n);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if (col.a < minimum_alpha)
{

View File

@ -24,6 +24,7 @@
*/
uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
uniform mat3 normal_matrix;
@ -34,11 +35,14 @@ in vec2 texcoord0;
out vec3 vary_normal;
out vec4 vertex_color;
out vec2 vary_texcoord0;
out vec3 vary_position;
void main()
{
//transform vertex
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vary_normal = normalize(normal_matrix * normal);

View File

@ -130,7 +130,7 @@ vec4 prefilterEnvMap(vec3 R)
float totalWeight = 0.0;
float envMapDim = float(textureSize(reflectionProbes, 0).s);
float roughness = mipLevel/max_probe_lod;
int numSamples = max(int(32*roughness), 1);
int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1);
float numMips = max_probe_lod+1;

View File

@ -30,9 +30,13 @@ uniform sampler2D texture1;
in vec2 vary_texcoord0;
in vec2 vary_texcoord1;
in vec3 vary_position;
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
float tex0 = texture(texture0, vary_texcoord0.xy).a;
float tex1 = texture(texture1, vary_texcoord1.xy).a;

View File

@ -23,6 +23,7 @@
* $/LicenseInfo$
*/
uniform mat4 modelview_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
@ -32,11 +33,11 @@ in vec2 texcoord1;
out vec2 vary_texcoord0;
out vec2 vary_texcoord1;
out vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
#endif
void main()
@ -46,8 +47,10 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
vary_position = pos.xyz;
gl_Position = projection_matrix * pos;
#else
vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;

View File

@ -78,6 +78,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
float getAmbientClamp();
void mirrorClip(vec3 pos);
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
@ -167,6 +169,8 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
void main()
{
mirrorClip(vary_position);
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
vec4 pos = vec4(vary_position, 1.0);

View File

@ -90,6 +90,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
void mirrorClip(vec3 pos);
void waterClip(vec3 pos);
void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
@ -156,6 +157,8 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
void main()
{
mirrorClip(vary_position);
vec3 color = vec3(0,0,0);
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;

View File

@ -53,8 +53,11 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
void mirrorClip(vec3 pos);
void main()
{
mirrorClip(vary_position);
#ifdef HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else

View File

@ -45,23 +45,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cs);
uniform vec4 clipPlane;
uniform float clipSign;
uniform float mirror_flag;
void applyClip(vec3 pos)
{
float funnyClip = 0;
if (mirror_flag > 0)
{
if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0)
{
discard;
}
}
}
uniform mat4 modelview_matrix;
uniform mat3 normal_matrix;
in vec3 vary_position;
void mirrorClip(vec3 pos);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
out vec4 frag_color;
@ -302,13 +292,12 @@ float getShadow(vec3 pos, vec3 norm)
void main()
{
applyClip(vary_position);
mirrorClip(vary_position);
waterClip();
// diffcol == diffuse map combined with vertex color
vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
alphaMask(diffcol.a);
// spec == specular map combined with specular color
@ -428,9 +417,6 @@ void main()
float flag = GBUFFER_FLAG_HAS_ATMOS;
if (mirror_flag > 0)
flag = 1;
frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
frag_data[2] = vec4(encode_normal(norm), env, flag);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)

View File

@ -682,6 +682,35 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
return col[1]+col[0];
}
#if defined(HERO_PROBES)
uniform vec4 clipPlane;
uniform samplerCubeArray heroProbes;
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
{
float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w;
if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8)
{
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0)
{
glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz;
}
}
}
#else
void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness)
{
}
#endif
void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)
{
@ -713,6 +742,8 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
glossenv = mix(glossenv, ssr.rgb, ssr.a);
}
#endif
tapHeroProbe(glossenv, pos, norm, glossiness);
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
@ -800,6 +831,7 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
{
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
}
if (envIntensity > 0.0)
@ -827,6 +859,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
}
#endif
tapHeroProbe(glossenv, pos, norm, glossiness);
tapHeroProbe(legacyenv, pos, norm, 1.0);
glossenv = clamp(glossenv, vec3(0), vec3(10));
}

View File

@ -60,6 +60,7 @@ uniform float ssao_irradiance_max;
#endif
// Inputs
uniform vec4 clipPlane;
uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
@ -188,7 +189,7 @@ void main()
float gloss = 1.0 - perceptualRoughness;
sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear);
adjustIrradiance(irradiance, ambocc);
vec3 diffuseColor;
@ -197,13 +198,6 @@ void main()
vec3 v = -normalize(pos.xyz);
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
#ifdef HERO_PROBES
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR))
color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor;
#endif
}
else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
@ -226,7 +220,7 @@ void main()
vec3 legacyenv = vec3(0);
sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear);
adjustIrradiance(irradiance, ambocc);
// apply lambertian IBL only (see pbrIbl)
@ -262,10 +256,6 @@ void main()
// add radiance map
applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
#ifdef HERO_PROBES
color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb;
#endif
}
color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);

View File

@ -55,9 +55,11 @@ in vec4 view;
in vec3 vary_position;
vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);
void mirrorClip(vec3 position);
void main()
{
mirrorClip(vary_position);
vec4 color;
//get detail normals

View File

@ -35,6 +35,8 @@ vec3 scaleSoftClipFragLinear(vec3 l);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
void mirrorClip(vec3 pos);
// PBR interface
vec2 BRDF(float NoV, float roughness);
@ -129,6 +131,7 @@ vec3 getPositionWithNDC(vec3 ndc);
void main()
{
mirrorClip(vary_position);
vN = vary_normal;
vT = vary_tangent;
vB = cross(vN, vT);

View File

@ -1,4 +1,4 @@
version 59
version 60
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@ -96,6 +96,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTerrainPBRDetail 1 -4
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.5
@ -126,6 +127,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTerrainPBRDetail 1 -1
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -154,6 +156,7 @@ RenderLocalLightCount 1 512
RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -184,6 +187,7 @@ RenderLocalLightCount 1 1024
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -214,6 +218,7 @@ RenderLocalLightCount 1 2048
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -243,6 +248,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -272,6 +278,7 @@ RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0

View File

@ -1,4 +1,4 @@
version 46
version 47
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@ -96,6 +96,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTerrainPBRDetail 1 -4
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.5
@ -126,6 +127,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTerrainPBRDetail 1 -1
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -154,6 +156,7 @@ RenderLocalLightCount 1 512
RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -184,6 +187,7 @@ RenderLocalLightCount 1 1024
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -214,6 +218,7 @@ RenderLocalLightCount 1 2048
RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
@ -243,6 +248,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -272,6 +278,7 @@ RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0

View File

@ -1,4 +1,4 @@
version 56
version 57
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@ -45,6 +45,7 @@ RenderObjectBump 1 1
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
@ -90,6 +91,7 @@ RenderLocalLightCount 1 8
RenderMaxPartCount 1 256
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTerrainPBRDetail 1 -4
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
@ -120,6 +122,7 @@ RenderMaxPartCount 1 2048
RenderLocalLightCount 1 256
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTerrainPBRDetail 1 -1
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -150,6 +153,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 512
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -180,6 +184,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 1024
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -210,6 +215,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 2048
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -240,6 +246,7 @@ RenderMaxPartCount 1 4096
RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
@ -269,6 +276,7 @@ RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 3
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0

View File

@ -1766,7 +1766,6 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot");
pingMainloopTimeout("Main:Snapshot");
gPipeline.mReflectionMapManager.update();
gPipeline.mHeroProbeManager.update();
LLFloaterSnapshot::update(); // take snapshots
LLFloaterSimpleSnapshot::update();
gGLActive = FALSE;

View File

@ -183,19 +183,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
glUniform4fv(specular, 1, lastSpecular.mV);
}
if (gPipeline.mHeroProbeManager.isMirrorPass())
{
glUniform1f(LLShaderMgr::MIRROR_FLAG, 1);
}
LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.currentMirrorClip()[0],
gPipeline.mHeroProbeManager.currentMirrorClip()[1],
gPipeline.mHeroProbeManager.currentMirrorClip()[2],
gPipeline.mHeroProbeManager.currentMirrorClip()[3]);
mShader->uniform4fv(LLShaderMgr::CLIP_PLANE,
1, clipPlane.mV);
LLVOAvatar* lastAvatar = nullptr;
for (LLCullResult::drawinfo_iterator i = begin; i != end; )

View File

@ -54,8 +54,6 @@
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
const S32 PBR_DETAIL_EMISSIVE = 0;
S32 LLDrawPoolTerrain::sPBRDetailMode = 0;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE;
@ -141,27 +139,29 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
tex->setBoostLevel(level);
tex->addTextureStats(stats);
LLPointer<LLFetchedGLTFMaterial>& mat = compp->mDetailMaterials[i];
llassert(mat.notNull());
if (mat->mBaseColorTexture)
LLPointer<LLFetchedGLTFMaterial>& fetched_material = compp->mDetailMaterials[i];
if (fetched_material)
{
mat->mBaseColorTexture->setBoostLevel(level);
mat->mBaseColorTexture->addTextureStats(stats);
}
if (mat->mNormalTexture)
{
mat->mNormalTexture->setBoostLevel(level);
mat->mNormalTexture->addTextureStats(stats);
}
if (mat->mMetallicRoughnessTexture)
{
mat->mMetallicRoughnessTexture->setBoostLevel(level);
mat->mMetallicRoughnessTexture->addTextureStats(stats);
}
if (mat->mEmissiveTexture)
{
mat->mEmissiveTexture->setBoostLevel(level);
mat->mEmissiveTexture->addTextureStats(stats);
if (fetched_material->mBaseColorTexture)
{
fetched_material->mBaseColorTexture->setBoostLevel(level);
fetched_material->mBaseColorTexture->addTextureStats(stats);
}
if (fetched_material->mNormalTexture)
{
fetched_material->mNormalTexture->setBoostLevel(level);
fetched_material->mNormalTexture->addTextureStats(stats);
}
if (fetched_material->mMetallicRoughnessTexture)
{
fetched_material->mMetallicRoughnessTexture->setBoostLevel(level);
fetched_material->mMetallicRoughnessTexture->addTextureStats(stats);
}
if (fetched_material->mEmissiveTexture)
{
fetched_material->mEmissiveTexture->setBoostLevel(level);
fetched_material->mEmissiveTexture->addTextureStats(stats);
}
}
}
}
@ -254,7 +254,7 @@ void LLDrawPoolTerrain::drawLoop()
void LLDrawPoolTerrain::renderFullShader()
{
const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE);
const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false);
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
@ -388,15 +388,26 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
LLPointer<LLFetchedGLTFMaterial> (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
LLPointer<LLFetchedGLTFMaterial> (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT;
#ifdef SHOW_ASSERT
constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
llassert(shader_material_count == terrain_material_count);
#endif
if (local_materials)
{
// Override region terrain with the global local override terrain
materials = &gLocalTerrainMaterials.mDetailMaterials;
fetched_materials = &gLocalTerrainMaterials.mDetailMaterials;
}
const LLGLTFMaterial* materials[terrain_material_count];
for (U32 i = 0; i < terrain_material_count; ++i)
{
materials[i] = (*fetched_materials)[i].get();
if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; }
}
constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
S32 detail_basecolor[terrain_material_count];
S32 detail_normal[terrain_material_count];
S32 detail_metalrough[terrain_material_count];
@ -404,12 +415,19 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
for (U32 i = 0; i < terrain_material_count; ++i)
{
const LLFetchedGLTFMaterial* material = (*materials)[i].get();
LLViewerTexture* detail_basecolor_texturep = nullptr;
LLViewerTexture* detail_normal_texturep = nullptr;
LLViewerTexture* detail_metalrough_texturep = nullptr;
LLViewerTexture* detail_emissive_texturep = nullptr;
LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture;
LLViewerTexture *detail_normal_texturep = material->mNormalTexture;
LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture;
LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture;
const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
if (fetched_material)
{
detail_basecolor_texturep = fetched_material->mBaseColorTexture;
detail_normal_texturep = fetched_material->mNormalTexture;
detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture;
detail_emissive_texturep = fetched_material->mEmissiveTexture;
}
detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
if (detail_basecolor_texturep)
@ -423,31 +441,37 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_basecolor[i])->activate();
detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
if (detail_normal_texturep)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
{
gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
if (detail_normal_texturep)
{
gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
}
else
{
gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
}
gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_normal[i])->activate();
}
else
{
gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
}
gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_normal[i])->activate();
detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
if (detail_metalrough_texturep)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
if (detail_metalrough_texturep)
{
gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
}
else
{
gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
}
gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_metalrough[i])->activate();
}
else
{
gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
}
gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_metalrough[i])->activate();
if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
if (detail_emissive_texturep)
@ -503,7 +527,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
F32 minimum_alphas[terrain_material_count];
for (U32 i = 0; i < terrain_material_count; ++i)
{
const LLFetchedGLTFMaterial* material = (*materials)[i].get();
const LLGLTFMaterial* material = materials[i];
base_color_factors[i] = material->mBaseColor;
metallic_factors[i] = material->mMetallicFactor;
@ -523,9 +547,12 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
minimum_alphas[i] = min_alpha;
}
shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors);
shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
}
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors);
}
@ -545,9 +572,15 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
for (U32 i = 0; i < terrain_material_count; ++i)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
}
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
}
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
}
@ -556,15 +589,21 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
gGL.getTexUnit(detail_basecolor[i])->disable();
gGL.getTexUnit(detail_basecolor[i])->activate();
gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_normal[i])->disable();
gGL.getTexUnit(detail_normal[i])->activate();
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
{
gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_normal[i])->disable();
gGL.getTexUnit(detail_normal[i])->activate();
}
gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_metalrough[i])->disable();
gGL.getTexUnit(detail_metalrough[i])->activate();
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_metalrough[i])->disable();
gGL.getTexUnit(detail_metalrough[i])->activate();
}
if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_emissive[i])->disable();

View File

@ -1810,8 +1810,6 @@ void LLEnvironment::update(const LLViewerCamera * cam)
updateSettingsUniforms();
// *TODO: potential optimization - this block may only need to be
// executed some of the time. For example for water shaders only.
{
LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
end_shaders = LLViewerShaderMgr::instance()->endShaders();
@ -1822,6 +1820,10 @@ void LLEnvironment::update(const LLViewerCamera * cam)
|| shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
{
shaders_iter->mUniformsDirty = TRUE;
if (shaders_iter->mRiggedVariant)
{
shaders_iter->mRiggedVariant->mUniformsDirty = TRUE;
}
}
}
}

View File

@ -128,7 +128,6 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor);
shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0);
F32 normal_packed[8];
mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed);

View File

@ -1627,6 +1627,11 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
mAskedTextureHeights = false;
mConfirmedTextureHeights = false;
if (!mRegionChangedSlot.connected())
{
mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this));
}
refresh();
return LLPanelRegionInfo::postBuild();
@ -1635,8 +1640,7 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
// virtual
void LLPanelRegionTerrainInfo::refresh()
{
// For simplicity, require restart
static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled");
static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
LLTextBox* texture_text = getChild<LLTextBox>("detail_texture_text");
if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); }
@ -1698,6 +1702,27 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType()
}
}
void LLPanelRegionTerrainInfo::onRegionChanged()
{
LLViewerRegion *region = gAgent.getRegion();
if (!region) { return; }
if (region->simulatorFeaturesReceived())
{
onSimulatorFeaturesReceived(region->getRegionID(), region);
}
else
{
// See "RenderTerrainPBREnabled" in LLViewerRegion::setSimulatorFeatures
region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived,this,_1, _2));
}
}
void LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp)
{
refresh();
}
// virtual
bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
{
@ -1754,6 +1779,9 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
LL_DEBUGS() << "no region set" << LL_ENDL;
getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
}
// Update visibility of terrain swatches, etc
refresh();
getChildView("download_raw_btn")->setEnabled(owner_or_god);
getChildView("upload_raw_btn")->setEnabled(owner_or_god);

View File

@ -274,6 +274,8 @@ public:
BOOL postBuild() override;
void onRegionChanged();
void onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp);
bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator
void setEnvControls(bool available); // Whether environment settings are available for this region
@ -301,6 +303,7 @@ protected:
private:
bool mConfirmedTextureHeights;
bool mAskedTextureHeights;
boost::signals2::connection mRegionChangedSlot;
};
/////////////////////////////////////////////////////////////////////////////

View File

@ -543,7 +543,6 @@ void LLGLTFPreviewTexture::postRender(BOOL success)
LLViewerDynamicTexture::postRender(success);
}
// static
LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetchedGLTFMaterial> &material)
{
if (!material)
@ -551,6 +550,13 @@ LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetc
return nullptr;
}
static LLCachedControl<bool> sUIPreviewMaterial(gSavedSettings, "UIPreviewMaterial", false);
if (!sUIPreviewMaterial)
{
fetch_texture_for_ui(material->mBaseColorTexture, material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
return material->mBaseColorTexture;
}
if (!is_material_loaded_enough_for_ui(*material))
{
return nullptr;

View File

@ -114,7 +114,7 @@ void LLHeroProbeManager::update()
for (auto vo : mHeroVOList)
{
if (vo)
if (vo && !vo->isDead())
{
if (vo->mDrawable.notNull())
{
@ -127,61 +127,39 @@ void LLHeroProbeManager::update()
else
{
// Valid drawables only please. Unregister this one.
unregisterHeroDrawable(vo);
unregisterViewerObject(vo);
}
}
else
{
unregisterHeroDrawable(vo);
unregisterViewerObject(vo);
}
}
if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull())
if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull())
{
U8 mode = mNearestHero->mirrorFace();
mode = llmin(mNearestHero->mDrawable->getNumFaces() - 1, mode);
mCurrentFace = mNearestHero->mDrawable->getFace(mode);
LLVector3 hero_pos = mCurrentFace->getPositionAgent();
// Calculate the average normal.
LLVector4a *posp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mPositions;
U16 *indp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mIndices;
// get first three vertices (first triangle)
LLVector4a v0 = posp[indp[0]];
LLVector4a v1 = posp[indp[1]];
LLVector4a v2 = posp[indp[2]];
v1.sub(v0);
v2.sub(v0);
LLVector3 face_normal = LLVector3(v1[0], v1[1], v1[2]) % LLVector3(v2[0], v2[1], v2[2]);
LLVector3 hero_pos = mNearestHero->getPositionAgent();
LLVector3 face_normal = LLVector3(0, 0, 1);
face_normal *= mNearestHero->mDrawable->getXform()->getWorldRotation();
face_normal.normalize();
face_normal *= mCurrentFace->getXform()->getWorldRotation();
LLVector3 offset = camera_pos - hero_pos;
LLVector3 project = face_normal * (offset * face_normal);
LLVector3 reject = offset - project;
LLVector3 point = (reject - project) + hero_pos;
glh::matrix4f mat = copy_matrix(gGLModelView);
glh::vec4f tc(face_normal.mV);
mat.mult_matrix_vec(tc);
LLVector3 mirror_normal;
mirror_normal.set(tc.v);
LLVector3 hero_pos_render;
tc = glh::vec4f(hero_pos.mV);
mat.mult_matrix_vec(tc);
hero_pos_render.set(tc.v);
mCurrentClipPlane.setVec(hero_pos_render, mirror_normal);
mCurrentClipPlane.setVec(hero_pos, face_normal);
mMirrorPosition = hero_pos;
mMirrorNormal = face_normal;
probe_pos.load3(point.mV);
}
else
{
mNearestHero = nullptr;
}
mHeroProbeStrength = 1;
}
@ -227,7 +205,7 @@ void LLHeroProbeManager::update()
void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip)
{
// hacky hot-swap of camera specific render targets
gPipeline.mRT = &gPipeline.mAuxillaryRT;
gPipeline.mRT = &gPipeline.mHeroProbeRT;
probe->update(mRenderTarget.getWidth(), face, true, near_clip);
@ -262,13 +240,13 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n
static LLStaticHashedString znear("znear");
static LLStaticHashedString zfar("zfar");
LLRenderTarget *screen_rt = &gPipeline.mAuxillaryRT.screen;
LLRenderTarget *depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen;
LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.deferredScreen;
// perform a gaussian blur on the super sampled render before downsampling
{
gGaussianProgram.bind();
gGaussianProgram.uniform1f(resScale, 1.f / mProbeResolution);
gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
// horizontal
@ -286,9 +264,9 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
screen_rt->flush();
gGaussianProgram.unbind();
}
S32 mips = log2((F32)mProbeResolution) + 0.5f;
gReflectionMipProgram.bind();
@ -348,14 +326,14 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n
{
//generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map)
gRadianceGenProgram.bind();
gHeroRadianceGenProgram.bind();
mVertexBuffer->setBuffer();
S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
S32 channel = gHeroRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
mTexture->bind(channel);
gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength);
gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength);
U32 res = mMipChain[0].getWidth();
@ -367,10 +345,10 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n
static LLStaticHashedString sWidth("u_width");
static LLStaticHashedString sStrength("probe_strength");
gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
gRadianceGenProgram.uniform1f(sMipLevel, i);
gRadianceGenProgram.uniform1i(sWidth, mProbeResolution);
gRadianceGenProgram.uniform1f(sStrength, 1);
gHeroRadianceGenProgram.uniform1f(sRoughness, (F32) i / (F32) (mMipChain.size() - 1));
gHeroRadianceGenProgram.uniform1f(sMipLevel, i);
gHeroRadianceGenProgram.uniform1i(sWidth, mProbeResolution);
gHeroRadianceGenProgram.uniform1f(sStrength, 1);
for (int cf = 0; cf < 6; ++cf)
{ // for each cube face
@ -393,7 +371,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n
}
}
gRadianceGenProgram.unbind();
gHeroRadianceGenProgram.unbind();
}
mMipChain[0].flush();
@ -561,24 +539,21 @@ void LLHeroProbeManager::doOcclusion()
}
}
void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep)
void LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep)
{
llassert(drawablep != nullptr);
if (mHeroVOList.find(drawablep) == mHeroVOList.end())
{
// Probe isn't in our list for consideration. Add it.
mHeroVOList.insert(drawablep);
LL_INFOS() << "Mirror drawable registered." << LL_ENDL;
}
}
void LLHeroProbeManager::unregisterHeroDrawable(LLVOVolume* drawablep)
void LLHeroProbeManager::unregisterViewerObject(LLVOVolume* drawablep)
{
if (mHeroVOList.find(drawablep) != mHeroVOList.end())
{
mHeroVOList.erase(drawablep);
}
}
bool LLHeroProbeManager::isViableMirror(LLFace* face) const
{
return face == mCurrentFace;
}

View File

@ -68,14 +68,13 @@ public:
// perform occlusion culling on all active reflection probes
void doOcclusion();
void registerHeroDrawable(LLVOVolume* drawablep);
void unregisterHeroDrawable(LLVOVolume* drawablep);
bool isViableMirror(LLFace* face) const;
void registerViewerObject(LLVOVolume *drawablep);
void unregisterViewerObject(LLVOVolume* drawablep);
bool isMirrorPass() const { return mRenderingMirror; }
LLPlane currentMirrorClip() const { return mCurrentClipPlane; }
LLVector3 mMirrorPosition;
LLVector3 mMirrorNormal;
private:
friend class LLPipeline;
@ -102,6 +101,7 @@ private:
LLPlane mCurrentClipPlane;
// update the specified face of the specified probe
void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip);
@ -135,8 +135,7 @@ private:
bool mRenderingMirror = false;
std::set<LLVOVolume*> mHeroVOList;
LLVOVolume* mNearestHero;
LLFace* mCurrentFace;
std::set<LLPointer<LLVOVolume>> mHeroVOList;
LLPointer<LLVOVolume> mNearestHero;
};

View File

@ -114,11 +114,6 @@ BOOL LLPanelVolume::postBuild()
getChild<LLUICtrl>("FlexForceZ")->setValidateBeforeCommit(precommitValidate);
}
// Mirror Parameters
{
childSetCommitCallback("Mirror Checkbox Ctrl", onCommitIsMirror, this);
}
// LIGHT Parameters
{
childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this);
@ -155,7 +150,7 @@ BOOL LLPanelVolume::postBuild()
// REFLECTION PROBE Parameters
{
childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
childSetCommitCallback("Probe Update Type", onCommitProbe, this);
childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
@ -313,10 +308,6 @@ void LLPanelVolume::getState( )
getChildView("select_single")->setVisible(true);
getChildView("select_single")->setEnabled(true);
}
BOOL is_mirror = volobjp && volobjp->isMirror();
getChild<LLUICtrl>("Mirror Checkbox Ctrl")->setValue(is_mirror);
getChildView("Mirror Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp);
// Light properties
BOOL is_light = volobjp && volobjp->getIsLight();
@ -405,17 +396,25 @@ void LLPanelVolume::getState( )
bool probe_enabled = is_probe && editable && single_volume;
bool mirrors_enabled = LLPipeline::RenderMirrors;
getChildView("Probe Update Type")->setVisible(mirrors_enabled);
getChildView("Probe Update Label")->setVisible(mirrors_enabled);
getChildView("Probe Dynamic")->setVisible(!mirrors_enabled);
getChildView("Probe Dynamic")->setEnabled(probe_enabled);
getChildView("Probe Update Type")->setEnabled(probe_enabled);
getChildView("Probe Volume Type")->setEnabled(probe_enabled);
getChildView("Probe Ambiance")->setEnabled(probe_enabled);
getChildView("Probe Near Clip")->setEnabled(probe_enabled);
getChildView("Probe Update Label")->setEnabled(probe_enabled);
if (!probe_enabled)
{
getChild<LLComboBox>("Probe Volume Type", true)->clear();
getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
getChild<LLComboBox>("Probe Update Type", true)->clear();
}
else
{
@ -429,10 +428,28 @@ void LLPanelVolume::getState( )
volume_type = "Sphere";
}
std::string update_type;
if (volobjp->getReflectionProbeIsDynamic())
{
update_type = "Dynamic";
}
else if (volobjp->getReflectionProbeIsMirror())
{
update_type = "Mirror";
}
else
{
update_type = "Static";
}
getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror");
getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror");
getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
getChild<LLComboBox>("Probe Update Type", true)->setValue(update_type);
}
// Animated Mesh
@ -723,7 +740,7 @@ void LLPanelVolume::clearCtrls()
getChildView("Reflection Probe")->setEnabled(false);;
getChildView("Probe Volume Type")->setEnabled(false);
getChildView("Probe Dynamic")->setEnabled(false);
getChildView("Probe Update Type")->setEnabled(false);
getChildView("Probe Ambiance")->setEnabled(false);
getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
@ -773,20 +790,6 @@ void LLPanelVolume::sendIsLight()
LL_INFOS() << "update light sent" << LL_ENDL;
}
void LLPanelVolume::sendIsMirror()
{
LLViewerObject* objectp = mObject;
if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
{
return;
}
LLVOVolume *volobjp = (LLVOVolume *)objectp;
BOOL value = getChild<LLUICtrl>("Mirror Checkbox Ctrl")->getValue();
volobjp->setIsMirror(value);
LL_INFOS() << "update mirror sent" << LL_ENDL;
}
void notify_cant_select_reflection_probe()
{
if (!gSavedSettings.getBOOL("SelectReflectionProbes"))
@ -1482,7 +1485,14 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
std::string update_type = self->getChild<LLUICtrl>("Probe Update Type")->getValue().asString();
volobjp->setReflectionProbeIsDynamic(update_type == "Dynamic");
volobjp->setReflectionProbeIsMirror(update_type == "Mirror");
self->getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror");
self->getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror");
std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
@ -1529,12 +1539,6 @@ void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
self->sendIsLight();
}
void LLPanelVolume::onCommitIsMirror( LLUICtrl* ctrl, void* userdata )
{
LLPanelVolume* self = (LLPanelVolume*) userdata;
self->sendIsMirror();
}
// static
void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp)
{

View File

@ -57,8 +57,7 @@ public:
void refresh();
void sendIsLight();
void sendIsMirror();
// when an object is becoming a refleciton probe, present a dialog asking for confirmation
// otherwise, send the reflection probe update immediately
void sendIsReflectionProbe();
@ -72,7 +71,6 @@ public:
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
static void onCommitIsMirror( LLUICtrl* ctrl, void* userdata);
static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata);
static void onCommitProbe(LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);

View File

@ -718,11 +718,11 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
// TODO -- make these getters return vec3s
LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV);
LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV);
LLVector3 sun_light_color = LLVector3(psky->getSunlightColor().mV);
LLVector3 moon_light_color = LLVector3(psky->getMoonlightColor().mV);
shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color);
shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moon_light_color);
shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV));
@ -765,9 +765,9 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale);
LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale;
LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale;
LLColor3 sun_diffuse = getSunDiffuse() * auto_adjust_sun_color_scale;
sun_light_color = sun_light_color * auto_adjust_sun_color_scale;
shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_diffuse.mV);
shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color.mV);
shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV);
shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV);
@ -1009,6 +1009,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
glh::matrix4f mat(modelView);
glh::matrix4f invtrans = mat.inverse().transpose();
invtrans.m[3] = invtrans.m[7] = invtrans.m[11] = 0.f;
glh::vec3f enorm;
glh::vec3f ep;
invtrans.mult_matrix_vec(norm, enorm);
@ -1017,12 +1018,29 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
norm = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
p = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
invtrans.mult_matrix_vec(norm, enorm);
enorm.normalize();
mat.mult_matrix_vec(p, ep);
LLVector4 mirrorPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
LLDrawPoolAlpha::sWaterPlane = waterPlane;
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
shader->uniform4fv(LLShaderMgr::CLIP_PLANE, mirrorPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
if (gPipeline.mHeroProbeManager.isMirrorPass())
{
shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 1);
}
else
{
shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0);
}
F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);

View File

@ -744,6 +744,10 @@ void LLFloaterTexturePicker::draw()
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
}
}
if (mGLTFPreview)
{
mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
}
}
else
{
@ -800,7 +804,7 @@ void LLFloaterTexturePicker::draw()
// If the floater is focused, don't apply its alpha to the texture (STORM-677).
const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
LLViewerTexture* preview = nullptr;
LLViewerTexture* preview;
if (mGLTFMaterial)
{
preview = mGLTFPreview.get();
@ -808,15 +812,11 @@ void LLFloaterTexturePicker::draw()
else
{
preview = mTexturep.get();
if (mTexturep)
{
// Pump the priority
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
}
}
if( preview )
{
preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
if( preview->getComponents() == 4 )
{
gl_rect_2d_checkerboard( interior, alpha );
@ -2407,6 +2407,10 @@ void LLTextureCtrl::draw()
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
}
}
if (mGLTFPreview)
{
mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
}
preview = mGLTFPreview;
}
@ -2447,10 +2451,7 @@ void LLTextureCtrl::draw()
}
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha);
if (mTexturep)
{
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
}
preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
// <FS:Ansariel> Mask texture if desired
if (mIsMasked)
{

View File

@ -772,6 +772,12 @@ BOOL LLViewerCamera::cameraUnderWater() const
{
LLViewerRegion* regionp = LLWorld::instance().getRegionFromPosAgent(getOrigin());
if (gPipeline.mHeroProbeManager.isMirrorPass())
{
// TODO: figure out how to handle this case
return FALSE;
}
if (!regionp)
{
regionp = gAgent.getRegion();

View File

@ -772,6 +772,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!gDisconnected)
{
// Render mirrors and associated hero probes before we render the rest of the scene.
// This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it.
if (gPipeline.RenderMirrors && !gSnapshot)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes");
gPipeline.mHeroProbeManager.update();
}
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1");
LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
@ -812,7 +820,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
gPipeline.updateGL();
stop_glerror();
LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");

View File

@ -12296,10 +12296,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
if (gSavedSettings.get<bool>("RenderTerrainPBREnabled"))
{
view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
}
view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
//[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ]
view_listener_t::addMenu(new FSAdvancedToggleDoubleClickAction, "Advanced.SetDoubleClickAction");
view_listener_t::addMenu(new FSAdvancedCheckEnabledDoubleClickAction, "Advanced.CheckEnabledDoubleClickAction");

View File

@ -332,9 +332,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mLastUpdateCached(FALSE),
mCachedMuteListUpdateTime(0),
mCachedOwnerInMuteList(false),
mRiggedAttachedWarned(false),
mIsMirror(false),
mMirrorFace(3)
mRiggedAttachedWarned(false)
{
if (!is_global)
{
@ -1203,39 +1201,6 @@ U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector
return parent_id;
}
void detectMirror(const std::string &str, bool &mirror, U8 &mode)
{
std::stringstream ss(str);
std::string word;
while (ss >> word)
{
if (word == "IsMirror")
{
mirror = true;
}
if (mirror)
{
bool num = false;
std::string::const_iterator it = word.begin();
while (it != word.end())
{
num = std::isdigit(*it);
++it;
if (!num)
break;
}
if (num)
{
mode = atoi(word.c_str());
}
}
}
}
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
@ -1614,8 +1579,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
std::string temp_string;
mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
detectMirror(temp_string, mIsMirror, mMirrorFace);
LLColor4U coloru;
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
@ -2009,8 +1972,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
std::string temp_string;
dp->unpackString(temp_string, "Text");
detectMirror(temp_string, mIsMirror, mMirrorFace);
LLColor4U coloru;
dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
coloru.mV[3] = 255 - coloru.mV[3];
@ -6514,11 +6475,6 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
{
new_block = new LLReflectionProbeParams();
break;
}
case LLNetworkData::PARAMS_MIRROR:
{
new_block = new LLMirrorParams();
break;
}
default:
{

View File

@ -260,8 +260,6 @@ public:
virtual BOOL isRiggedMesh() const { return FALSE; }
virtual BOOL hasLightTexture() const { return FALSE; }
virtual BOOL isReflectionProbe() const { return FALSE; }
virtual BOOL isMirror() const { return FALSE; }
virtual U8 mirrorFace() const { return 0; }
// This method returns true if the object is over land owned by
// the agent, one of its groups, or it encroaches and
@ -900,9 +898,6 @@ protected:
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
bool mIsMirror;
U8 mMirrorFace;
// If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap"
bool mShouldShrinkWrap = false;

View File

@ -1695,8 +1695,8 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
static bool pbr_terrain_enabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
@ -2011,8 +2011,8 @@ void LLViewerRegion::forceUpdate()
{
constexpr F32 max_update_time = 0.f;
static bool pbr_terrain_enabled = gSavedSettings.get<BOOL>("RenderTerrainPBREnabled");
static LLCachedControl<BOOL> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
@ -2602,7 +2602,47 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
mSimulatorFeatures = sim_features;
setSimulatorFeaturesReceived(true);
// if region has MaxTextureResolution, set max_texture_dimension settings, otherwise use default
if (mSimulatorFeatures.has("MaxTextureResolution"))
{
S32 max_texture_resolution = mSimulatorFeatures["MaxTextureResolution"].asInteger();
gSavedSettings.setS32("max_texture_dimension_X", max_texture_resolution);
gSavedSettings.setS32("max_texture_dimension_Y", max_texture_resolution);
}
else
{
gSavedSettings.setS32("max_texture_dimension_X", 1024);
gSavedSettings.setS32("max_texture_dimension_Y", 1024);
}
bool mirrors_enabled = false;
if (mSimulatorFeatures.has("MirrorsEnabled"))
{
mirrors_enabled = mSimulatorFeatures["MirrorsEnabled"].asBoolean();
}
gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled);
if (mSimulatorFeatures.has("PBRTerrainEnabled"))
{
bool enabled = mSimulatorFeatures["PBRTerrainEnabled"];
gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled);
}
else
{
gSavedSettings.setBOOL("RenderTerrainPBREnabled", false);
}
if (mSimulatorFeatures.has("PBRMaterialSwatchEnabled"))
{
bool enabled = mSimulatorFeatures["PBRMaterialSwatchEnabled"];
gSavedSettings.setBOOL("UIPreviewMaterial", enabled);
}
else
{
gSavedSettings.setBOOL("UIPreviewMaterial", false);
}
// <FS:CR> Opensim god names
#ifdef OPENSIM

View File

@ -84,7 +84,8 @@ LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gReflectionMipProgram;
LLGLSLShader gGaussianProgram;
LLGLSLShader gRadianceGenProgram;
LLGLSLShader gRadianceGenProgram;
LLGLSLShader gHeroRadianceGenProgram;
LLGLSLShader gIrradianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureCompareProgram;
@ -105,7 +106,6 @@ LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gSkinnedObjectPreviewProgram;
LLGLSLShader gPhysicsPreviewProgram;
LLGLSLShader gObjectFullbrightAlphaMaskProgram;
LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
LLGLSLShader gObjectBumpProgram;
LLGLSLShader gSkinnedObjectBumpProgram;
LLGLSLShader gObjectAlphaMaskNoColorProgram;
@ -231,7 +231,7 @@ LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
LLGLSLShader gDeferredPBRTerrainProgram;
//helper for making a rigged variant of a given shader
bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
{
riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
riggedShader.mFeatures = shader.mFeatures;
@ -246,58 +246,40 @@ bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
return riggedShader.createShader(NULL, NULL);
}
#ifdef SHOW_ASSERT
// return true if there are no redundant shaders in the given vector
// also checks for redundant variants
static bool no_redundant_shaders(const std::vector<LLGLSLShader*>& shaders)
{
std::set<std::string> names;
for (LLGLSLShader* shader : shaders)
{
if (names.find(shader->mName) != names.end())
{
LL_WARNS("Shader") << "Redundant shader: " << shader->mName << LL_ENDL;
return false;
}
names.insert(shader->mName);
if (shader->mRiggedVariant)
{
if (names.find(shader->mRiggedVariant->mName) != names.end())
{
LL_WARNS("Shader") << "Redundant shader: " << shader->mRiggedVariant->mName << LL_ENDL;
return false;
}
names.insert(shader->mRiggedVariant->mName);
}
}
return true;
}
#endif
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()
@ -306,6 +288,58 @@ LLViewerShaderMgr::~LLViewerShaderMgr()
mShaderList.clear();
}
void LLViewerShaderMgr::finalizeShaderList()
{
//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(&gObjectFullbrightAlphaMaskProgram);
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(&gDeferredAlphaImpostorProgram);
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(&gDeferredEmissiveProgram);
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(&gDeferredPostGammaCorrectProgram); // for gamma
mShaderList.push_back(&gNoPostGammaCorrectProgram);
mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
mShaderList.push_back(&gDeferredDiffuseProgram);
mShaderList.push_back(&gDeferredBumpProgram);
mShaderList.push_back(&gDeferredPBROpaqueProgram);
mShaderList.push_back(&gDeferredAvatarProgram);
mShaderList.push_back(&gDeferredTerrainProgram);
mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram);
mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram);
mShaderList.push_back(&gDeferredTreeProgram);
// make sure there are no redundancies
llassert(no_redundant_shaders(mShaderList));
}
// static
LLViewerShaderMgr * LLViewerShaderMgr::instance()
{
@ -358,6 +392,10 @@ void LLViewerShaderMgr::setShaders()
return;
}
mShaderList.clear();
LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors;
if (!gGLManager.mHasRequirements)
{
// Viewer will show 'hardware requirements' warning later
@ -539,6 +577,8 @@ void LLViewerShaderMgr::setShaders()
}
gPipeline.createGLBuffers();
finalizeShaderList();
reentrance = false;
}
@ -644,6 +684,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor");
attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor);
S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail");
detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX);
attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail);
}
@ -682,6 +723,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
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/globalF.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/pbrterrainUtilF.glsl", 1) );
@ -1086,9 +1128,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
if (success)
{
mShaderList.push_back(&gDeferredMaterialProgram[i]);
bool has_skin = i & 0x10;
gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
if (!has_skin)
{
mShaderList.push_back(&gDeferredMaterialProgram[i]);
gDeferredMaterialProgram[i].mName = llformat("Material Shader %d", i);
}
else
{
gDeferredMaterialProgram[i].mName = llformat("Skinned Material Shader %d", i);
}
U32 alpha_mode = i & 0x3;
@ -1125,7 +1175,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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;
@ -1827,11 +1877,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
if (LLPipeline::RenderMirrors)
{
gDeferredSoftenProgram.addPermutation("HERO_PROBES", "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);
@ -2859,8 +2904,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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];
gRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "32");
success = gRadianceGenProgram.createShader(NULL, NULL);
}
if (success && gGLManager.mHasCubeMapArray)
{
gHeroRadianceGenProgram.mName = "Hero Radiance Gen Shader";
gHeroRadianceGenProgram.mShaderFiles.clear();
gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
gHeroRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
gHeroRadianceGenProgram.addPermutation("HERO_PROBES", "1");
gHeroRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "4");
success = gHeroRadianceGenProgram.createShader(NULL, NULL);
}
if (success && gGLManager.mHasCubeMapArray)
{

View File

@ -41,6 +41,10 @@ public:
LLViewerShaderMgr();
/* virtual */ ~LLViewerShaderMgr();
// Add shaders to mShaderList for later uniform propagation
// Will assert on redundant shader entries in debug builds
void finalizeShaderList();
// singleton pattern implementation
static LLViewerShaderMgr * instance();
static void releaseInstance();
@ -153,6 +157,7 @@ extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gReflectionMipProgram;
extern LLGLSLShader gGaussianProgram;
extern LLGLSLShader gRadianceGenProgram;
extern LLGLSLShader gHeroRadianceGenProgram;
extern LLGLSLShader gIrradianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
@ -179,7 +184,6 @@ extern LLGLSLShader gOneTextureFilterProgram;
//object shaders
extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gPhysicsPreviewProgram;
extern LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
extern LLGLSLShader gObjectBumpProgram;
extern LLGLSLShader gSkinnedObjectBumpProgram;
extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
@ -285,15 +289,19 @@ extern LLGLSLShader gDeferredPBROpaqueProgram;
extern LLGLSLShader gDeferredPBRAlphaProgram;
extern LLGLSLShader gHUDPBRAlphaProgram;
// Encodes detail level for dropping textures, in accordance with the GLTF spec
// Encodes detail level for dropping textures, in accordance with the GLTF spec where possible
// 0 is highest detail, -1 drops emissive, etc
// Dropping metallic roughness is off-spec - Reserve for potato machines as needed
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
enum TerrainPBRDetail : S32
{
TERRAIN_PBR_DETAIL_MAX = 0,
TERRAIN_PBR_DETAIL_EMISSIVE = 0,
TERRAIN_PBR_DETAIL_OCCLUSION = -1,
TERRAIN_PBR_DETAIL_MIN = -1,
TERRAIN_PBR_DETAIL_MAX = 0,
TERRAIN_PBR_DETAIL_EMISSIVE = 0,
TERRAIN_PBR_DETAIL_OCCLUSION = -1,
TERRAIN_PBR_DETAIL_NORMAL = -2,
TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS = -3,
TERRAIN_PBR_DETAIL_BASE_COLOR = -4,
TERRAIN_PBR_DETAIL_MIN = -4,
};
extern LLGLSLShader gDeferredPBRTerrainProgram;
#endif

View File

@ -75,12 +75,12 @@ LLTerrainMaterials::~LLTerrainMaterials()
BOOL LLTerrainMaterials::generateMaterials()
{
if (texturesReady(TRUE))
if (texturesReady(true, true))
{
return TRUE;
}
if (materialsReady(TRUE))
if (materialsReady(true, true))
{
return TRUE;
}
@ -123,42 +123,82 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType()
{
LL_PROFILE_ZONE_SCOPED;
const BOOL use_textures = texturesReady() || !materialsReady();
const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false);
return use_textures ? Type::TEXTURE : Type::PBR;
}
BOOL LLTerrainMaterials::texturesReady(BOOL boost)
bool LLTerrainMaterials::texturesReady(bool boost, bool strict)
{
BOOL ready = TRUE;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!textureReady(mDetailTextures[i], boost))
{
ready = FALSE;
}
}
return ready;
}
bool ready[ASSET_COUNT];
// *NOTE: Calls to textureReady may boost textures. Do not early-return.
for (S32 i = 0; i < ASSET_COUNT; i++)
{
ready[i] = textureReady(mDetailTextures[i], boost);
}
BOOL LLTerrainMaterials::materialsReady(BOOL boost)
{
BOOL ready = TRUE;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
bool one_ready = false;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
const bool current_ready = ready[i];
one_ready = one_ready || current_ready;
if (!current_ready && strict)
{
ready = FALSE;
return false;
}
}
return ready;
return one_ready;
}
bool LLTerrainMaterials::materialsReady(bool boost, bool strict)
{
bool ready[ASSET_COUNT];
// *NOTE: Calls to materialReady may boost materials/textures. Do not early-return.
for (S32 i = 0; i < ASSET_COUNT; i++)
{
ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict);
}
#if 1
static LLCachedControl<bool> sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false);
static LLCachedControl<bool> sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false);
if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce)
{
bool defined = true;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
if (!mDetailMaterials[i])
{
defined = false;
break;
}
}
if (defined)
{
return true;
}
}
#endif
bool one_ready = false;
for (S32 i = 0; i < ASSET_COUNT; i++)
{
const bool current_ready = ready[i];
one_ready = one_ready || current_ready;
if (!current_ready && strict)
{
return false;
}
}
return one_ready;
}
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
// static
BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost)
{
llassert(tex.notNull());
llassert(tex);
if (!tex) { return false; }
if (tex->getDiscardLevel() < 0)
{
@ -167,7 +207,7 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->addTextureStats(BASE_SIZE*BASE_SIZE);
}
return FALSE;
return false;
}
if ((tex->getDiscardLevel() != 0 &&
(tex->getWidth() < BASE_SIZE ||
@ -188,23 +228,23 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setMinDiscardLevel(ddiscard);
tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
}
return FALSE;
return false;
}
if (tex->getComponents() == 0)
{
return FALSE;
return false;
}
return TRUE;
return true;
}
// Boost the loading priority of every known texture in the material
// Return true when ready to use (i.e. material and all textures within are sufficiently loaded)
// Return true when ready to use
// static
BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
bool LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial> &mat, bool &textures_set, bool boost, bool strict)
{
if (!mat || !mat->isLoaded())
{
return FALSE;
return false;
}
// Material is loaded, but textures may not be
@ -213,33 +253,39 @@ BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bo
// *NOTE: These can sometimes be set to to nullptr due to
// updateTEMaterialTextures. For the sake of robustness, we emulate
// that fetching behavior by setting textures of null IDs to nullptr.
mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
textures_set = true;
mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
textures_set = true;
return FALSE;
return false;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost))
// *NOTE: Calls to textureReady may boost textures. Do not early-return.
bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] =
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost);
ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] =
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost);
ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] =
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() ||
textureReady(mat->mMetallicRoughnessTexture, boost);
ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] =
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost);
if (strict)
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost))
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost))
{
return FALSE;
}
if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost))
{
return FALSE;
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
{
if (!ready[i])
{
return false;
}
}
}
return TRUE;
return true;
}
@ -409,16 +455,13 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
S32 st_data_size[ASSET_COUNT]; // for debugging
const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
// *TODO: Remove this as it is reduandant computation (first and foremost
// because getMaterialType() does something similar, but also... shouldn't
// the textures/materials already be loaded by now?)
if (use_textures)
{
if (!texturesReady()) { return FALSE; }
if (!texturesReady(true, true)) { return FALSE; }
}
else
{
if (!materialsReady()) { return FALSE; }
if (!materialsReady(true, true)) { return FALSE; }
}
for (S32 i = 0; i < ASSET_COUNT; i++)

View File

@ -61,12 +61,16 @@ public:
LLUUID getDetailAssetID(S32 asset);
virtual void setDetailAssetID(S32 asset, const LLUUID& id);
Type getMaterialType();
BOOL texturesReady(BOOL boost = FALSE);
BOOL materialsReady(BOOL boost = FALSE);
bool texturesReady(bool boost, bool strict);
// strict = true -> all materials must be sufficiently loaded
// strict = false -> at least one material must be loaded
bool materialsReady(bool boost, bool strict);
protected:
static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost);
// strict = true -> all materials must be sufficiently loaded
// strict = false -> at least one material must be loaded
static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict);
LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
bool mMaterialTexturesSet[ASSET_COUNT];
@ -116,8 +120,8 @@ public:
BOOL getParamsReady() const { return mParamsReady; }
protected:
static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost = false);
static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost = false);
BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;

View File

@ -267,9 +267,6 @@ LLVOVolume::~LLVOVolume()
mTextureAnimp = NULL;
delete mVolumeImpl;
mVolumeImpl = NULL;
if (mIsMirror)
gPipeline.mHeroProbeManager.unregisterHeroDrawable(this);
gMeshRepo.unregisterMesh(this);
@ -1154,11 +1151,6 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
updateReflectionProbePtr();
}
if (isMirror())
{
gPipeline.mHeroProbeManager.registerHeroDrawable(this);
}
updateRadius();
bool force_update = true; // avoid non-alpha mDistance update being optimized away
mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
@ -3523,48 +3515,6 @@ F32 LLVOVolume::getLightCutoff() const
}
}
bool LLVOVolume::setIsMirror(BOOL is_mirror)
{
BOOL was_mirror = isMirror();
if (is_mirror != was_mirror)
{
if (is_mirror)
{
setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, TRUE, true);
}
else
{
setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, FALSE, true);
}
}
updateMirrorDrawable();
return was_mirror != is_mirror;
}
void LLVOVolume::updateMirrorDrawable()
{
if (isMirror())
{
gPipeline.mHeroProbeManager.registerHeroDrawable(this);
}
else
{
gPipeline.mHeroProbeManager.unregisterHeroDrawable(this);
}
}
BOOL LLVOVolume::isMirror() const
{
return mIsMirror;
}
U8 LLVOVolume::mirrorFace() const
{
return mMirrorFace;
}
BOOL LLVOVolume::isReflectionProbe() const
{
return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
@ -3654,6 +3604,22 @@ bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
return false;
}
bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
{
LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
if (param_block)
{
if (param_block->getIsMirror() != is_mirror)
{
param_block->setIsMirror(is_mirror);
parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
return true;
}
}
return false;
}
F32 LLVOVolume::getReflectionProbeAmbiance() const
{
const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
@ -3702,6 +3668,18 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const
return false;
}
bool LLVOVolume::getReflectionProbeIsMirror() const
{
const LLReflectionProbeParams *param_block =
(const LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
if (param_block)
{
return param_block->getIsMirror();
}
return false;
}
U32 LLVOVolume::getVolumeInterfaceID() const
{
if (mVolumeImpl)
@ -4655,25 +4633,34 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
}
updateReflectionProbePtr();
if (isMirror())
gPipeline.mHeroProbeManager.registerHeroDrawable(this);
else
gPipeline.mHeroProbeManager.unregisterHeroDrawable(this);
}
void LLVOVolume::updateReflectionProbePtr()
{
if (isReflectionProbe())
{
if (mReflectionProbe.isNull())
if (mReflectionProbe.isNull() && !getReflectionProbeIsMirror())
{
mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
}
else if (mReflectionProbe.isNull() && getReflectionProbeIsMirror())
{
// Geenz: This is a special case - what we want here is a hero probe.
// What we want to do here is instantiate a hero probe from the hero probe manager.
gPipeline.mHeroProbeManager.registerViewerObject(this);
}
}
else if (mReflectionProbe.notNull())
else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror())
{
mReflectionProbe = nullptr;
if (mReflectionProbe.notNull())
{
mReflectionProbe = nullptr;
}
if (getReflectionProbeIsMirror())
{
gPipeline.mHeroProbeManager.unregisterViewerObject(this);
}
}
}

View File

@ -299,11 +299,6 @@ public:
F32 getLightRadius() const;
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
// Mirrors
bool setIsMirror(BOOL is_mirror);
void updateMirrorDrawable();
U8 mirrorFace() const override;
// Reflection Probes
bool setIsReflectionProbe(BOOL is_probe);
@ -311,14 +306,14 @@ public:
bool setReflectionProbeNearClip(F32 near_clip);
bool setReflectionProbeIsBox(bool is_box);
bool setReflectionProbeIsDynamic(bool is_dynamic);
bool setReflectionProbeIsMirror(bool is_mirror);
BOOL isReflectionProbe() const override;
F32 getReflectionProbeAmbiance() const;
F32 getReflectionProbeNearClip() const;
bool getReflectionProbeIsBox() const;
bool getReflectionProbeIsDynamic() const;
BOOL isMirror() const override;
bool getReflectionProbeIsMirror() const;
// Flexible Objects
U32 getVolumeInterfaceID() const;

View File

@ -851,6 +851,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mRT = &mAuxillaryRT;
U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
allocateScreenBuffer(res, res, samples);
res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it.
mRT = &mHeroProbeRT;
allocateScreenBuffer(res, res, samples);
mRT = &mMainRT;
gCubeSnapshot = FALSE;
}
@ -1159,7 +1164,12 @@ void LLPipeline::refreshCachedSettings()
RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples");
RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors)
{
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
LLViewerShaderMgr::instance()->clearShaderCache();
LLViewerShaderMgr::instance()->setShaders();
}
sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
RenderSpotLight = nullptr;

View File

@ -714,6 +714,9 @@ public:
// used by reflection probes and dynamic texture bakes
RenderTargetPack mAuxillaryRT;
// Auxillary render target pack scaled to the hero probe's per-face size.
RenderTargetPack mHeroProbeRT;
// currently used render target pack
RenderTargetPack* mRT;

View File

@ -2931,30 +2931,22 @@ Low ↔ Lwst
name="FlexForceZ"
top_pad="4"
width="128" />
<check_box
height="16"
label="Mirror"
layout="topleft"
left="10"
name="Mirror Checkbox Ctrl"
tool_tip="Causes object to be a mirror"
top_pad="8"
width="60" />
<check_box
height="16"
label="Light"
layout="topleft"
left_pad="10"
left="10"
name="Light Checkbox Ctrl"
tool_tip="Causes object to emit light"
top_delta="0"
top_pad="10"
width="60" />
<color_swatch
can_apply_immediately="true"
color="SL-MidDkGray"
border.border_thickness="0"
follows="left|top"
height="50"
height="48"
layout="topleft"
left_pad="10"
top_pad="-21"
@ -2983,7 +2975,7 @@ Low ↔ Lwst
layout="topleft"
left="10"
name="Light Intensity"
top_delta="32"
top_delta="30"
width="128" />
<spinner bottom_delta="0"
decimal_digits="3"
@ -3084,8 +3076,42 @@ Low ↔ Lwst
left="10"
name="Probe Dynamic"
tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
top_delta="17"
top_delta="19"
width="60" />
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
left="10"
name="Probe Update Label"
text_readonly_color="LabelDisabledColor"
top_delta="0"
width="100">
Probe Update
</text>
<combo_box
height="19"
top_delta="0"
left="144"
follows="left|top"
name="Probe Update Type"
tool_tip="Determines how the probe updates. Static updates the slowest and without avatars. Dynamic updates more frequently, with avatars visible in the probes. Mirror turns this probe into a realtime planar projected mirror probe, but does not calculate ambiance."
width="108">
<combo_box.item
label="Static"
name="Static"
value="Static" />
<combo_box.item
label="Dynamic"
name="Dynamic"
value="Dynamic"/>
<combo_box.item
label="Mirror"
name="Mirror"
value="Mirror"/>
</combo_box>
<spinner top_pad="0"
decimal_digits="3"
follows="left|top"