From c72846b06ebd44418d23c9e16a7fddc39b42a47e Mon Sep 17 00:00:00 2001 From: BaekRyang Date: Wed, 25 Feb 2026 16:52:48 +0900 Subject: [PATCH] Refactor lens distortion calculation in distortion shader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 렌즈 왜곡 계산을 로컬 UV에서 글로벌 UV 및 픽셀 거리 기반으로 변경 - 영역 중심 기준의 자연스러운 볼록/오목 효과 및 감쇠 로직 구현 --- src/shaders/distortion.frag.glsl | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/shaders/distortion.frag.glsl b/src/shaders/distortion.frag.glsl index d50bdd0..8023117 100644 --- a/src/shaders/distortion.frag.glsl +++ b/src/shaders/distortion.frag.glsl @@ -76,13 +76,28 @@ void main() { vec2 distortion = u_dragVectors[i] * influence * u_distortionStrengths[i]; texCoord += distortion; - // 렌즈 왜곡 효과 (방사형 UV 왜곡) + // 렌즈 왜곡 효과 (볼록: 중심 확대, 오목: 중심 축소) if (abs(u_lensEffects[i]) > 0.001) { - vec2 centered = uv_local - vec2(0.5); - float dist2 = dot(centered, centered); - float lensK = u_lensEffects[i] * 2.0; // 강도 스케일링 - vec2 lensDistortion = centered * lensK * dist2; - texCoord += lensDistortion * u_distortionStrengths[i]; + // 영역 중심의 글로벌 UV 좌표 + vec2 minP_area = min(min(p0, p1), min(p2, p3)); + vec2 maxP_area = max(max(p0, p1), max(p2, p3)); + vec2 areaSize = maxP_area - minP_area; + vec2 areaCenterUV = (minP_area + maxP_area) * 0.5 / u_resolution; + + // 현재 픽셀에서 영역 중심까지의 글로벌 UV 오프셋 + vec2 offset = vUv - areaCenterUV; + // 픽셀 공간 거리로 원형 감쇠 (긴 변 기준으로 영역 전체 커버) + float distPx = length(offset * u_resolution); + float maxRadiusPx = max(areaSize.x, areaSize.y) * 0.5; + float normalizedDist = distPx / maxRadiusPx; + + if (normalizedDist < 1.0) { + // 중심에서 최대 강도, 가장자리로 갈수록 자연스럽게 0으로 감소 + float lensAmount = u_lensEffects[i] * (1.0 - normalizedDist * normalizedDist); + // 볼록(+): 텍스처 좌표를 중심으로 당김 → 확대 + // offset은 글로벌 UV이므로 픽셀 공간에서 등방성(isotropic) 확대 + texCoord -= offset * lensAmount * u_distortionStrengths[i]; + } } } }