이전 글에서는 벡터의 길이(Length)와 정규화(Normalize)가 왜 중요한지를 정리해보았습니다.
특히 방향은 유지하면서 벡터 길이를 항상 1로 유지해야 하는 이유와,
게임 안에서 이동 속도를 일정하게 유지하기 위해 정규화가 어떻게 사용되는지도 함께 살펴보았습니다.
이번에는 게임 수학에서 굉장히 자주 등장하는 내적(Dot Product) 개념을 정리해보려고 합니다.
내적은 단순 수학 공식처럼 보일 수 있지만,
실제로는 게임 안에서 두 방향이 얼마나 비슷한지를 계산하기 위해 굉장히 자주 사용됩니다.
그리고 이 개념은 시야 판정과 조명 계산,
카메라 처리 같은 다양한 시스템들과도 직접 연결됩니다.
내적(Dot Product)은 두 방향의 관계를 계산한다
게임 안에서는 특정 객체가 다른 객체를 바라보고 있는지를 계산해야 하는 상황이 굉장히 많습니다.
예를 들어 적 AI가 플레이어를 바라보고 있는지 확인하거나,
플레이어가 특정 방향을 향해 공격하고 있는지를 판단하는 상황을 생각해볼 수 있습니다.
이런 상황에서는 단순 위치 정보만으로는 충분하지 않습니다.
“현재 바라보는 방향”과 “목표 방향”이 얼마나 비슷한지를 계산해야 하기 때문입니다.
그리고 바로 이 때 내적(Dot Product)이 사용됩니다.
내적은 두 벡터를 비교해서 방향이 얼마나 비슷한지를 계산하는 연산입니다.
예를 들어 아래처럼 두 벡터가 있다고 가정해보겠습니다.
Vector2 a = { 1.0f, 0.0f };
Vector2 b = { 1.0f, 0.0f };
이 경우 두 벡터는 완전히 같은 방향을 바라보고 있습니다.
반대로 아래처럼 방향이 서로 반대인 경우도 생각해볼 수 있습니다.
Vector2 a = { 1.0f, 0.0f };
Vector2 b = { -1.0f, 0.0f };
이 경우 두 벡터는 서로 정반대 방향을 바라보게 됩니다.
내적은 두 벡터가 얼마나 같은 방향을 바라보고 있는지를 숫자로 표현하기 위한 계산이라고 볼 수 있습니다.
내적은 각 요소를 곱해서 계산한다
2D 벡터 기준으로 내적은 아래처럼 계산할 수 있습니다.
(a.x * b.x) + (a.y * b.y)
예를 들어 아래 두 벡터의 내적을 계산해보겠습니다.
Vector2 a = { 1.0f, 0.0f };
Vector2 b = { 0.0f, 1.0f };
이 경우 계산 결과는 아래와 같이 0이 됩니다.
(1 * 0) + (0 * 1) = 0
내적 결과가 0이라는 것은 두 벡터가 서로 수직이라는 의미입니다.
그런데 내적은 단순히 각 요소를 곱하는 계산으로만 이해하면 부족합니다.
왜 방향이 같으면 1에 가까워지고, 수직이면 0, 반대 방향이면 -1에 가까워지는지 자연스럽게 이해하기 어렵습니다.
그리고 바로 이 부분을 설명해주는 것이 코사인(cos)을 사용하는 내적 공식입니다.
내적을 구하는 공식에는 2가지가 있습니다.
내적은 아래처럼 두 벡터 사이의 각도를 이용해서도 표현할 수 있습니다.
Dot(a, b) = |a| * |b| * cos(theta)
여기에서 |a| 는 벡터 a의 길이, |b| 는 벡터 b의 길이, theta 는 두 벡터 사이의 각도를 의미합니다.
특히 방향 비교를 할 때는 대부분 정규화된 벡터를 사용합니다.
정규화된 벡터는 길이가 항상 1이기 때문에 공식이 아래처럼 단순해집니다.
Dot(a, b) = cos(theta)

그리고 바로 이 공식 덕분에 내적 결과를 방향 관계로 해석할 수 있게 됩니다.
예를 들어 두 벡터 방향이 완전히 같다면 각도는 0도가 됩니다.
cos(0)는 1이기 때문에 내적 값 역시 1에 가까워집니다.
반대로 두 벡터가 서로 수직이라면 각도는 90도가 됩니다.
그리고 cos(90)는 0이기 때문에 내적 결과 역시 0이 됩니다.
또한 두 벡터가 완전히 반대 방향이라면 각도는 180도가 됩니다.
이 경우 cos(180)은 -1이기 때문에 내적 값 역시 -1이됩니다.

즉, 내적은 단순 숫자 계산이 아니라, 두 벡터가 얼마나 비슷한 방향을 바라보고 있는지를 계산하는 연산입니다.
그리고 이런 특징 때문에 게임 개발에서는 시야 판정과 조명 계산,
카메라 처리 같은 다양한 시스템에서 내적이 활용됩니다.
적 AI의 시야 판정에도 내적이 사용된다
게임 AI에서는 적이 바라보는 방향 벡터(forward)와 플레이어 방향 벡터(directionToPlayer)의 내적(Dot Product)을 계산해 플레이어가 시야 안에 존재하는지를 판단할 수 있습니다.
게임 AI에서는 플레이어가 적의 시야 안에 들어왔는지를 계산해야 하는 경우가 많습니다.
예를 들어 적 캐릭터가 정면 방향만 볼 수 있다고 가정해보겠습니다.
이 경우 적이 바라보는 방향 벡터와,
적에서 플레이어 방향으로 향하는 벡터를 비교하면 플레이어가 시야 안에 존재하는지 계산할 수 있습니다.
예를 들어 아래처럼 사용할 수 있습니다.
// 시야 1/2각도의 코사인 값 (60도일 때의 코사인)
float halfSightThreshold = 0.5f; // cos(60도) = 0.5
// 시야 벡터(forward)와 플레이어를 향하는 벡터 사이의 내적
float dot = Dot(forward, directionToPlayer);
// 플레이어가 시야에 들어왔는지 여부를 판단 (각도 판정)
if (dot >= halfSightThreshold)
{
// 시야에 들어왔을 떄
}
else
{
// 시야에 들어오지 않았을 때
}
즉, 내적 값을 이용하면 플레이어가 적 시야 범위 안에 존재하는지를 계산할 수 있습니다.
즉, 내적은 게임 안에서 “현재 어느 방향을 바라보고 있는가”를 계산하기 위한 핵심 도구 중 하나라고 볼 수 있습니다.
조명 계산에서도 내적이 사용된다
내적은 렌더링과 조명 계산에서도 굉장히 중요하게 사용됩니다.
특히 빛 방향과 표면 방향이 얼마나 비슷한지를 계산할 때 내적이 사용됩니다.

예를 들어 빛이 표면 정면 방향으로 들어오면 밝게 보이고, 옆 방향으로 들어오면 어둡게 보입니다.
이런 밝기 계산 역시 내적 기반으로 처리합니다.
따라서 내적은 단순 벡터 계산 수준이 아니라, 최종 화면 색상 계산에도 직접 영향을 주는 중요한 연산이라고 볼 수 있습니다.
내적은 게임 엔진 전체에서 계속 사용된다
내적은 시야 판정과 조명 계산뿐 아니라,
카메라 처리와 물리 계산,
애니메이션 시스템 등 다양한 상황에서 활용됩니다.
특히 두 방향이 얼마나 비슷한지를 계산해야 하는 상황에서는 항상 사용된다고 볼 수 있습니다.
그리고 이후에 배우게 될 반사 벡터 계산과 조명 모델, 카메라 회전 같은 다양한 계산에도 내적이 활용됩니다.
내적은 게임 수학 안에서도 가장 자주 사용되는 핵심 벡터 연산 중 하나입니다.
마무리
내적(Dot Product)은 두 벡터가 얼마나 같은 방향을 바라보고 있는지를 계산하기 위한 연산입니다.
그리고 게임 개발에서는 방향 비교가 굉장히 자주 필요하기 때문에, 내적 역시 다양한 시스템 안에서 계속 사용됩니다.
특히 시야 판정과 조명 계산, 카메라 처리 같은 구조들은 대부분 내적 기반 계산 위에서 동작합니다.
따라서 내적은 단순 수학 공식이 아니라, 게임 엔진 안에서 방향 관계를 계산하기 위한 핵심 기초 개념 중 하나라고 볼 수 있습니다.
다음 글에서는 외적(Cross Product)이 왜 중요한지,
그리고 3D 공간에서 회전 방향과 법선 벡터 계산에 어떻게 활용되는지를 이어서 정리해보겠습니다.