/** * WebGL Gradient Shader * * Canvas Texture 없이 GLSL uniform만으로 linear / circular gradient를 렌더링합니다. * 최대 8개 color stop 지원. SDF border-radius 및 ellipse 클리핑 내장. * GLSL ES 1.00 호환 (constant index only). */ export declare const gradientVertex = "\n attribute vec2 position;\n attribute vec2 uv;\n uniform mat4 uModelMatrix;\n uniform mat4 uViewMatrix;\n uniform mat4 uProjectionMatrix;\n varying vec2 vUV;\n\n void main() {\n vUV = uv;\n gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(position, 0.0, 1.0);\n }\n"; export declare const gradientFragment = "\n precision highp float;\n\n #define PI 3.14159265358979323846\n\n uniform int uStopCount;\n uniform vec4 uStopColors0;\n uniform vec4 uStopColors1;\n uniform vec4 uStopColors2;\n uniform vec4 uStopColors3;\n uniform vec4 uStopColors4;\n uniform vec4 uStopColors5;\n uniform vec4 uStopColors6;\n uniform vec4 uStopColors7;\n uniform float uStopOffset0;\n uniform float uStopOffset1;\n uniform float uStopOffset2;\n uniform float uStopOffset3;\n uniform float uStopOffset4;\n uniform float uStopOffset5;\n uniform float uStopOffset6;\n uniform float uStopOffset7;\n uniform float uDirection;\n uniform int uType;\n\n uniform vec2 uSize;\n uniform vec4 uBorderRadius;\n uniform float uIsEllipse;\n uniform float uOpacity;\n\n varying vec2 vUV;\n\n float sdRoundedBox(vec2 p, vec2 b, vec4 r) {\n float rx = (p.x > 0.0)\n ? ((p.y > 0.0) ? r.y : r.z)\n : ((p.y > 0.0) ? r.x : r.w);\n vec2 q = abs(p) - b + rx;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - rx;\n }\n\n vec4 getColor(int i) {\n if (i == 0) return uStopColors0;\n if (i == 1) return uStopColors1;\n if (i == 2) return uStopColors2;\n if (i == 3) return uStopColors3;\n if (i == 4) return uStopColors4;\n if (i == 5) return uStopColors5;\n if (i == 6) return uStopColors6;\n return uStopColors7;\n }\n\n float getOffset(int i) {\n if (i == 0) return uStopOffset0;\n if (i == 1) return uStopOffset1;\n if (i == 2) return uStopOffset2;\n if (i == 3) return uStopOffset3;\n if (i == 4) return uStopOffset4;\n if (i == 5) return uStopOffset5;\n if (i == 6) return uStopOffset6;\n return uStopOffset7;\n }\n\n vec4 evalStops(float t) {\n if (t <= uStopOffset0) return uStopColors0;\n vec4 result = uStopColors0;\n for (int i = 0; i < 7; i++) {\n int next = i + 1;\n if (next >= uStopCount) break;\n float s0 = getOffset(i);\n float s1 = getOffset(next);\n if (t >= s0 && t <= s1) {\n float localT = (s1 > s0) ? (t - s0) / (s1 - s0) : 0.0;\n result = mix(getColor(i), getColor(next), localT);\n break;\n }\n result = getColor(next);\n }\n return result;\n }\n\n void main() {\n vec2 p = (vUV - 0.5) * uSize;\n\n if (uIsEllipse > 0.5) {\n vec2 pN = vUV * 2.0 - 1.0;\n if (dot(pN, pN) > 1.0) discard;\n } else {\n float d = sdRoundedBox(p, uSize * 0.5, uBorderRadius);\n if (d > 0.0) discard;\n }\n\n float t;\n if (uType == 1) {\n vec2 pNorm = vUV * 2.0 - 1.0;\n t = clamp(length(pNorm), 0.0, 1.0);\n } else {\n float rad = (uDirection - 90.0) * PI / 180.0;\n vec2 dir = vec2(cos(rad), -sin(rad));\n t = clamp(dot(vUV - 0.5, dir) + 0.5, 0.0, 1.0);\n }\n\n vec4 color = evalStops(t);\n float a = color.a * uOpacity;\n gl_FragColor = vec4(color.rgb * a, a);\n }\n";