responsive-image-canvas/dist/distortion.frag.glsl
BaekRyang e531a7a762 feat: Apply cumulative distortion from all overlapping areas
- 모든 겹치는 영역의 왜곡을 누적하여 적용하도록 변경
- 각 영역별 clamp를 제거하고, 모든 왜곡 계산 후 최종적으로 한 번만 clamp
- 불필요한 `found` 변수 및 `break` 문 제거
2025-11-05 12:48:36 +09:00

85 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;
// 모든 겹치는 영역의 왜곡을 누적 적용
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;
if (distToCenter < maxUvRadius) {
float influence = 1.0 - smoothstep(0.0, maxUvRadius, distToCenter);
// dragVector는 정규화된 좌표(0-1)이므로 바로 사용
vec2 distortion = u_dragVectors[i] * influence * u_distortionStrengths[i];
texCoord += distortion;
// clamp를 루프 내에서 제거: 모든 왜곡을 완전히 누적한 후 마지막에 한 번만 clamp
}
}
}
// 모든 왜곡을 누적한 후 최종적으로 한 번만 clamp
texCoord = clamp(texCoord, 0.0, 1.0);
gl_FragColor = texture2D(u_texture, texCoord);
}