diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index 61feecc3eee821006c4be14dc59ef4ac3ee51086..7b98ee3edffc8d2b5a83558c5ce4d499e77ac490 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -401,11 +401,7 @@ inline bool operator!=(const LLVector3d& a, const LLVector3d& b) // [RLVa:KB] - RlvBehaviourModifierCompMin/Max inline bool operator<(const LLVector3d& lhs, const LLVector3d& rhs) { - return (lhs.mdV[0] < rhs.mdV[0] - || (lhs.mdV[0] == rhs.mdV[0] - && (lhs.mdV[1] < rhs.mdV[1] - || ((lhs.mdV[1] == rhs.mdV[1]) - && lhs.mdV[2] < rhs.mdV[2])))); + return std::tie(lhs.mdV[0], lhs.mdV[1], lhs.mdV[2]) < std::tie(rhs.mdV[0], rhs.mdV[1], rhs.mdV[2]); } // [/RLVa:KB] diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index a4fe91b575f1e84185e0467ef6259e773c97108f..816b8adf739af9c764940c122ceeaf16677ff2da 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -471,13 +471,7 @@ inline LLVector4 operator-(const LLVector4 &a) // [RLVa:KB] - RlvBehaviourModifierCompMin/Max inline bool operator<(const LLVector4& lhs, const LLVector4& rhs) { - return (lhs.mV[0] < rhs.mV[0] - || (lhs.mV[0] == rhs.mV[0] - && (lhs.mV[1] < rhs.mV[1] - || ((lhs.mV[1] == rhs.mV[1]) - && lhs.mV[2] < rhs.mV[2] - || ((lhs.mV[2] == rhs.mV[2]) - && lhs.mV[3] < rhs.mV[3]))))); + return std::tie(lhs.mV[0], lhs.mV[1], lhs.mV[2], rhs.mV[3]) < std::tie(rhs.mV[0], rhs.mV[1], rhs.mV[2], rhs.mV[3]); } // [/RLVa:KB] diff --git a/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl b/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl index 8661ffe923cca2bd45c087ba6e343d4d54cfb947..4875523fb259684978d6c7cf955c2c38f913e163 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/rlvF.glsl @@ -147,7 +147,7 @@ void main() break; case 2: // Blur (variable) fragColor = texture2DRect(diffuseRect, fragTC).rgb; - fragColor = mix(fragColor, blurVariable(diffuseRect, fragTC, SPHERE_PARAMS.x, BLUR_DIRECTION, effectStrength), effectStrength > 0); + fragColor = mix(fragColor, blurVariable(diffuseRect, fragTC, SPHERE_PARAMS.x, BLUR_DIRECTION, effectStrength), int(effectStrength > 0)); break; case 3: // ChromaticAberration fragColor = chromaticAberration(diffuseRect, fragTC, SPHERE_PARAMS.xy, SPHERE_PARAMS.zw, effectStrength); diff --git a/indra/newview/app_settings/shaders/class1/deferred/rlvFLegacy.glsl b/indra/newview/app_settings/shaders/class1/deferred/rlvFLegacy.glsl new file mode 100644 index 0000000000000000000000000000000000000000..fce37c24beb94b00d230b182bd0421a56be386c2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/rlvFLegacy.glsl @@ -0,0 +1,176 @@ +/** + * + * Copyright (c) 2018-2020, 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 int rlvEffectMode; // ESphereMode +uniform vec4 rlvEffectParam1; // Sphere origin (in local coordinates) +uniform vec4 rlvEffectParam2; // Min/max dist + min/max value +uniform bvec2 rlvEffectParam3; // Min/max dist extend +uniform vec4 rlvEffectParam4; // Sphere params (=color when using blend) +uniform vec2 rlvEffectParam5; // Blur direction (not used for blend) + +#define SPHERE_ORIGIN rlvEffectParam1.xyz +#define SPHERE_DISTMIN rlvEffectParam2.y +#define SPHERE_DISTMAX rlvEffectParam2.w +#define SPHERE_DISTEXTEND rlvEffectParam3 +#define SPHERE_VALUEMIN rlvEffectParam2.x +#define SPHERE_VALUEMAX rlvEffectParam2.z +#define SPHERE_PARAMS rlvEffectParam4 +#define BLUR_DIRECTION rlvEffectParam5.xy + +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; +} + +vec3 blur13(sampler2DRect source, vec2 tc, vec2 direction) +{ + vec4 color = vec4(0.0); + vec2 off1 = vec2(1.411764705882353) * direction; + vec2 off2 = vec2(3.2941176470588234) * direction; + vec2 off3 = vec2(5.176470588235294) * direction; + + color += texture2DRect(source, tc) * 0.1964825501511404; + + color += texture2DRect(source, tc + off1) * 0.2969069646728344; + color += texture2DRect(source, tc - off1) * 0.2969069646728344; + + color += texture2DRect(source, tc + off2) * 0.09447039785044732; + color += texture2DRect(source, tc - off2) * 0.09447039785044732; + + color += texture2DRect(source, tc + off3) * 0.010381362401148057; + color += texture2DRect(source, tc - off3) * 0.010381362401148057; + + return color.xyz; +} + +const float pi = 3.14159265; + +// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html +vec3 blurVariable(sampler2DRect source, vec2 tc, float kernelSize, vec2 direction, float strength) { + float numBlurPixelsPerSide = float(kernelSize / 2); + + // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889) + vec3 incrementalGaussian; + incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * strength); + incrementalGaussian.y = exp(-0.5 / (strength * strength)); + incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y; + + vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0); + float coefficientSum = 0.0; + + // Take the central sample first... + avgValue += texture2DRect(source, tc) * incrementalGaussian.x; + coefficientSum += incrementalGaussian.x; + incrementalGaussian.xy *= incrementalGaussian.yz; + + // Go through the remaining 8 vertical samples (4 on each side of the center) + for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { + avgValue += texture2DRect(source, tc - i * direction) * incrementalGaussian.x; + avgValue += texture2DRect(source, tc + i * direction) * incrementalGaussian.x; + coefficientSum += 2.0 * incrementalGaussian.x; + incrementalGaussian.xy *= incrementalGaussian.yz; + } + + return (avgValue / coefficientSum).rgb; +} + +vec3 chromaticAberration(sampler2DRect source, vec2 tc, vec2 redDrift, vec2 blueDrift, float strength) +{ + vec3 sourceColor = texture2DRect(source, tc).rgb; + + // Sample the color components + vec3 driftColor; + driftColor.r = texture2DRect(source, tc + redDrift).r; + driftColor.g = sourceColor.g; + driftColor.b = texture2DRect(source, tc + blueDrift).b; + + // Adjust the strength of the effect + return mix(sourceColor, driftColor, strength); +} + +void main() +{ + vec2 fragTC = vary_fragcoord.st; + float fragDepth = texture2DRect(depthMap, fragTC).x; + vec3 fragPosLocal = getPosition_d(fragTC, fragDepth).xyz; + float distance = length(fragPosLocal.xyz - SPHERE_ORIGIN); + + // Linear non-branching interpolation of the strength of the sphere effect (replaces if/elseif/else for x < min, min <= x <= max and x > max) + float effectStrength = SPHERE_VALUEMIN + mix(0.0, SPHERE_VALUEMAX - SPHERE_VALUEMIN, (distance - SPHERE_DISTMIN) / (SPHERE_DISTMAX - SPHERE_DISTMIN)); + if (distance < SPHERE_DISTMIN) + { + effectStrength = SPHERE_DISTEXTEND.x ? SPHERE_VALUEMIN : 0.0; + } + else if (distance > SPHERE_DISTMAX) + { + effectStrength = SPHERE_DISTEXTEND.y ? SPHERE_VALUEMAX : 0.0; + } + + vec3 fragColor; + if (rlvEffectMode == 0) // Blend + { + fragColor = texture2DRect(diffuseRect, fragTC).rgb; + fragColor = mix(fragColor, SPHERE_PARAMS.rgb, effectStrength); + } + else if (rlvEffectMode == 1) // Blur (fixed) + { + fragColor = blur13(diffuseRect, fragTC, effectStrength * BLUR_DIRECTION); + } + else if (rlvEffectMode == 2) // Blur (variable) + { + fragColor = texture2DRect(diffuseRect, fragTC).rgb; + if (effectStrength > 0) + { + fragColor = blurVariable(diffuseRect, fragTC, SPHERE_PARAMS.x, BLUR_DIRECTION, effectStrength); + } + } + else if (rlvEffectMode == 3) // ChromaticAberration + { + fragColor = chromaticAberration(diffuseRect, fragTC, SPHERE_PARAMS.xy, SPHERE_PARAMS.zw, effectStrength); + } + else if (rlvEffectMode == 4) // Pixelate + { + effectStrength = sign(effectStrength); + float pixelWidth = max(1, floor(SPHERE_PARAMS.x * effectStrength)); float pixelHeight = max(1, floor(SPHERE_PARAMS.y * effectStrength)); + fragTC = vec2(pixelWidth * floor(fragTC.x / pixelWidth), pixelHeight * floor(fragTC.y / pixelHeight)); + fragColor = texture2DRect(diffuseRect, fragTC).rgb; + } + + frag_color.rgb = fragColor; + frag_color.a = 0.0; +} diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 517ec78725e8b21a1477b0597594825dce45c41e..479b3cdda60efa2cecf174211879c73861adc591 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -4144,7 +4144,10 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() gRlvSphereProgram.mName = "RLVa Sphere Post Processing Shader"; gRlvSphereProgram.mShaderFiles.clear(); gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvV.glsl", GL_VERTEX_SHADER_ARB)); - gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB)); + if (gGLManager.mGLVersion >= 4.5f) + gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvF.glsl", GL_FRAGMENT_SHADER_ARB)); + else + gRlvSphereProgram.mShaderFiles.push_back(make_pair("deferred/rlvFLegacy.glsl", GL_FRAGMENT_SHADER_ARB)); gRlvSphereProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; success = gRlvSphereProgram.createShader(NULL, NULL); }