responsive-image-canvas/dist/distortion.frag.glsl
BaekRyang e66b078dd8 build: Update compiled distribution files
- Update CJS and ESM bundles with coordinate system fixes
- Update type definitions (d.ts, d.mts)
- Add editor styles (CSS)
- Update shader files
- Update source maps
2025-11-05 11:20:53 +09:00

86 lines
2.8 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

uniform vec2 u_resolution;
uniform sampler2D u_texture;
uniform vec2 u_points[32]; // 최대 8영역 × 4포인트 (정규화된 좌표 0-1)
uniform int u_numAreas;
uniform vec2 u_dragVectors[8]; // 드래그 벡터 (정규화된 좌표 0-1)
uniform float u_distortionStrengths[8];
varying vec2 vUv;
// Flutter 원본 computeUV 함수 (정확히 동일하게 변환)
vec2 computeUV(vec2 xy, vec2 p0, vec2 p1, vec2 p2, vec2 p3) {
vec2 minP = min(min(p0, p1), min(p2, p3));
vec2 maxP = max(max(p0, p1), max(p2, p3));
if (xy.x < minP.x || xy.x > maxP.x || xy.y < minP.y || xy.y > maxP.y) {
return vec2(-1.0, -1.0); // 외부
}
vec2 rectSize = maxP - minP;
if (rectSize.x == 0.0 || rectSize.y == 0.0) {
return vec2(-1.0, -1.0); // 축퇴
}
vec2 rectMin = minP;
vec2 rectUV = (xy - rectMin) / rectSize;
float u0 = rectUV.x;
float v0 = rectUV.y;
// 1회 Newton-Raphson (Flutter 원본과 동일)
vec2 left = mix(p0, p1, u0);
vec2 right = mix(p3, p2, u0);
vec2 xy0 = mix(left, right, v0);
vec2 dxy = xy - xy0;
vec2 du_vec = mix(p1 - p0, p2 - p3, v0);
vec2 dv_vec = mix(p3 - p0, p2 - p1, u0);
float det = du_vec.x * dv_vec.y - du_vec.y * dv_vec.x;
if (abs(det) > 1e-6) {
float inv_det = 1.0 / det;
float du = (dv_vec.y * dxy.x - dv_vec.x * dxy.y) * inv_det;
float dv = (-du_vec.y * dxy.x + du_vec.x * dxy.y) * inv_det;
u0 += du;
v0 += dv;
}
return vec2(u0, v0);
}
void main() {
vec2 xy = vUv * u_resolution; // 픽셀 좌표
vec2 texCoord = vUv;
bool found = false;
// Flutter 원본과 동일: 첫 번째 매칭되는 영역만 적용
for (int i = 0; i < 8; i++) {
if (i >= u_numAreas) break;
// 포인트는 정규화된 좌표로 전달받았으므로 픽셀 좌표로 변환
vec2 p0 = u_points[i * 4 + 0] * u_resolution;
vec2 p1 = u_points[i * 4 + 1] * u_resolution;
vec2 p2 = u_points[i * 4 + 2] * u_resolution;
vec2 p3 = u_points[i * 4 + 3] * u_resolution;
vec2 uv_local = computeUV(xy, p0, p1, p2, p3);
if (uv_local.x >= 0.0 && uv_local.x <= 1.0 && uv_local.y >= 0.0 && uv_local.y <= 1.0) {
vec2 uvCenter = vec2(0.5, 0.5);
float distToCenter = distance(uv_local, uvCenter);
float maxUvRadius = 0.5; // Flutter 원본과 동일
if (distToCenter < maxUvRadius) {
float influence = 1.0 - smoothstep(0.0, maxUvRadius, distToCenter);
// dragVector는 정규화된 좌표(0-1)이므로 바로 사용 (Flutter와 동일한 결과)
vec2 distortion = u_dragVectors[i] * influence * u_distortionStrengths[i];
texCoord += distortion;
texCoord = clamp(texCoord, 0.0, 1.0);
}
found = true;
break; // Flutter 원본처럼 첫 번째 영역만 적용
}
}
gl_FragColor = texture2D(u_texture, texCoord);
}