레이캐스팅(raycasting)은 2차원 맵을 3차원으로 원근감있게 만드는 렌더링 기술입니다.
(실제로 raycasting을 이용해 2d map을 3d로 변환한 모습)
dda알고리즘은 2차원 그리드를 지나가는 선이 어떤 네모칸과 부딪히는지 찾을 때 일반적으로 사용되는 속도가 빠른 알고리즘입니다.
dda알고리즘을 사용하면 광선이 맵에서 어떤 네모칸이랑 부딪히는지 찾아낼 수 있고, 벽에 부딪힌 것이 확인되면 dda알고리즘이 중단됩니다.
플레이어의 위치 벡터(x좌표, y좌표)
플레이어의 방향 벡터(x좌표, y좌표)
카메라 평면 벡터(x좌표, y좌표)
방향 벡터 끝점 = 위치 벡터 + 방향 벡터
오른쪽 카메라평면의 끝점 = 방향 벡터 끝점 + 카메라 평면 벡터
왼쪽 카메라 평면의 끝점 = 방향 벡터 끝점 - 카메라 평면 벡터
광선의 방향 벡터
FOV(Field of View)
플레이어가 방향을 돌리면 방향 벡터와 카메라 평면 벡터가 모두 회전해야 합니다.
벡터를 회전시키려면 회전행렬과 곱해주면 됩니다
side dist Y : 시작점 ~ 첫번째 Y면을 만나는 점 까지 광선의 이동 거리
delta dist Y : 첫번째 Y면을 만나고 바로 다음 Y면 까지 광선의 이동 거리
side dist X : 시작점 ~ 첫번째 X면을 만나는 점 까지 광선의 이동 거리
delta dist X : 첫번째 X면을 만나고 바로 다음 X면 까지 광선의 이동 거리
delta dist 구하는 방법 : abs(1 / ray dir y or x)
이렇게 구할 수 있는 이유는 delta dist들의 비율이 필요하기 때문이다
delta dist공식 유도
플레이어 위치에서 광선을 쏜걸로 계산하게 되면 모든 벽이 둥글게 보이는 왜곡이 일어납니다.
이러한 현상을 방지하게위해 카메라 평면에서 광선을 쏜것처럼 보정해주면 왜곡이 방지되는 효과가 있습니다.
카메라평면에서 쏜것처럼 보정하는 방법(x방향으로 부딪힌 경우) : perpWallDist = (mapX - posX + (1 - stepX) / 2) / rayDirX;
이동한거리 : mapX - posX + (1 - stepX) / 2
광선의 방향 : rayDirX;
광선이 양쪽 사이드로 갈수록 ray dir이 커지는 것을 이용하여서 간단하게 보정하는 방법입니다.