fix: Fix coordinate system to match Flutter implementation
- Fix y-coordinate inversion between UI (top-left origin) and WebGL (bottom-left origin) - Convert UI coordinates to WebGL coordinates when passing to shader - Invert drag vector y-direction to match coordinate system - Add getResolution() method to ThreeScene for coordinate conversion - Update shader to use normalized drag vectors directly This resolves the issue where distortion appeared at opposite y-position from clicked point.
This commit is contained in:
parent
e371321fd2
commit
ef992b5525
@ -143,22 +143,27 @@ export const ImageDistortion: React.FC<ImageDistortionProps> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!sceneRef.current || !isReady) return;
|
if (!sceneRef.current || !isReady) return;
|
||||||
|
|
||||||
|
// 현재 해상도 가져오기
|
||||||
|
const resolution = sceneRef.current.getResolution();
|
||||||
|
|
||||||
// 포인트 배열 생성
|
// 포인트 배열 생성
|
||||||
|
// UI는 좌상단 (0,0), WebGL은 좌하단 (0,0)이므로 y 좌표를 반전
|
||||||
const points = new Float32Array(SHADER_CONFIG.MAX_POINTS * 2);
|
const points = new Float32Array(SHADER_CONFIG.MAX_POINTS * 2);
|
||||||
currentAreas.forEach((area, areaIndex) => {
|
currentAreas.forEach((area, areaIndex) => {
|
||||||
area.basePoints.forEach((point, pointIndex) => {
|
area.basePoints.forEach((point, pointIndex) => {
|
||||||
const index = (areaIndex * 4 + pointIndex) * 2;
|
const index = (areaIndex * 4 + pointIndex) * 2;
|
||||||
points[index] = point.x;
|
points[index] = point.x;
|
||||||
points[index + 1] = point.y;
|
points[index + 1] = 1.0 - point.y; // y 좌표 반전
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 드래그 벡터 배열 생성
|
// 드래그 벡터 배열 생성
|
||||||
|
// dragVector도 y 좌표계를 맞춰야 하므로 y를 반전
|
||||||
const dragVectors = new Float32Array(SHADER_CONFIG.MAX_DRAG_VECTORS * 2);
|
const dragVectors = new Float32Array(SHADER_CONFIG.MAX_DRAG_VECTORS * 2);
|
||||||
currentAreas.forEach((area, index) => {
|
currentAreas.forEach((area, index) => {
|
||||||
const baseIndex = index * 2;
|
const baseIndex = index * 2;
|
||||||
dragVectors[baseIndex] = area.dragVector.x;
|
dragVectors[baseIndex] = area.dragVector.x;
|
||||||
dragVectors[baseIndex + 1] = area.dragVector.y;
|
dragVectors[baseIndex + 1] = -area.dragVector.y; // y 방향 반전
|
||||||
});
|
});
|
||||||
|
|
||||||
// 강도 배열 생성
|
// 강도 배열 생성
|
||||||
|
|||||||
@ -115,6 +115,16 @@ export class ThreeScene {
|
|||||||
this.renderer.render(this.scene, this.camera);
|
this.renderer.render(this.scene, this.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 현재 해상도 가져오기
|
||||||
|
*/
|
||||||
|
public getResolution(): { x: number; y: number } {
|
||||||
|
return {
|
||||||
|
x: this.uniforms.u_resolution.value.x,
|
||||||
|
y: this.uniforms.u_resolution.value.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 리소스 정리
|
* 리소스 정리
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
uniform vec2 u_resolution;
|
uniform vec2 u_resolution;
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
uniform vec2 u_points[32]; // 최대 8영역 × 4포인트 (정규화된 좌표)
|
uniform vec2 u_points[32]; // 최대 8영역 × 4포인트 (정규화된 좌표 0-1)
|
||||||
uniform int u_numAreas;
|
uniform int u_numAreas;
|
||||||
uniform vec2 u_dragVectors[8]; // 정규화된 좌표
|
uniform vec2 u_dragVectors[8]; // 드래그 벡터 (정규화된 좌표 0-1)
|
||||||
uniform float u_distortionStrengths[8];
|
uniform float u_distortionStrengths[8];
|
||||||
|
|
||||||
varying vec2 vUv;
|
varying vec2 vUv;
|
||||||
@ -72,10 +72,9 @@ void main() {
|
|||||||
|
|
||||||
if (distToCenter < maxUvRadius) {
|
if (distToCenter < maxUvRadius) {
|
||||||
float influence = 1.0 - smoothstep(0.0, maxUvRadius, distToCenter);
|
float influence = 1.0 - smoothstep(0.0, maxUvRadius, distToCenter);
|
||||||
// dragVector도 정규화된 좌표이므로 픽셀로 변환
|
// dragVector는 정규화된 좌표(0-1)이므로 바로 사용 (Flutter와 동일한 결과)
|
||||||
vec2 distortion = (u_dragVectors[i] * u_resolution) * influence * u_distortionStrengths[i];
|
vec2 distortion = u_dragVectors[i] * influence * u_distortionStrengths[i];
|
||||||
// texCoord는 이미 정규화된 좌표이므로 정규화된 왜곡 적용
|
texCoord += distortion;
|
||||||
texCoord += distortion / u_resolution;
|
|
||||||
texCoord = clamp(texCoord, 0.0, 1.0);
|
texCoord = clamp(texCoord, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
found = true;
|
found = true;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user