이론 48

디자인 패턴 - 생성 패턴

개요 생성 패턴에는 다음의 패턴이 포함된다. Factory Factory Method Abstract Factory Builder Singleton Prototype 이 글에서는 위 패턴들을 '간단하게' 다룬다. 팩토리(Factory) 패턴 팩토리는 오브젝트를 찍어내는 공장 같은 것이다. //타입을 받아 클래스를 반환한다. public class AnimalFactory { public Animal Create(AnimalType animalType) { switch (animalType) { case AnimalType.Cat: return new Cat(); case AnimalType.Dog: return new Dog(); } return null; } } 위 방식처럼 ~~ Factory 클래스를..

배칭(Batching)

2021.11.13 - [이론/그래픽스] - 드로우콜(Draw Call) 배칭 배칭은 여러 배치를 묶어 하나의 배치를 만드는 것이다. 드로우콜 횟수를 줄이는 가장 효과적인 방법 중 하나이기도 하다. 배칭을 위해서는 오브젝트들이 동일한 머티리얼을 사용해야 하는데, 이때 머티리얼이 동일하다는 것은 동일한 머티리얼 인스턴스가 같다는 것을 의미한다. 스태틱 배칭 스태틱 배칭은 정적인 오브젝트를 대상으로 하는 배칭 기법이다. 따라서 런타임에서 버텍스 연산을 하지 않아도 되기 때문에 매우 효율적이다. 스태틱 배칭은 메시의 폴리곤 수에 상관 없이 같은 머티리얼을 사용하는 오브젝트들을 하나의 메시로 묶어준다. 단, 머티리얼이 1개라고 해서 무조건 1개의 배치로 합쳐지는 것은 아니며 라이트와 같은 요소들로 인해 배칭이 ..

이론/그래픽스 2021.11.15

드로우콜(Draw Call)

드로우콜 CPU는 현재 프레임에 어떤 것을 그려야 할지 정하고, GPU에 오브젝트를 그리라고 명령을 호출하는데 이 명령이 바로 드로우 콜(Draw Call)이다. 게임의 오브젝트를 화면에 렌더링하려면 우선 오브젝트가 렌더링 대상인지를 판단한다. 이러한 과정을 컬링이라고 한다. 컬링을 거친 오브젝트가 렌더링 되기 위해선 CPU에서 GPU에 다음의 정보를 줘야 한다. 메시 정보 텍스처 정보 쉐이더 정보 트랜스폼 정보 알파 블렌딩 여부 기타 등등 메시 텍스쳐 쉐이더등의 정보는 스토리지에 보관되어 있다가 CPU가 이를 읽어들여 CPU 메모리에 데이터를 올린다. 그 후 CPU메모리에 있는 정보들을 GPU 메모리로 복사한다. 정보들은 GPU 메모리에 있어야 GPU가 사용할 수 있다. 만약 위 복사과정이 매 프레임마..

이론/그래픽스 2021.11.13

병목(Bottleneck)

최적화 게임의 성능 최적화를 위해서는 다음의 작업들을 고려할 수 있다. 메시의 버텍스 줄이기 텍스처 크기 줄이기 가벼운 쉐이더 사용 드로우콜 줄이기 게임 로직 최적화 물리 연산 줄이기 기타 등등 그러나 위 작업들을 수행하기 전에 어디서 병목이 일어나는지를 알아야 한다. 왜냐면 병목이 일어나는 곳 외에서 최적화를 해봤자 전반적인 수행 속도는 크게 바뀌지 않기 때문이다. 목표 설정 게임의 최적화 목표를 설정할 때 60FPS냐 30FPS냐를 정하는 것을 목표로 삼을 수 있다. 그러나 먼저 기준이 되는 하드웨어 스펙을 정해야 한다. 예를 들어 만드는 게임이 퍼즐게임이라면 가능한 다양한 기기에서 이용 가능하도록 해야 할 것이다. 또한 더 좋은 디바이스라고 해서 병목이 덜 발생할 것이라고 생각할 수 있지만 사실은 ..

이론/그래픽스 2021.11.03

렌더링 파이프라인

GPU 원래 렌더링은 CPU로만 처리하고 있었는데 GPU가 추가되면서 이를 이용한 하드웨어 가속이 가능해졌다. 동시에 렌더링 파이프라인이라는 개념이 쓰이게 됐고 이는 여러 Graphics API의 기반이 된다. CPU가 GPU에 명령을 보내어 각각 자신의 일을 병렬적으로 처리한다. GPU에는 VRAM이라는 전용 메모리가 존재하는데, 여기에는 텍스쳐나 메시 데이터 혹은 이중 버퍼링등에 쓰이는 버퍼가 저장된다. 기기별로 하나의 물리적인 RAM을 CPU+GPU가 나눠서 쓰기도 한다. 렌더링 파이프라인 래스터(raster) : 화상 정보를 표현하기 위해 이미지를 2차원 배열 형태의 픽셀로 구성하여 표현하는 것. 즉, 연속된 픽셀들의 집합. 렌더링 파이프라인 : 3차원 이미지를 2차원 래스터 이미지로 표현하기 위..

이론/그래픽스 2021.10.26

ECS (Entity Component System)

ECS 정의 "A different paradigm of writing code, where we model our programs in a data oriented way" 유니티 ECS 메뉴얼에서는 ECS를 위와 같이 정의했다. 데이터 지향 설계방식은 아래 글을 참고. https://tsyang.tistory.com/68 Data-oriented Design (데이터 지향 설계, DoD) CppCon 2014 - Mike Acton의 "Data-Oriented Design and C++"을 주로 참고해서 씀. https://www.youtube.com/watch?v=rX0ItVEVjHc 인트로 1. 소프트웨어는 플랫폼이다. 2. 코드는 실제 세계의 모델을 중심으로 설.. tsyang.tistory.c..

이론/설계 2021.09.26

Data-oriented Design (데이터 지향 설계, DoD)

CppCon 2014 - Mike Acton의 "Data-Oriented Design and C++"을 주로 참고해서 씀. https://www.youtube.com/watch?v=rX0ItVEVjHc 인트로 1. 소프트웨어는 플랫폼이다. 2. 코드는 실제 세계의 모델을 중심으로 설계되어야 한다. 3. 코드는 데이터보다 중요하다. 저 위의 3가지 명제를 보면 그럴 듯 하다. 특히 2번의 경우에는, 게임 클라 개발자로써 많이 의식하는 명제인 것 같다. 누가 저렇게 하라고 시키지는 않았지만 많은 예제코드에서 저런 식으로 코드를 짜니까. (ex. 몬스터 클래스가 있고 그 안에 transform, status, animation... 등을 포함) 강연자인 Mike Acton은 저 위의 3가지 명제를 거짓말이라고..

이론/설계 2021.09.19

곡선(Curve) & 스플라인(Spline)

곡선 곡선을 표현하기에 앞서, 두 정점 (A, B) 사이에 있는 점 P를 다음과 같이 표현할 수 있다. 또한 곡선은 t에 대한 방정식(P(t))으로 표현할 수 있다. 베지에 곡선(Bézier Curves) n차 베지에 곡선은 n+1개의 점으로 얻을 수 있는 베지에 곡선이다. 1차(Linear) 베지에 곡선은 앞서 말한 점 A,B 사이에 있는 점 P의 집합으로 표현할 수 있다. 말이 곡선이지, 사실상 A-B를 잇는 선분이다. 2차(Quadratic) 베지에 곡선은 아래와 같다. 2차 베지에 곡선은 A와 B를 잇는 1차 베지에 곡선 위에 있는 한 점 AB(t)와 B와 C를 잇는 1차 베지에 곡선 위의 한 점 BC(t)사이에 있는 한 점 P(t)의 집합으로 볼 수 있다. 식으로 표현하면 다음과 같을 것이다. ..

이론/그래픽스 2021.07.11

클린 코드 - 경계

개발을 하다 보면 외부 코드 (구매한 패키지, 오픈 소스, 다른 팀이 개발한 컴포넌트 등) 를 사용할 일이 있다. 이 장에서는 이런 외부코드를 깔끔하게 사용하는 법에 대해 다룬다. 외부 코드 사용 외부 인터페이스를 사용할 때는 해당 인터페이스를 사용하는 클래스 밖으로 인터페이스가 노출되지 않도록 해야한다. 만약 그렇지 않다면 다음과 같은 문제가 생긴다. 만약 외부 인터페이스의 메서드들이 모두 노출된 상태에서 사용한다면, 누군가 의도치 않은 메서드를 사용하여 예기치 않은 문제를 발생시킬 수 있다. 외부 인터페이스가 변할 경우, 메서드를 사용한 코드를 모두 수정해야 한다. 따라서 외부 코드를 새로운 클래스로 감싸거나 Adaptor 패턴을 이용하면 좋다. 이 경우 인터페이스에 변경이 발생해도 해당 클래스만 수..

이론/설계 2021.06.13

클린코드 7장 - 오류 처리

깔끔한 오류 처리는 중요하다 여기 저기 흩어진 오류 처리 코드 때문에 코드의 가독성이 떨어질 수 있기 때문이다. 오류 코드보다 예외 예외처리가 아닌 오류 처리는 기본적으로 if,else 분기를 타며 Debug.Log(...)를 하는 코드이다. 그러나 이런식으로 쓰면 논리가 오류 처리 코드와 뒤섞여 알아보기 힘들다. 그러나 예외를 사용하면 이를 구분할 수 있다. 단, 앞 장에서 말했듯, 오류 처리도 '한 가지 일'이다. 오류를 처리하는 알고리즘은 분리해야 한다. public void DoSomething() { try { TryDoSomething(); } catch (Exception e) { } } Try-Catch-Finally 부터 작성해라 별 이유는 아니고 이렇게 하면 자연스럽게 try 블록의 트..

이론/설계 2021.05.21