본문 바로가기

전체 글

(308)
[Unreal] 카메라 회전 관련 변수 Use Controller Rotation Yaw - 캐릭터의 Yaw가 컨트롤러의 Yaw와 같아진다. Use Controller Desired Rotation - 캐릭터가 컨트롤러 방향으로 회전한다. Orient Rotation to Movement가 이것을 오버라이드한다. Orient Rotation to Movement - 카메라가 바라보는 방향과 상관없이 캐릭터는 캐릭터가 움직이는 방향을 향한다. 그렇다면 컨트롤러 방향에 따라 캐릭터의 회전을 제어하려면 어떻게 해야 할까? 확인하기 위해서 실험을 해봤다. Use Controller Rotation Yaw는 false, Orient Rotation to Movement는 true일 때 캐릭터가 컨트롤러 방향 상관없이 회전한다. 즉, 캐릭터의 회전에는 ..
[Unreal] 언리얼에서 auto 사용 C++11에서 auto 키워드는 선언된 변수의 초기화 식으로 변수의 타입을 추론한다. TArray OverlapResults; FCollisionQueryParams QueryParams(NAME_None, false, CurrentPawn); bool bResult = World->OverlapMultiByChannel( OverlapResults, Center, FQuat::Identity, ECollisionChannel::ECC_GameTraceChannel1, FCollisionShape::MakeSphere(SearchRadius), QueryParams); if (bResult) { for (auto& OverlapResult : OverlapResults) { AMyCharacter* My..
[DX12] Frustum Culling Frustum Culling frustum은 한국어로 절도체라고 하는데, 피라미드에서 윗부분이 잘린 도형을 말한다. frustum이 곧 카메라가 비추는 부분인데, 게임에서 Frustum Culling을 이용해서 Frustum 안쪽의 물체만 출력한다. 이것을 이용하면 CPU에서 GPU로 넘기는 단계에서 걸러버리기 때문에 큰 최적화 효과를 볼 수 있다. 평면의 방정식 평면을 나타내는 방정식은 ax+by+cz+d=0 인데 이 방정식의 몇가지 특징이 있다. ① x,y,z의 계수 (a,b,c)는 평면의 법선벡터이다. 평면위 임의의 점 두 개를 잇는 벡터와 (a,b,c)를 내적하면 0이 나온다. ② -d는 원점에서 평면까지 거리이다. 벡터의 내적은 각 x,y,z좌표를 곱해서 더한것과 같기 때문에 ax+by+cz 는..
[DX12] Normal Mapping Normal Mapping Normal Mapping은 물체에 어떤 Texture을 입힘으로써 물체를 더 세부적으로 표현하는 것인데, 그냥 Texture처럼 이미지를 입히는 것이 아니라 빛과도 상호작용해서 입체감을 더욱 늘린다. 즉 RGB 색상 정보만 가지고 있는 것이 아니라 Normal 벡터까지 가지고 있다. 그렇기 때문에 따로 물체에 정점을 추가할 필요 없이 텍스쳐만으로 더 생동감 있게 표현할 수 있다. Tangent Space Tangent Space는 Normal Mapping할 때 사용하는 좌표계이다. Normal Mapping할 때 사용하는 Texture가 파랑색인 이유도 Normal 벡터가 이 좌표계에서 위쪽으로 향하는 경우가 대부분이기 때문이다. Tangent Space는 Pixel마다 하..
[DX12] Projection, Screen 변환 행렬 Projection 변환 행렬 Projection은 3차원 공간에 있는 물체들을 2차원 화면에 투영하는 것이다. 투영하는 것은 카메라로부터 멀리 떨어져 있을 수록 작게 표시되기 때문에 떨어져 있는 만큼 좌표를 나누면 화면에 출력하는 좌표가 된다. 먼저 2차원으로 변환하고 해상도에 맞게 크기를 조절하면 크기가 달라질 수 있으므로 변환할 때 x에만 (그림의 y도 r로 나누는건 잘못된 것) 화면비율 width/height으로 나눈다. 해상도에 따라 크기가 늘어나는 것을 대비해 미리 줄여주는 것이다. 또한 카메라의 시야각(FOV)에 따라 출력되는 것이 달라지므로 시야각이 달라지는 것을 대비해야 한다. 최대 tan(θ/2) 크기를 가질 수 있는 것을 크기 1까지 줄여야하므로 tan(θ/2)로 나누어준다. 행렬로 ..
[DX12] World, View 변환 행렬 게임에서 플레이어의 화면은 카메라 기준이기 때문에 게임 세상의 World 좌표계에서 카메라 좌표계로 모든 물체들을 변환해야 한다. 그리고 화면에 출력될 물체는 카메라가 촬영하는 공간 안에 들어와있어야 하며 이것을 투영이라고 한다. 카메라가 촬영하는 공간을 Clip Space라고 한다. 마지막으로 화면 해상도에 맞게 화면을 조정해주면 모든 과정이 완료된다. 과정을 정리하자면, Local 행렬 - 물체만의 세상에서 상대적인 물체의 위치를 정한다. World 행렬 - 게임 세상에서 각 물체의 위치를 정한다. (물체마다 world 행렬 한개씩) View 행렬 - 카메라 위치 기준 좌표계 Projection - 카메라가 잡고 있는 범위 내 물체들을 투영 Screen - 해상도에 맞게 비율을 조절 Local → W..
[DX12] 좌표계 변환 행렬 카메라 기준으로 좌표가 바뀌기 때문에 좌표계의 변환은 수시로 일어난다. 그래서 새로운 좌표계를 기준으로 행렬을 변환하는 것은 중요하다. 예시로 아래 그림의 좌표 M을 A좌표계에서 B좌표계로 변환해서 표현해보겠다. 1.벡터 AM을 AB+BM으로 나눈다. 2.AB를 넘기고 BM을 그림처럼 (...)u2 + (...)v2 형식으로 표현한다. 식을 행렬로 표현하면 (x,y,z,1)와 Ux Uy Uz 0 를 곱한 것이 된다. Vx Vy Vz 0 Wx Wy Wz 0 Qx Qy Qz 1 X = xUx + yUy + zUz , Y = xVx + yVy + zVz , Z = xWx + yWy + zWz 는 A좌표를 B좌표계 기준으로 표현한 것이다. 만약 위치벡터가 아닌 기하벡터(방향벡터)라면 시작점이 존재하지 않기 때문..
[C++] weak_ptr shared_ptr은 위와 같이 서로의 객체를 참조하고 있을 때 문제가 발생한다. 객체가 사라지려면 shared_ptr의 레퍼런스 카운트가 0이 되어야하는데 그러기 위해서는 상대방 객체가 파괴되어야 한다. 하지만 순환 참조를 이루고 있기 때문에 두 shared_ptr들은 해제되지 않는다. 이 문제를 해결하기 위해 weak_ptr을 사용한다.   std::string s; std::weak_ptr other; weak_ptr을 사용하는 예시로 먼저 weak_ptr을 선언한다.   void set_other(std::weak_ptr o) { other = o; } std::vector> vec; vec.push_back(std::make_shared("자원 1")); vec.push_back(std::m..