normalize()가 하는 일 (그리고 Three.js 레이캐스팅이 그것을 필요로 하는 이유)
Source: Dev.to
normalize()가 하는 일
normalize()는 벡터의 길이를 정확히 1 단위로 만들면서 방향은 그대로 유지합니다.
const rayDirection = new THREE.Vector3(10, 0, 0); // length = 10
rayDirection.normalize(); // → (1, 0, 0)
수학적으로 정규화는 벡터를 그 길이로 나누는 것입니다:
[ \text{normalized} = \frac{v}{|v|} ]
const v = new THREE.Vector3(10, 0, 0);
console.log(v.length()); // 10
v.normalize();
console.log(v.length()); // 1
방향은 동일하게 유지되고, 크기만 변합니다.
Three.js 레이캐스팅이 정규화된 방향을 필요로 하는 이유
거리 계산은 단위 길이를 전제로 함
레이가 어떤 물체에 닿을 때, Three.js는 교차점이 레이 상에서 얼마나 떨어져 있는지를 계산합니다. 이 거리 값들은 방향 벡터의 길이가 1일 때만 의미가 있습니다. 만약 방향이 길이 10이라면 내부 수식이 모든 값을 잘못 스케일링하게 되고, 거리값은 실제 세계 단위와 맞지 않게 됩니다.
교차 공식은 단위 벡터를 전제로 함
많은 레이‑기하학 교차 공식(및 Three.js 문서)에서는 방향 벡터가 단위 벡터일 것을 요구합니다. 정규화를 생략하면 정의되지 않은 동작이 발생할 수 있으며, 가끔은 동작하는 것처럼 보여도 신뢰할 수 없습니다.
normalize()를 올바르게 사용하는 방법
일반적인 레이‑캐스팅 설정
const rayOrigin = new THREE.Vector3(-3, 0, 0);
const rayDirection = new THREE.Vector3(10, 0, 0);
rayDirection.normalize(); // 단위 길이 보장
const raycaster = new THREE.Raycaster(rayOrigin, rayDirection);
- Origin(시작점):
x = -3위치에서 시작 - Direction(방향): X 축을 따라 바로 오른쪽을 가리키며, 이제 정규화됨
다음 호출을 하면:
raycaster.intersectObjects(scene.children);
정확하고 일관된 교차 거리 값을 반환합니다.
원본 벡터를 보존하고 싶을 때
const original = new THREE.Vector3(10, 0, 0);
const direction = original.clone().normalize(); // original은 변경되지 않음
레이의 범위 제어
범위를 제한하기 위해 방향 벡터를 스케일링하지 마세요. 대신 레이캐스터의 near와 far 속성을 설정합니다:
raycaster.near = 0;
raycaster.far = 100; // 100 세계 단위까지 제한
방향은 정규화된 상태를 유지하고, 거리 제한은 레이캐스터가 담당하게 합니다.
시각적 비유
방향 벡터를 나침반 바늘에 비유해 보세요.
- 정규화 전: 길이 10미터인 화살표.
- 정규화 후: 같은 방향을 가리키는 길이 1미터인 화살표.
Three.js 레이캐스팅은 1미터 버전을 기대하므로 모든 거리 계산이 깔끔하고 예측 가능하게 유지됩니다.