- 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
86 lines
2.8 KiB
GLSL
86 lines
2.8 KiB
GLSL
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);
|
||
} |