Reflection vector in 3D / (반사 벡터)

 

Client Game Play Engineer로써 게임을 만들다보면 간단한 Physics Engine을 구현해야 하는 상황은 자주 발생한다.
반사 각도 혹은 반사 벡터 를 구하는 것도 그 중 하나인데, 2D 게임에서 반사 각도를 구하는 것은 어렵지 않다.
Vector Math를 사용하지 않고도 구할 수 있다.

아래 그림에서 보면, 입사각과 반사각은 동일하므로, -4/3 의 기울기로 입사한 물체는 다시 4/3의 기울기로 반사한다.

 

 


abc

 

It’s so simple in 2D.
그럼, 한 차원만 확장해서 3D 면에서는 어떨까?
이게 실제 게임에선 가장 많이 맞닥뜨리는 경우일 것이다.
그림으로 표현하자면 아래와 같은 경우다.
3차원에서 입사 방향의 V가 반사 했을 경우 R의 형태로 반사될 것인데, R의 정확한 방향이 어떻게 그려질 것인가?

 

 

aaa

 

 

단순 기울기로 간단히 계산하려고 해보지만, 회전이 들어가 있고, 위치가 원점도 아닌 경우 계산이 복잡해진다.
여기서 Vector Math가 쓰인다.

 

 

V, R, N을 Vector 로 정의한다.

V : 입사 방향의 (x,y,z) 성분을 가진 벡터

R : 새로운 반사 방향의 (x,y,z) 성분을 가진 벡터

N : 해당 면의 Normal Vector (Normalized 된 것)

의외로 Client Developer라고 하면서 Cross Product Dot Product 대해서,
모르는 개발자를 상당히 많이 만났는데 기본적인 Vector Math를 꼭 숙지해 두기를 추천한다.
(내적, 외적 Link)

울프람에 잘 설명되어 있으니 참고:
http://mathworld.wolfram.com/DotProduct.html
http://mathworld.wolfram.com/CrossProduct.html

식이야 참고하면 되고, 기하학적인 의미만을 요약하면 아래와 같다.

Dot product 는 projection of vector onto another vector,
Cross product 는 perpendicular vector to both A and B.

Cross Product의 경우 OpenGL은 오른손 법칙을 따르지만, Unity에서는 왼손을 사용한 엄지 방향의 벡터임을 주의해야 하고,
추가로 Dot product가 스칼라이면서도 기하학적으로 정사영의 Size라는 의미를 가진다는 것을 잊지 말아야 한다.
결론적으로 반사 벡터는 아래 그림으로 표현 가능하다.

 

 

ans

 

 

위 그림의  N1 + N2 벡터는 Normal Vector를 minus(-) 방향으로 바꾼 방향의 벡터이다.
또한 크기는 V 벡터를 -N 벡터 방향으로 정사영을 내린 크기, 즉 내적 시킨 사이즈를 두배한 크기이다.

이걸 식으로 표현하면 아래와 같다.

여기서 dot은 Dot Product(내적)을 의미한다.
그리고 그림에서 V2 벡터는 V 벡터를 거꾸로 돌린 -V 벡터이다.
따라서, 그림에 보는 R1 벡터는 두벡터의 합으로 아래와 같은 식으로 표시될 수 있다.

결국, R은 R1의 reverse direction vector이므로,

 

간단한 설명을 위해서 2D 좌표계에서 설명했지만, 3D 에서도 동일하게 사용 가능한 Vector 식이다.


Unity에서는 위의 모든 계산을 하나의 메쏘드로 호출로 해결하게 한다. (털석…)
구체적인 동작을 몰라도, Input Vector와 Normal Vector를 파라미터로 받는 아래의 Vector3의 static method를 사용하면 된다.