diff options
Diffstat (limited to 'indra')
55 files changed, 547 insertions, 439 deletions
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index f67959de5b..53d09df618 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1825,40 +1825,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; @@ -1968,6 +1934,19 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic) } } + +void LLReflectionProbeParams::setIsMirror(bool is_mirror) +{ + if (is_mirror) + { + mFlags |= FLAG_MIRROR; + } + else + { + mFlags &= ~FLAG_MIRROR; + } +} + //============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 88bac34ef2..5622483861 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -109,7 +109,6 @@ public: PARAMS_EXTENDED_MESH = 0x70, PARAMS_RENDER_MATERIAL = 0x80, PARAMS_REFLECTION_PROBE = 0x90, - PARAMS_MIRROR = 0x100, }; public: @@ -173,16 +172,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; @@ -197,6 +186,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: @@ -220,11 +210,13 @@ public: void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); } void setIsBox(bool is_box); void setIsDynamic(bool is_dynamic); + void setIsMirror(bool is_mirror); F32 getAmbiance() const { return mAmbiance; } F32 getClipDistance() const { return mClipDistance; } bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; } bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; } + bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; } }; //------------------------------------------------- diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 33d229bcc9..5384133220 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -44,6 +44,7 @@ using std::make_pair; using std::string; LLShaderMgr * LLShaderMgr::sInstance = NULL; +bool LLShaderMgr::sMirrorsEnabled = false; LLShaderMgr::LLShaderMgr() { @@ -183,7 +184,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) // Attach Fragment Shader Features Next /////////////////////////////////////// -// NOTE order of shader object attaching is VERY IMPORTANT!!! + // NOTE order of shader object attaching is VERY IMPORTANT!!! + + if (!shader->attachFragmentObject("deferred/globalF.glsl")) + { + return FALSE; + } + if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred) { if (!shader->attachFragmentObject("environment/srgbF.glsl")) @@ -224,14 +231,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - - if (features->hasHeroProbes) - { - if (!shader->attachFragmentObject("deferred/heroProbesUtil.glsl")) - { - return FALSE; - } - } if (features->hasShadows) { @@ -609,6 +608,11 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); } + if (sMirrorsEnabled) + { + extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n"); + } + // Use alpha float to store bit flags // See: C++: addDeferredAttachment(), shader: frag_data[2] extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 4ee5c8ef47..eb13418cd7 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -368,6 +368,7 @@ public: bool mShaderCacheInitialized = false; bool mShaderCacheEnabled = false; std::string mShaderCacheDir; + static bool sMirrorsEnabled; protected: diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 85b90a8da5..6ec9a9acc5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10388,18 +10388,7 @@ <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> diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 6ebe4ce251..c0607d0149 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index bc0c11ec46..5cc2846156 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -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; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 35f483f633..a22c174349 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 3af2eab1e4..74319349f6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index 6f3b94f734..e8ead91504 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index e5f2af2c53..a07c892d8e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 68fb8bf499..76776ede2c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 93d561504e..b983acf657 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 2402cc3b70..64230dc680 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index a6fab10791..52dfed06ae 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl new file mode 100644 index 0000000000..7e3e7d9271 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl @@ -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; + } + } +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 65706e2c3f..ddf878ae60 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -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 } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 9b98a37925..0683236460 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 160ae7a215..5e0141910b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index f6d509e2c6..2dba7cb9d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index 33a78fd26d..8e1e4b54d5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index e2d87e68fa..f108faf283 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -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) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index ce8a10712c..c84fccd4c6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index cb6f34713c..c1ed1bfe6e 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl index 67c99530e3..142f2a5d71 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index 7d5417919e..b8a02fbdec 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index acd32a81b3..4aef22c296 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 003dd05e6f..059c2a64ce 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index 8430cca325..c382a9fbc0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index b3b1aaed56..0476b98e10 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index d9dc83bb10..4f6e01764a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -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)); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index f1de0b88d6..cc6e16c64f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 223e55eb69..ef086fc3be 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -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 diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index b364e454e8..b2a81aa025 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -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); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 038858321c..28dd2a3c9a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1520,7 +1520,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; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index ec229711ea..c0e4ed38c1 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -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; ) diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 60c2682078..affea3f69c 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1675,8 +1675,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(); @@ -1687,6 +1685,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; + } } } } diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 6bd613622e..97b959e5cb 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -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); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 1ecafd4f54..2a81919856 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -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; -} diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 68cfdbfd99..552c5dcaab 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -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; }; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index a306a0a9ac..8d8263448d 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -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); @@ -309,10 +304,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(); @@ -401,17 +392,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 { @@ -425,10 +424,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 @@ -715,7 +732,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); @@ -755,20 +772,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")) @@ -1422,7 +1425,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(); @@ -1469,12 +1479,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) { diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index a658351624..aafefa918f 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -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); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index caa3f296dd..afae5f140b 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -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); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 4134e35f87..9ba42e4f47 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -764,6 +764,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(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index b07a3243c7..e6d9aed1a3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -656,6 +656,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)) @@ -696,7 +704,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } gPipeline.updateGL(); - + stop_glerror(); LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 691a2e14d3..d71814bd3f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -313,9 +313,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) { @@ -1149,39 +1147,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, @@ -1557,8 +1522,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); @@ -1946,8 +1909,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]; @@ -6328,11 +6289,6 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLReflectionProbeParams(); break; } - case LLNetworkData::PARAMS_MIRROR: - { - new_block = new LLMirrorParams(); - break; - } default: { LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index f3c00e83dc..80da7b2f73 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -257,8 +257,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 @@ -880,9 +878,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; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ce57585d82..cea083e07d 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2451,6 +2451,14 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) 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); } //this is called when the parent is not cacheable. diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 7149dc781f..4eb934114d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -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; @@ -227,7 +227,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; @@ -242,64 +242,98 @@ 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) { +} + +LLViewerShaderMgr::~LLViewerShaderMgr() +{ + mShaderLevel.clear(); + 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(&gSkinnedObjectBumpProgram); - mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram); - mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); - mShaderList.push_back(&gUnderWaterProgram); - mShaderList.push_back(&gDeferredSunProgram); + 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(&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(&gDeferredAlphaImpostorProgram); + mShaderList.push_back(&gDeferredFullbrightProgram); mShaderList.push_back(&gHUDFullbrightProgram); - mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram); mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram); mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram); - mShaderList.push_back(&gDeferredFullbrightShinyProgram); + 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(&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(&gDeferredSkinnedPBRAlphaProgram); mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma mShaderList.push_back(&gNoPostGammaCorrectProgram); mShaderList.push_back(&gLegacyPostGammaCorrectProgram); - -} - -LLViewerShaderMgr::~LLViewerShaderMgr() -{ - mShaderLevel.clear(); - mShaderList.clear(); + 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 @@ -354,6 +388,10 @@ void LLViewerShaderMgr::setShaders() return; } + mShaderList.clear(); + + LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors; + if (!gGLManager.mHasRequirements) { // Viewer will show 'hardware requirements' warning later @@ -535,6 +573,8 @@ void LLViewerShaderMgr::setShaders() } gPipeline.createGLBuffers(); + finalizeShaderList(); + reentrance = false; } @@ -679,6 +719,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) ); @@ -1067,9 +1108,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; @@ -1106,7 +1155,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; @@ -1808,11 +1857,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); @@ -2825,8 +2869,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) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 824c66ab49..57fc66ce0d 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -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; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9813039145..54e0a0113d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -249,9 +249,6 @@ LLVOVolume::~LLVOVolume() mTextureAnimp = NULL; delete mVolumeImpl; mVolumeImpl = NULL; - - if (mIsMirror) - gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); gMeshRepo.unregisterMesh(this); @@ -1000,11 +997,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); @@ -3327,48 +3319,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); @@ -3458,6 +3408,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); @@ -3506,6 +3472,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) @@ -4419,25 +4397,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); + } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b03fc4b862..cac09609b3 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -294,11 +294,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); @@ -306,14 +301,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; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d63b9d317e..9d90002eb9 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -785,6 +785,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; } @@ -1057,7 +1062,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; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fb28a0e41c..e8c6da1473 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -701,6 +701,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; diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 510351b471..72c78fec3d 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2412,15 +2412,6 @@ even though the user gets a free copy. width="278" /> <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="10" @@ -2568,16 +2559,52 @@ even though the user gets a free copy. name="Box" value="Box"/> </combo_box> + <check_box - height="16" - label="Dynamic" + height="16" + label="Dynamic" + layout="topleft" + left="10" + name="Probe Dynamic" + tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume." + bottom_delta="19" + width="60" /> + + <text + bottom_delta="-8" + type="string" + length="1" + follows="left|top" + height="10" layout="topleft" left="10" - name="Probe Dynamic" - tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume." - bottom_delta="19" - width="60" /> - <spinner bottom_delta="19" + name="Probe Update Label" + text_readonly_color="LabelDisabledColor" + 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 bottom_delta="17" decimal_digits="3" follows="left|top" height="16" |