전체 글 102

[게임 서버][4장]게임 서버와 클라이언트

개요 멀티플레이 게임을 구현하는데는 여러가지 방법이 있지만 보통 서버와 클라이언트로 나누어 개발하는 것이 대부분이다. 보통 서버는 클라이언트로부터 요청을 받아 응답해주며 클라이언트는 유저의 조작을 서버로 보내고 서버로부터 받은 데이터로 게임을 진행한다. ​ 서버와 클라이언트 역할분담 멀티플레이가 없는 싱글 플레이게임은 다음과 같은 게임 루프로 작동한다. 입력 받기 게임 로직 처리 렌더링 멀티 플레이가 있는 게임에서는 게임 로직 처리중 일부를 서버가 대신 처리해주게 된다. 여기서 데미지 판정같이 공정해야하는 부분은 서버에서 처리하며 최적 경로 탐색 등 클라이언트에서 계산해도 문제가 생기지않는 로직들은 클라이언트에서 처리하게 된다. 서버에서 많은 로직을 처리하고 클라이언트에서는 정보를 받아 렌더링만 하는 정..

[게임 서버][3장]소켓 프로그래밍

개요 어플리케이션 프로그래밍에서 네트워크 통신은 특정 포트와 바인딩된 소켓이라는 자원을 이용하여 구현한다. 이러한 소켓을 이용한 프로그래밍을 소켓 프로그래밍이라고 한다. ​ 소켓 소켓은 다음과 같은 연산이 가능하다. TCP, UDP 소캣으로서 생성 특정 포트에 바인딩 (TCP) TCP 연결 받기 (TCP) TCP 연결 요청 데이터 송신 : 송신 버퍼에 공간이 없거나(TCP), 부족하면 (UDP) 불가능 데이터 수신 : 수신 버퍼에 데이터가 없으면 불가능 소켓 닫기 이때 데이터 송수신은 각각 해당 소켓의 송신 버퍼, 수신 버퍼에 데이터를 채우거나 가져오는 처리를 한다. 또한 데이터를 송신했는데 상대 수신 버퍼가 가득 찼으면 다음과 같이 처리된다. TCP : 재전송 (또한 매번 상대 수신 버퍼의 여유 공간에..

[게임 서버][2장]컴퓨터 네트워크

개요 이번 장에서는 게임 서버 프로그래밍에 필요한 네트워크 지식을 다룬다. ​ 네트워크 구성 네트워크는 실제 통신을 하는 기기인 단말기와 그 연결을 위해 존재하는 네트워크 기기로 구성된다. 단말기는 컴퓨터, 핸드폰 등이 있으며 네트워크 기기는 스위치, 라우터등이 존재한다. ​ 단말기들은 스위치같은 네트워크 기기들을 통해 LAN이라는 작은 규모의 지역 네트워크를 구성하며 이러한 LAN들이 라우터들로 연결되어 WAN이라는 광역 네트워크를 구성하게 된다. 이때 지구 전체를 덮은 WAN이 바로 인터넷이다. ​ OSI 모델 인터넷은 다음과 같은 프로토콜 계층으로 구성된다. 물리 계층 : 전류, 광 등의 물리 통신 담당 데이터 링크 계층 : LAN안에서의 통신을 담당, MAC주소를 이용하여 트래킹 네트워크 계층: ..

[게임 서버][1장]멀티 스레딩

개요 멀티 스레딩은 한 프로세스에서 여러 스레드를 활용하는 것을 의미한다. 서버 프로그래밍에서는 한 서버가 여러 클라이언트를 상대하야하므로 멀티 스레딩이 필수적이다. ​ ​ 프로세스와 스레드 한 프로세스는 여러 스레드를 가진다. 이때 프로세스의 힙은 각 스레드에 공유되며 각 스레드는 각자의 호출 스택을 가지게 된다. 보통 스레드는 한 스레드에서 특정 함수 포인터를 매개변수로 넘겨주며 스레드 생성 함수를 호출하여 생성한다. 그러면 해당 함수를 실행하는 스레드가 생성된다. 생성된 스레드들은 실행과 대기를 반복하다 수행이 끝나면 소멸된다. 실행중인 스레드들은 각자 코어를 하나씩 차치하여 실행되며 코어가 더 적다면 문맥 교환을 하며 번갈아 실행된다. 이때 문맥 교환은 가벼운 연산이 아니므로 스레드가 너무 많다면..

[Directx12][23장]캐릭터 애니메이션

개요 지금까지는 메쉬의 큰 변화없이 트랜스폼만을 이용하여 오브젝트들을 움직였다. 이제는 뼈대들의 계층구조를 이용하여 좀 더 다채로운 애니메이션을 만들어보자. ​ 뼈대 계층구조 우리는 부모 자식 관계로 트리 형태의 계층구조를 가지는 뼈대 계층구조를 이용하여 애니메이션을 만들 것이다. 여기에서의 핵심은 부모의 트랜스폼이 변화하면 자식의 트랜스폼도 따라서 변화한다는 점이다. 예를 들어 우리 몸의 관절을 표현한 뼈대 계층구조가 있다고하자. 그 중 오른팔의 부분을 보면 윗팔, 아랫팔, 손이라는 계층구조가 존재한다. 이때 손이 움직이면 손만 움직이지만 아랫팔이 움직이면 그의 하위 계층인 손도 따라움직이게 된다. 윗팔이 움직이면 아랫팔, 손 모두가 움직일 것이다. 이러한 계층구조로 우리는 다양한 뼈대 애니메이션을 구..

[Directx12][22장]사원수

개요 지금까지는 회전을 회전 행렬로 표현했다. 하지만 사원수라는 새로운 대수를 사용하면 실수 네개만으로 회전을 표현할 수 있다. ​ 복소수 복소수는 실수부와 허수부로 구성되며 (a,b) 또는 a+ib로 표현된다. 여기서 i는 -1의 루트로 i2은 -1이 된다. 복소수에는 상등 비교와 사칙연산이 가능한데 a+ib의 상등비교와 사칙연산을 생각하면 된다. (a,b) = (c,d) => a = c && b = d (a,b) ± (c,d) = (a±c,b±d) (a,b)(c,d) = (ac-bd,ad+bc) (a,b)/(c,d) = ( (ac+bd)/(c2+d2) , (bc-ad)(c2+d2) ) ​ 실수 x는 (x,0)의 복소수로 생각할 수 있으며 i는 (0,1)로 생각할 수 있다. 또한 복소수 z = (a,b..

[Directx12][21장]주변광 차폐

개요 현재까지의 렌더링에서는 주변광을 고정된 상수로 사용했었다. 이러한 방식은 그림자에 가려진 부분들에 취약할 수 있다. 특정 광원에 대해 그림자가 든 부분은 해당 광원에 대한 분산광, 반영광 없이 주변광만으로 나타나게 되는데 이때 상수 주변광을 사용하면 입체감이 잘 느껴지지 않을 수 있다. 따라서 화면의 한점이 주변의 다른 기하구조에 얼마나 둘려싸여있는지에 따른 차폐도를 계산하고 이를 이용하여 주변광의 세기를 조절할 필요가 있다. 이러한 기법을 주변광 차폐라고 한다. ​ 도달도 도달도는 1 - 차폐도에 해당하는 수치로 해당 점이 주변 기하구조에 얼마나 둘려싸여있지 않은지, 즉 주변광을 얼마나 많이 받는지를 나타내는 수치이다. 이러한 도달도는 기하구조 생성시점이나 프로그램 초기화 시점에 계산하여 기하구조..

[Directx12][20장]그림자 매핑

개요 그림자 매핑은 광원에서 한 방향으로 본 장면을 깊이만 렌더링하여 만든 그림자 맵을 이용해 그림자를 표현하는 기법이다. 정확히는 광원의 광선에 처음 맞는 부분과 아닌 부분을 구분하여 빛의 세기를 조절해 그림자를 표현한다. 이러한 기법은 기존의 스텐실 그림자와 달리 평면 뿐 아닌 모든 기하구조에 정상적으로 그림자가 나타나게 된다. ​ 직교 투영 우선 직교 투영이라는 개념부터 배워보자. 지금까지 어떠한 시점에서 바라본 장면을 만들때 원근 투영을 이용하여 장면의 정점들을 투영창에 투영했다. 절두체와 시점 - 정점을 잇는 시선을 사용했던 것이 원근 투영이라면 직교 투영은 절두체가 아닌 직사각형으로 z축과 평행한 시선으로 정점들을 투영한다. 직교 투영의 투영선은 그냥 z축과 평행 하기에 시야 공간에서 한 정점..

[Directx12][19장]법선 매핑

개요 기존에는 삼각형의 한 점의 법선을 정점 법선들의 보간으로 구했다. 이제는 법선 맵에서 텍스처 좌표로 법선을 추출하여 특정 픽셀의 법선을 구하는 법선 매핑을 사용해 볼 것이다. ​ ​ 법선 맵 법선 맵은 각 텍셀이 단위 벡터에 해당하는 텍스처이다. 보통 0~255의 8비트 RGB를 사용하며 이는 단위벡터의 각 원소의 상한인 -1 ~ 1을 0~255로 변환한 값에 해당한다. 보통 포토샵이나 기타 툴로 법선 맵을 작성하면 RGB에 각각 0~255값으로 변환된채 텍스처가 저장되는데 이러한 텍스처를 루트 매개변수에 넣고 표본 추출을 통해 특정 텍셀을 추출하면 자동으로 0~1의 값으로 변환된다. 여기에 2를 곱하고 1을 빼서 -1 ~ 1구간으로 변환하면 원래의 단위 벡터를 구할 수 있다. ​ 텍스처 공간 (접..

[Directx12][18장]입방체 매핑

개요 DirectX는 6개짜리 텍스트 배열을 입방체 맵(cube map)이라는 특별한 형태로 해석하여 사용 할 수 있다. 각 텍스트는 좌표축에 정렬된 큐브의 각 면을 나타내며 0~5번째 텍스처는 각각 +-X 면 +- Y면 +-Z면에 해당한다. 이는 6개 짜리 텍스트 배열로 자원을 생성하고 차원 멤버를 cube map로 설정한 desc로 srv를 만들면 큐브 맵에 대한 뷰가 생성된다. 이후 그 srv를 루트 매개변수에 달고 hlsl에서 TextrueCube라는 타입으로 받으면 큐브 맵이 쉐이더에 전달된다. 큐브 맵 에서는 3차원 좌표로 표본 추출을 할 수 있는데 원점에서 해당 좌표에 해당하는 벡터로 쏜 반직선이 맞는 입방체의 한 점이 추출되는 점이 된다. 3차원 좌표가 표현하는 벡터는 조회 벡터로 불리며 ..