diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0df7400ffd..d808761f3b 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1256,6 +1256,9 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("camPosLocal"); // [RLVa:KB] - @setsphere mReservedUniforms.push_back("avPosLocal"); + mReservedUniforms.push_back("rlvEffectParam1"); + mReservedUniforms.push_back("rlvEffectParam2"); + mReservedUniforms.push_back("rlvEffectParam3"); // [/RLV:KB] mReservedUniforms.push_back("gWindDir"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ec45ab44cd..02fbd8e4d1 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -205,6 +205,9 @@ public: WL_CAMPOSLOCAL, // [RLVa:KB] - @setsphere RLV_AVPOSLOCAL, + RLV_EFFECT_PARAM1, + RLV_EFFECT_PARAM2, + RLV_EFFECT_PARAM3, // [/RLVa:KB] AVATAR_WIND, diff --git a/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl b/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl index 42694a9de2..9edcf16f2b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl @@ -28,14 +28,18 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect depthMap; uniform mat4 inv_proj; uniform vec2 screen_res; + uniform vec4 avPosLocal; +uniform vec4 rlvEffectParam1; +uniform vec4 rlvEffectParam2; +uniform vec4 rlvEffectParam3; vec4 getPosition_d(vec2 pos_screen, float depth) { - vec2 sc = pos_screen.xy*2.0; + vec2 sc = pos_screen.xy * 2.0; sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0 * depth - 1.0, 1.0); vec4 pos = inv_proj * ndc; pos /= pos.w; pos.w = 1.0; @@ -44,30 +48,36 @@ vec4 getPosition_d(vec2 pos_screen, float depth) void main() { - vec2 tc = vary_fragcoord.xy; - - vec4 diffuse = texture2DRect(diffuseRect, tc); - vec3 col = diffuse.rgb; - - float depth = texture2DRect(depthMap, tc.xy).r; - vec3 pos = getPosition_d(tc, depth).xyz; + vec2 fragTC = vary_fragcoord.xy; + float fragDepth = texture2DRect(depthMap, fragTC.xy).r; + vec3 fragPosLocal = getPosition_d(fragTC, fragDepth).xyz; + vec3 fragColor = texture2DRect(diffuseRect, fragTC).rgb; { - float cutoff = 20; - float cutoff2 = 45; - float minAlpha = 0.0f; - float maxAlpha = 0.95f; - vec3 fogColor = vec3(0., 0., 0.); + vec2 blendStart = rlvEffectParam1.xy; + vec2 blendEnd = rlvEffectParam1.zw; + vec3 blendColor = rlvEffectParam2.rgb; - float distance = length(pos.xyz - avPosLocal.xyz) ; + float cutoff = blendStart.y; + float cutoff2 = blendEnd.y; + float minAlpha = blendStart.x; + float maxAlpha = blendEnd.x; - float density = 1; - float fracDistance = (distance - cutoff) / (cutoff2 - cutoff); - float visionFactor = clamp((1 - maxAlpha) + (exp(-density * fracDistance) * (maxAlpha - minAlpha)), 0.0, 1.0); - col = mix(fogColor, col, visionFactor); - col *= 1 - ((distance - cutoff) / (cutoff2 - cutoff)); + float distance = length(fragPosLocal.xyz - avPosLocal.xyz); + if (distance < cutoff) + { + discard; + } + else if (distance < cutoff2) + { + fragColor = mix(fragColor, blendColor, minAlpha + (distance - cutoff) * (maxAlpha - minAlpha) / (cutoff2 - cutoff)); + } + else + { + fragColor = mix(fragColor, blendColor, maxAlpha); + } } - frag_color.rgb = col; + frag_color.rgb = fragColor; frag_color.a = 0.0; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4ee5dc5caf..a583a50ad8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -9049,6 +9049,7 @@ void LLPipeline::renderDeferredLighting() mScreen.flush(); // [RLVa:KB] - @setsphere + if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) { LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_RLV); @@ -9070,18 +9071,7 @@ void LLPipeline::renderDeferredLighting() gGL.getTexUnit(nDepthChannel)->bind(&mDeferredDepth, TRUE); } - if (isAgentAvatarValid()) - { - LLVector4 avPos(gAgentAvatarp->getRenderPosition(), 1.0f); - glh::vec4f avPosGl(avPos.mV); - - const glh::matrix4f& mvMatrix = gGL.getModelviewMatrix(); - mvMatrix.mult_matrix_vec(avPosGl); - - gDeferredRlvProgram.uniform4fv(LLShaderMgr::RLV_AVPOSLOCAL, 1, avPosGl.v); - } - gDeferredRlvProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); - gDeferredRlvProgram.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, glh_get_current_projection().inverse().m); + RlvActions::setEffectSphereShaderUniforms(&gDeferredRlvProgram, &mScreen); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 83c44583d8..add7e74056 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -17,6 +17,7 @@ #include "llviewerprecompiledheaders.h" #include "llagent.h" #include "llimview.h" +#include "llshadermgr.h" #include "llviewercamera.h" #include "llvoavatarself.h" #include "llworld.h" @@ -246,6 +247,38 @@ EChatType RlvActions::checkChatVolume(EChatType chatType) return chatType; } +// ============================================================================ +// Effects +// + +// static +void RlvActions::setEffectSphereShaderUniforms(LLGLSLShader* pShader, LLRenderTarget* pRenderTarget) +{ + if (!pShader || !pRenderTarget) + return; + + pShader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, glh_get_current_projection().inverse().m); + pShader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, pRenderTarget->getWidth(), pRenderTarget->getHeight()); + + // Pass the center of the sphere to the shader + const LLVector4 posSphereOrigin(isAgentAvatarValid() ? gAgentAvatarp->getRenderPosition() : gAgent.getPositionAgent() , 1.0f); + glh::vec4f posSphereOriginGl(posSphereOrigin.mV); + const glh::matrix4f& mvMatrix = gGL.getModelviewMatrix(); + mvMatrix.mult_matrix_vec(posSphereOriginGl); + pShader->uniform4fv(LLShaderMgr::RLV_AVPOSLOCAL, 1, posSphereOriginGl.v); + + const RlvBehaviourDictionary& rlvBhvrDict = RlvBehaviourDictionary::instance(); + + // Pack min/max distance and alpha together + pShader->uniform4f(LLShaderMgr::RLV_EFFECT_PARAM1, + rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MINALPHA)->getValue(), rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MINDIST)->getValue(), + rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MAXALPHA)->getValue(), rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MAXDIST)->getValue()); + + // Pass color + const glh::vec4f sphereColor(rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_COLOR)->getValue().mV, 1.0); + pShader->uniform4fv(LLShaderMgr::RLV_EFFECT_PARAM2, 1, sphereColor.v); +} + // ============================================================================ // Inventory // diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 90b1069f6b..87d8a44290 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -24,8 +24,10 @@ // Forward declarations // +class LLGLSLShader; class LLInventoryCategory; class LLInventoryItem; +class LLRenderTarget; // ============================================================================ // RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible @@ -135,6 +137,15 @@ protected: // Backwards logic so that we can initialize to 0 and it won't block when we forget to/don't check if RLVa is disabled static bool s_BlockNamesContexts[SNC_COUNT]; + // ======= + // Effects + // ======= +public: + /* + * Sets the uniform values needed by the 'vision spheres' effect + */ + static void setEffectSphereShaderUniforms(LLGLSLShader* pShader, LLRenderTarget* renderTarget); + // ========= // Inventory // ========= diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index f8cb3f3295..ccdbb8778e 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -234,6 +234,15 @@ enum ERlvBehaviour { // Camera (force) RLV_BHVR_SETCAM_MODE, // Switch the user's camera into the specified mode (e.g. mouselook or thirdview) + // Effect: "vision spheres" + RLV_BHVR_SETSPHERE, // Gives an object exclusive control of the 'vision spheres' effect + RLV_BHVR_SETSPHERE_COLOR, + RLV_BHVR_SETSPHERE_DENSITY, + RLV_BHVR_SETSPHERE_MAXALPHA, + RLV_BHVR_SETSPHERE_MAXDIST, + RLV_BHVR_SETSPHERE_MINALPHA, + RLV_BHVR_SETSPHERE_MINDIST, + // Overlay RLV_BHVR_SETOVERLAY, // Gives an object exclusive control of the overlay RLV_BHVR_SETOVERLAY_ALPHA, // Changes the overlay texture's transparency level @@ -248,17 +257,28 @@ enum ERlvBehaviour { enum ERlvBehaviourModifier { + // "Vision spheres" post processing effect + RLV_MODIFIER_EFFECT_SPHERE_COLOR, // Colour to mix with the actual pixel colour (alpha depends non-linerally ) + RLV_MODIFIER_EFFECT_SPHERE_DENSITY, // Not exposed at the moment + RLV_MODIFIER_EFFECT_SPHERE_MAXALPHA,// Alpha of the mix colour at maximum distance + RLV_MODIFIER_EFFECT_SPHERE_MAXDIST, // Distance at which the blending stops ; or colour = mix(colour, sphere_colour, max_alpha) + RLV_MODIFIER_EFFECT_SPHERE_MINALPHA,// Alpha of the mix colour at minimum distance + RLV_MODIFIER_EFFECT_SPHERE_MINDIST, // Distance at which the gradual blending starts; or colour = mix(colour, sphere_colour, min_alpha) + RLV_MODIFIER_FARTOUCHDIST, // Radius of a sphere around the user in which they can interact with the world + RLV_MODIFIER_OVERLAY_ALPHA, // Transparency level of the overlay texture (in addition to the texture's own alpha channel) RLV_MODIFIER_OVERLAY_TEXTURE, // Specifies the UUID of the overlay texture RLV_MODIFIER_OVERLAY_TINT, // The tint that's applied to the overlay texture RLV_MODIFIER_OVERLAY_TOUCH, // Determines whether the overlay texture's alpha channel will be used to allow/block world interaction + RLV_MODIFIER_RECVIMDISTMIN, // Minimum distance to receive an IM from an otherwise restricted sender (squared value) RLV_MODIFIER_RECVIMDISTMAX, // Maximum distance to receive an IM from an otherwise restricted sender (squared value) RLV_MODIFIER_SENDIMDISTMIN, // Minimum distance to send an IM to an otherwise restricted recipient (squared value) RLV_MODIFIER_SENDIMDISTMAX, // Maximum distance to send an IM to an otherwise restricted recipient (squared value) RLV_MODIFIER_STARTIMDISTMIN, // Minimum distance to start an IM to an otherwise restricted recipient (squared value) RLV_MODIFIER_STARTIMDISTMAX, // Maximum distance to start an IM to an otherwise restricted recipient (squared value) + RLV_MODIFIER_SETCAM_AVDIST, // Distance at which nearby avatars turn into a silhouette (normal value) RLV_MODIFIER_SETCAM_AVDISTMIN, // Minimum distance between the camera position and the user's avatar (normal value) RLV_MODIFIER_SETCAM_AVDISTMAX, // Maximum distance between the camera position and the user's avatar (normal value) @@ -269,6 +289,7 @@ enum ERlvBehaviourModifier RLV_MODIFIER_SETCAM_FOVMIN, // Minimum value for the camera's field of view (angle in radians) RLV_MODIFIER_SETCAM_FOVMAX, // Maximum value for the camera's field of view (angle in radians) RLV_MODIFIER_SETCAM_TEXTURE, // Specifies the UUID of the texture used to texture the world view + RLV_MODIFIER_SITTPDIST, RLV_MODIFIER_TPLOCALDIST, diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index b159634c7c..03ad05108d 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -210,6 +210,19 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor("camzoommax", RlvBehaviourInfo::BHVR_DEPRECATED)); addEntry(new RlvBehaviourGenericToggleProcessor("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED)); + // Effect: "vision spheres" + addEntry(new RlvBehaviourGenericProcessor("setsphere", RLV_BHVR_SETSPHERE, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addModifier(new RlvForceGenericProcessor("setsphere_color", RLV_BHVR_SETSPHERE_COLOR, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_EFFECT_SPHERE_COLOR, new RlvBehaviourModifier("Effect: Vision spheres - Color", LLVector3(.0f, .0f, .0f), true, new RlvBehaviourModifierComp())); + addModifier(new RlvForceGenericProcessor("setsphere_maxdist", RLV_BHVR_SETSPHERE_MAXDIST, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_EFFECT_SPHERE_MAXDIST, new RlvBehaviourModifier("Effect: Vision spheres - Max distance", 0.f, false, new RlvBehaviourModifierCompMin())); + addModifier(new RlvForceGenericProcessor("setsphere_maxalpha", RLV_BHVR_SETSPHERE_MAXALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_EFFECT_SPHERE_MAXALPHA, new RlvBehaviourModifier("Effect: Vision spheres - Max distance alpha", 1.0f, false, new RlvBehaviourModifierCompMax())); + addModifier(new RlvForceGenericProcessor("setsphere_mindist", RLV_BHVR_SETSPHERE_MINDIST, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_EFFECT_SPHERE_MINDIST, new RlvBehaviourModifier("Effect: Vision spheres - Min distance", 0.f, false, new RlvBehaviourModifierCompMin())); + addModifier(new RlvForceGenericProcessor("setsphere_minalpha", RLV_BHVR_SETSPHERE_MINALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL), + RLV_MODIFIER_EFFECT_SPHERE_MINALPHA, new RlvBehaviourModifier("Effect: Vision spheres - Min distance alpha", 1.0f, false, new RlvBehaviourModifierCompMax())); + // Overlay addEntry(new RlvBehaviourGenericToggleProcessor("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(new RlvForceGenericProcessor("setoverlay_alpha", RLV_BHVR_SETOVERLAY_ALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL),