diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 643c36887041300b8fa25c5ef240c180d37f2347..a827d01aaf646165e285160edf240c3b90a9490e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1252,6 +1252,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("sunAngle2"); 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"); mReservedUniforms.push_back("gSinWaveParams"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 394b38f832329964798deee031671f4b6d715fa2..02fbd8e4d173b39628b312191e7f9c4ab4a93c86 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -203,6 +203,12 @@ class LLShaderMgr WATER_SUN_ANGLE2, WL_CAMPOSLOCAL, +// [RLVa:KB] - @setsphere + RLV_AVPOSLOCAL, + RLV_EFFECT_PARAM1, + RLV_EFFECT_PARAM2, + RLV_EFFECT_PARAM3, +// [/RLVa:KB] AVATAR_WIND, AVATAR_SINWAVE, diff --git a/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl b/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl new file mode 100644 index 0000000000000000000000000000000000000000..9edcf16f2b5183c208d1538eaf71c2f078aab7bd --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/rlvF.glsl @@ -0,0 +1,83 @@ +/** + * + * Copyright (c) 2018, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR + out vec4 frag_color; +#else + #define frag_color gl_FragColor +#endif + +VARYING vec2 vary_fragcoord; + +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; + sc /= screen_res; + 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; + return pos; +} + +void main() +{ + 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; + { + vec2 blendStart = rlvEffectParam1.xy; + vec2 blendEnd = rlvEffectParam1.zw; + vec3 blendColor = rlvEffectParam2.rgb; + + float cutoff = blendStart.y; + float cutoff2 = blendEnd.y; + float minAlpha = blendStart.x; + float maxAlpha = blendEnd.x; + + 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 = fragColor; + frag_color.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/rlvV.glsl b/indra/newview/app_settings/shaders/class2/deferred/rlvV.glsl new file mode 100644 index 0000000000000000000000000000000000000000..19124b6101228990af13503585b93fe6edf8086b --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/rlvV.glsl @@ -0,0 +1,33 @@ +/** + * + * Copyright (c) 2018, Kitty Barnett + * + * The source code in this file is provided to you under the terms of the + * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt + * + * By copying, modifying or distributing this software, you acknowledge that + * you have read and understood your obligations described above, and agree to + * abide by those obligations. + * + */ + +ATTRIBUTE vec3 position; + +uniform vec2 screen_res; + +VARYING vec2 vary_fragcoord; +VARYING vec3 vary_position; + +void main() +{ + //transform vertex + vec4 pos = vec4(position.xyz, 1.0); + gl_Position = pos; + + + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + vary_position = (vec4(1, 0, 0, 1.0)).xyz; +} diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 6d8b27ff2d84f159033073b353c29d22f6f00c9e..7497e122aacbb1b8b75781fbe7c51d48821b3d5d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -243,6 +243,9 @@ LLGLSLShader gDeferredFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightProgram; LLGLSLShader gNormalMapGenProgram; +// [RLVa:KB] - @setsphere +LLGLSLShader gDeferredRlvProgram; +// [/RLVa:KB] // Deferred materials shaders LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; @@ -348,6 +351,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredAvatarAlphaProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); +// [RLVa:KB] - @setsphere + mShaderList.push_back(&gDeferredRlvProgram); +// [/RLVa:KB] } LLViewerShaderMgr::~LLViewerShaderMgr() @@ -1175,6 +1181,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightShinyProgram.unload(); gDeferredSkinnedFullbrightShinyProgram.unload(); gDeferredSkinnedFullbrightProgram.unload(); +// [RLVa:KB] - @setsphere + gDeferredRlvProgram.unload(); +// [/RLVa:KB] gDeferredHighlightProgram.unload(); gDeferredHighlightNormalProgram.unload(); @@ -2087,6 +2096,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gNormalMapGenProgram.createShader(NULL, NULL); } +// [RLVa:KB] - @setsphere + if (success) + { + gDeferredRlvProgram.mName = "Deferred (RLVa) Post Processing Shader"; + gDeferredRlvProgram.mShaderFiles.clear(); + gDeferredRlvProgram.mShaderFiles.push_back(make_pair("deferred/rlvV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredRlvProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredRlvProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredRlvProgram.createShader(NULL, NULL); + } +// [/RLV:KB] + return success; } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 9edaa97e576806b60c63e8b3ac88b89fecf718f6..dfcfbb89c7bf8f0b62189170c6a4c2a733dfbc94 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -344,6 +344,9 @@ extern LLGLSLShader gDeferredFullbrightShinyProgram; extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; extern LLGLSLShader gDeferredSkinnedFullbrightProgram; extern LLGLSLShader gNormalMapGenProgram; +// [RLVa:KB] - @setsphere +extern LLGLSLShader gDeferredRlvProgram; +// [/RLVa:KB] // Deferred materials shaders extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cbf477d76ffe1ddecc9992899438ff7ae08f1b53..f493299ccaf7026774604a86bf532737720329ae 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -259,6 +259,9 @@ LLTrace::BlockTimerStatHandle FTM_STATESORT("Sort Draw State"); LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline"); LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy"); LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading"); +// [RLVa:KB] - @setsphere +LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_RLV("Post-process (Deferred RLVa)"); +// [/RLVa:KB] static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables"); @@ -9080,6 +9083,79 @@ void LLPipeline::renderDeferredLighting() mScreen.flush(); +// [RLVa:KB] - @setsphere + if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) + { + LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_RLV); + + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + + mScreen.bindTarget(); + gDeferredRlvProgram.bind(); + + S32 nDiffuseChannel = gDeferredRlvProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (nDiffuseChannel > -1) + { + mScreen.bindTexture(0, nDiffuseChannel); + gGL.getTexUnit(nDiffuseChannel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + S32 nDepthChannel = gDeferredRlvProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); + if (nDepthChannel > -1) + { + gGL.getTexUnit(nDepthChannel)->bind(&mDeferredDepth, TRUE); + } + + RlvActions::setEffectSphereShaderUniforms(&gDeferredRlvProgram, &mScreen); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + + int nRenderMethod = 0; + switch (nRenderMethod) + { + case 0: + { + LLVector2 tc1(0, 0); + LLVector2 tc2((F32)mScreen.getWidth() * 2, (F32)mScreen.getHeight() * 2); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + } + break; + case 1: + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + break; + } + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + + gDeferredRlvProgram.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + gDeferredRlvProgram.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mScreen.getUsage()); + gDeferredRlvProgram.unbind(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->activate(); + + mScreen.flush(); + } +// [/RLVa:KB] } void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index e96fdbcf601c7486fa01ccf3dc445d73f5544529..bb656372c391bd5d305e21561d129921cb29de9e 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" @@ -257,6 +258,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<float>(), rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MINDIST)->getValue<float>(), + rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MAXALPHA)->getValue<float>(), rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_MAXDIST)->getValue<float>()); + + // Pass color + const glh::vec4f sphereColor(rlvBhvrDict.getModifier(RLV_MODIFIER_EFFECT_SPHERE_COLOR)->getValue<LLVector3>().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 a6a52199330d3a05f0ca3b8f869c318e79c96fd3..7525ef860ba1a154cc8a2f27ef3b47398208a4c5 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 @@ -140,6 +142,15 @@ class RlvActions // 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 827a2d74c788cc72252eeb59ea4ed860c997f4b6..1b97316143cc82a31dc35616c504de3e72167951 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -240,6 +240,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 @@ -254,17 +263,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) @@ -276,6 +296,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 b08875fca55423127ce76573f81cfe2d49e2e711..a57bc03b6898bfce7e7202028b11aa4a1b6814f7 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -214,6 +214,19 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor<RLV_BHVR_CAMZOOMMAX, RlvBehaviourCamZoomMinMaxHandler>("camzoommax", RlvBehaviourInfo::BHVR_DEPRECATED)); addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM_UNLOCK, RLV_OPTION_NONE>("camunlock", RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED)); + // Effect: "vision spheres" + addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setsphere", RLV_BHVR_SETSPHERE, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("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<RLV_OPTION_MODIFIER>("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<RLV_OPTION_MODIFIER>("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<RLV_OPTION_MODIFIER>("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<RLV_OPTION_MODIFIER>("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<RLV_BHVR_SETOVERLAY, RLV_OPTION_NONE>("setoverlay", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(new RlvForceGenericProcessor<RLV_OPTION_MODIFIER>("setoverlay_alpha", RLV_BHVR_SETOVERLAY_ALPHA, RlvBehaviourInfo::BHVR_EXPERIMENTAL),