일단 TOP 에서 본다고 칩시다. 위에서 보는 겁니다 Plane을 보는 카메라를 위에서 바라본다고 생각해 보죠
그러니까. 이렇게 보고 있는 거예요
저기에 우리가 그리고 싶은건 입체입니다. 일종의 '박스' 를 그리는 거지요.
그래서 결국 우리가 원하는 것은, 아래처럼 P 점의 위치가 R 점으로 이동하길 원합니다. 이런식으로 우리가 보는 점이 계속 방의 안쪽 점으로 이동시켜지면 결국 방이 그려지는 것이니까요
자 그럼 본격적으로 들어가 봅니다.
일단. P의 위치를 잡아보지요
대충 이렇게 볼 수 있습니다.
D 는 카메라 벡터의 단위벡터입니다. normalize(viewDir) 쯤 되겠죠
P의 수치는 지금 중요하지 않습니다. 대충 저기입니다.
그럼 여기서 P 점을 R 점으로 이동시키기 위한 원리는 다음과 같을 겁니다.
P 점에서 D벡터의 방향으로 K 만큼의 거리를 이동시키면 R이 나오게 되는거죠
이걸 공식으로 표현해 보면 아래와 같겠죠.
즉 우린 k.x 스칼라만 구하면 해결됩니다. P 점이야 알고 있는거고 D 벡터는 뷰벡터니까요
자 그래서 일단 중심을 긋습니다. 그리고 중간의 안쪽을 0으로 만들어 줍니다.
아래처럼요.
이렇게 중심을 0으로 두면 공식에서 한 번 더 생각할게 있습니다
아래처럼 A.x 와 B.x 의 스칼라가 생길 수 있겠죠. B.x는 1인걸 알 수 있습니다.
그래서 아래 공식이 도출됩니다. B.x(1이죠) 는 P.x + A.x
이상하게 느낄 수도 있겠지만 지금 P.x 는 음수라고 생각하시면 편합니다. 벡터의 연산은 다 그렇고 그런거죠
자 그럼 이걸 봤을때, 우리는 A.x 를 구할 수 있습니다. 어떻게요? 필요없는 것만 날려보죠
짜잔.
평범한 dot 공식의 모습이 보이네요
그래서 이걸 다시 여기서 다시 정리하면.
B.x 는 D 단위벡터에 K.x 스칼라를 구한 것을 X 좌표에 투영한 것이니까요.
B.x 는 D.x 값에 K.x 스칼라를 곱한것과도 같게 됩니다. K.x는 비율일 뿐이니까요
그럼 최종정리 들어갑니다.
B.x 는 P.x + D.x K.x 니까
이렇게 공식이 나오게 되고, B.x 는 1이니까
이렇게 됩니다
이걸 3차원으로 처리하면 방 하나를 입체로 만들 수 있는 것입니다.
즉 아래 코드에서
| // raytrace box from tangent view dir float3 pos = float3(roomUV * 2.0 - 1.0, 1.0); float3 id = 1.0 / i.viewDir; float3 k = abs(id) - pos * id; float kMin = min(min(k.x, k.y), k.z); pos += kMin * i.viewDir; | cs |
pos 에서 중점을 0,0,1으로 만들고
id 는 1/viewDir 이므로 사실상 저 공식의 1/D.x , 1/D.y, 1/D.z 가 추출된 것이고요
flaot3 k 는 id (음수 방향 벡터일때에도 대응용 abs) 이므로 1/D - Pos/ D 입니다
거기서 그 3가지 데이터중 가장 작은 수를 찾아내야 화면에서 보이는 가장 가까운 벽일테니까 min을 써서 검출해 냈고요.
이걸 뷰 디렉션 (길이가 1인) 만큼 포지션을 이동시켜주는데 그 정도를 kMin으로 조절해 줘서 방을 만들어 냅니다
댓글