summaryrefslogtreecommitdiff
path: root/src/render/shaders
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-03-27 10:08:56 -0400
committerGitHub <noreply@github.com>2026-03-27 14:08:56 +0000
commit2c4852e31f1cc974164fdd1bf383a67c26cafe44 (patch)
treec248ef256b6ff1d8de9fe031ff2bf33b67e85dde /src/render/shaders
parent2fde538e0fa5663ac99f631fcfee6742e09368f6 (diff)
renderer/deco: add glow decoration (#13862)
Diffstat (limited to 'src/render/shaders')
-rw-r--r--src/render/shaders/glsl/inner_glow.frag57
-rw-r--r--src/render/shaders/glsl/inner_glow.glsl106
2 files changed, 163 insertions, 0 deletions
diff --git a/src/render/shaders/glsl/inner_glow.frag b/src/render/shaders/glsl/inner_glow.frag
new file mode 100644
index 00000000..2fc405c0
--- /dev/null
+++ b/src/render/shaders/glsl/inner_glow.frag
@@ -0,0 +1,57 @@
+#version 300 es
+#define ALLOW_INCLUDES
+#extension GL_ARB_shading_language_include : enable
+
+#include "defines.h"
+
+precision highp float;
+in vec4 v_color;
+in vec2 v_texcoord;
+
+uniform int sourceTF; // eTransferFunction
+uniform int targetTF; // eTransferFunction
+uniform mat3 targetPrimariesXYZ;
+
+uniform vec2 topLeft;
+uniform vec2 bottomRight;
+uniform vec2 fullSize;
+uniform float radius;
+uniform float roundingPower;
+uniform float range;
+uniform float shadowPower;
+
+#if USE_CM
+#include "cm_helpers.glsl"
+#include "CM.glsl"
+#endif
+
+#include "inner_glow.glsl"
+
+layout(location = 0) out vec4 fragColor;
+void main() {
+ vec4 pixColor = v_color;
+
+ fragColor = getInnerGlow(pixColor, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight
+#if USE_CM
+ ,
+ sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange
+#if USE_ICC
+ ,
+ iccLut3D, iccLutSize
+#else
+#if USE_TONEMAP || USE_SDR_MOD
+ ,
+ targetPrimariesXYZ
+#endif
+#if USE_TONEMAP
+ ,
+ maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance
+#endif
+#if USE_SDR_MOD
+ ,
+ sdrSaturation, sdrBrightnessMultiplier
+#endif
+#endif
+#endif
+ );
+}
diff --git a/src/render/shaders/glsl/inner_glow.glsl b/src/render/shaders/glsl/inner_glow.glsl
new file mode 100644
index 00000000..b0d55b19
--- /dev/null
+++ b/src/render/shaders/glsl/inner_glow.glsl
@@ -0,0 +1,106 @@
+#ifndef ALLOW_INCLUDES
+#define ALLOW_INCLUDES
+#extension GL_ARB_shading_language_include : enable
+#endif
+#ifndef INNER_GLOW_GLSL
+#define INNER_GLOW_GLSL
+
+#include "cm_helpers.glsl"
+
+float innerGlowAlpha(float distFromEdge, float range, float glowPower) {
+ if (distFromEdge >= range)
+ return 0.0;
+
+ if (distFromEdge <= 0.0)
+ return 1.0;
+
+ return pow(1.0 - distFromEdge / range, glowPower);
+}
+
+float innerGlowModifiedLength(vec2 a, float roundingPower) {
+ return pow(pow(abs(a.x), roundingPower) + pow(abs(a.y), roundingPower), 1.0 / roundingPower);
+}
+
+float innerGlowSmin(float a, float b, float k) {
+ float h = max(k - abs(a - b), 0.0) / k;
+ return min(a, b) - h * h * h * k * (1.0 / 6.0);
+}
+
+vec4 getInnerGlow(vec4 pixColor, vec2 v_texcoord, float radius, float roundingPower, vec2 topLeft, vec2 fullSize, float range, float glowPower, vec2 bottomRight
+#if USE_CM
+ ,
+ int sourceTF, int targetTF, mat3 convertMatrix, vec2 srcTFRange, vec2 dstTFRange
+#if USE_ICC
+ ,
+ highp sampler3D iccLut3D, float iccLutSize
+#else
+#if USE_TONEMAP || USE_SDR_MOD
+ ,
+ mat3 targetPrimariesXYZ
+#endif
+#if USE_TONEMAP
+ ,
+ float maxLuminance, float dstMaxLuminance, float dstRefLuminance, float srcRefLuminance
+#endif
+#if USE_SDR_MOD
+ ,
+ float sdrSaturation, float sdrBrightnessMultiplier
+#endif
+#endif
+#endif
+) {
+ vec2 pixCoord = fullSize * v_texcoord;
+
+ // clip to the rounded rectangle shape using actual SDF
+ vec2 center = fullSize * 0.5;
+ vec2 p = abs(pixCoord - center);
+ vec2 q = p - (center - vec2(radius));
+ vec2 qc = max(q, vec2(0.0));
+ float cornerD = (qc.x > 0.0 || qc.y > 0.0) ? innerGlowModifiedLength(qc, roundingPower) : 0.0;
+ float sdfDist = cornerD + min(max(q.x, q.y), 0.0) - radius;
+
+ if (sdfDist > 0.0)
+ discard;
+
+ // smooth-min of edge distances for rounded glow contours
+ float distT = pixCoord.y;
+ float distB = fullSize.y - pixCoord.y;
+ float distL = pixCoord.x;
+ float distR = fullSize.x - pixCoord.x;
+
+ float k = range;
+ float distFromEdge = innerGlowSmin(innerGlowSmin(distT, distB, k), innerGlowSmin(distL, distR, k), k);
+
+ pixColor[3] = pixColor[3] * innerGlowAlpha(distFromEdge, range, glowPower);
+
+ if (pixColor[3] == 0.0)
+ discard;
+
+ // premultiply
+ pixColor.rgb *= pixColor[3];
+
+#if USE_CM
+ pixColor = doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange
+#if USE_ICC
+ ,
+ iccLut3D, iccLutSize
+#else
+#if USE_TONEMAP || USE_SDR_MOD
+ ,
+ targetPrimariesXYZ
+#endif
+#if USE_TONEMAP
+ ,
+ maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance
+#endif
+#if USE_SDR_MOD
+ ,
+ sdrSaturation, sdrBrightnessMultiplier
+#endif
+#endif
+ );
+#endif
+
+ return pixColor;
+}
+#endif