게임에서 반사는 어떻게 구현할까?
반사는 정반사와 난반사가 있다.
정반사는 입사된 각의 완전 반대방향으로 반사가 되어 나가는 것이다.
이를 위해서 투영 벡터라는 것을 우선 알아둘 필요가 있다.
투영 벡터란, A 벡터와 B 벡터를 내적할 때, 그 결과값이 B 벡터 상에 나타나는데 이를 투영 벡터라고 한다.
사실 이 글을 작성하는 필자도 문과이고 많은 문과들이 벡터에 대한 개념을 잡기가 어려운 것을 알고 있다.
쉽게 생각하면 이와 같다.
반사를 할 때 정반사의 경우 반사각은 입사각에서 그대로 90도를 더하거나 뺀 값이 된다. 그 90도라는 것은 결국 가상의 벡터가 되어 반사각과 입사각 사이에서 중심이 된다.
이 90도를 가상의 벡터라고 가정하고 이 벡터와 입사각을 내적한 결과가 투영 벡터가 되고, 이 투영 벡터를 이용해서 입사 벡터의 완전한 반사 벡터를 구할 수 있다.
void Bullet::Reflection(ObLine axisX, ObLine axisY)
{
Vector2 projectionX = Vector2(axisX.GetWorldPivot().x, missile.GetWorldPivot().y) - Vector2(axisX.GetWorldPivot());
Vector2 projectionY = Vector2(missile.GetWorldPivot().x, axisY.GetWorldPivot().y) - Vector2(axisY.GetWorldPivot());
Vector2 dir = lastPos - missile.GetWorldPivot();
float seta = Utility::DirToRadian(dir) / ToRadian;
Vector2 inner_product;
Vector2 Reflection;
if (isOutLineX())
{
// 투영 벡터
inner_product = Vector2(dir.x * projectionX.x, dir.y * projectionX.y);
inner_product.Normalize();
// 투영 벡터를 이용해서 반사벡터를 구하는 공식
Reflection = dir + 2 * inner_product * (-dir * inner_product);
missile.rotation = Utility::DirToRadian(Reflection);
}
else if (isOutLineY())
{
inner_product = Vector2(dir.x * projectionY.x, dir.y * projectionY.y);
inner_product.Normalize();
Reflection = dir + 2 * inner_product * (-dir * inner_product);
missile.rotation = Utility::DirToRadian(Reflection);
}
this->lastPos = missile.GetWorldPivot();
}
bool Bullet::isOutCAM()
{
float x, y, lineX, lineY;
x = missile.GetWorldPivot().x;
y = missile.GetWorldPivot().y;
lineX = CAM->position.x;
lineY = CAM->position.y;
if (x >= lineX + app.GetHalfWidth() ||
x <= lineX - app.GetHalfWidth() ||
y >= lineY + app.GetHalfHeight() ||
y <= lineY - app.GetHalfHeight())
return true;
return false;
}
bool Bullet::isOutLineX()
{
float x, lineX;
x = missile.GetWorldPivot().x;
lineX = CAM->position.x;
if (x >= lineX + app.GetHalfWidth() || x <= lineX - app.GetHalfWidth())
return true;
else
return false;
}
bool Bullet::isOutLineY()
{
float y, lineY;
y = missile.GetWorldPivot().y;
lineY = CAM->position.y;
if (y >= lineY + app.GetHalfHeight() || y <= lineY - app.GetHalfHeight())
return true;
else
return false;
}
밖으로 나갔는지 확인하는 함수와 반사각을 구해 발사된 미사일을 반사시키는 함수이다.
'프로그래밍 > 공부' 카테고리의 다른 글
[DirectX] 셰이더(Shader) (0) | 2023.01.04 |
---|---|
[DirectX] 렌더링 파이프라인 - (1) (0) | 2023.01.04 |
[Game] 객체의 회전 part.2 (0) | 2022.12.22 |
[Game] 객체의 회전 (0) | 2022.12.19 |
[Game] 변환행렬 (2) | 2022.12.15 |
댓글