diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-03-27 10:08:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-27 14:08:56 +0000 |
| commit | 2c4852e31f1cc974164fdd1bf383a67c26cafe44 (patch) | |
| tree | c248ef256b6ff1d8de9fe031ff2bf33b67e85dde /src/render/shaders | |
| parent | 2fde538e0fa5663ac99f631fcfee6742e09368f6 (diff) | |
renderer/deco: add glow decoration (#13862)
Diffstat (limited to 'src/render/shaders')
| -rw-r--r-- | src/render/shaders/glsl/inner_glow.frag | 57 | ||||
| -rw-r--r-- | src/render/shaders/glsl/inner_glow.glsl | 106 |
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 |
