인스턴싱 : 한 장면에서 같은 물체를 여러 번 그리는 것, 성능을 크게 향상할 수 있다.

절두체 선별 : 시야 절두체 바깥에 있는 일단의 삼각형들을 간단한 판정으로 골라내서 기각하는 기법

 

16.1 하드웨어 인스턴싱

한 장면에서 같은 물체를 여러번 그리되 위치나 방향, 축적, 재질, 텍스처 등을 각자 다르게 해서 한 번에 그리는 것

 

DrawIndexedInstanced 함수의 두번째 매개변수로 원래 1을 사용했었는데 여기에 10을 지정하면 인스턴스를 10번 그린다는 뜻이 된다.

 

인스턴스별로 다른 자료를 가져야 겹쳐 그려지지 않기 때문에, 인스턴스 버퍼를 파이프라인에 묶어야 한다.

셰이더에서 SV_InstanceID라는 시스템 값 의미소로 인스턴스 색인을 알 수 있다.

이 방식을 사용하면 물체별 상수 버퍼를 사용하지 않아도 된다. 인스턴스 버퍼에 넣으면 되기 때문이다.

 

정점 자료(VertexOut)에 재질 색인(인스턴스 버퍼에서 얻어온)을 기록하게 되는데, 정점 자료가 래스터화 단계에서 보간될 때 색인 값이 보간되면 안되기 때문에 색인 특성에 nointerpolation을 지정해야 한다.

 

인스턴스 버퍼는 렌더 항목마다 존재 해야 하며 FrameResource 클래스에서 렌더 항목별로 UploadBuffer로 관리한다.(버퍼를 매 프레임 갱신하기 위해서) (상수 버퍼로 사용할 용도는 아니라서 버퍼 크기를 256 배수에 맞출 필요는 없음)

 

16.2 경계입체와 절두체

DirectXMath의 DirectXCollision.h에 있는 충돌 라이브러리를 사용한다.

 

16.2.2 경계상자

BoundingBox 구조체로 표현

AABB(axis-aligned bounding box: 축 정렬 경계상자)

1. vmin과 vmax로 표현 가능

2. 중심 c와 한계벡터 e로 표현 가능

 

BoundingOrientedBox 구조체로 표현

OBB (oriented bounding box: 유향 경계상자)

ㄴ 메시의 국소 공간에서 계산한 메시의 AABB를 세계 공간으로 변환했을 때 생기는 특정 방향을 가리키는 경계 상자

 

16.2.3 경계구

BoundingSphere 구조체로 표현

중심은 AABB의 중심을 쓰고 반지름은 중심과 임의의 정점 사이의 최대 거리를 사용함

16.2.4 절두체

절두체는 DirectXMath 라이브러리의 BoundingFrustum 구조체로 서술된다.

절두체는 6개의 평면으로 되어있지만, 시야 공간에서 절두체 평면을 정의하는 것은 복잡하지 않다

 

절두체 구조체의 멤버

원점, 회전 사원수

양의 X 기울기, 음의 X 기울기, 양의 Y 기울기, 음의 Y 기울기

가까운 평면 거리, 먼 평면 거리

 

NDC 공간의 꼭짓점을 투영 행렬의 역행렬로 변환하면 시야 공간에서의 꼭짓점이 나온다.

이 변환된 꼭짓점들로 

 

16.2.4.2 절두체 대 구 교차 판정

절두체의 6평면에 대해 구가 평면의 음의 반공간에 있으면 절두체에서 벗어나 있다는 뜻이다.

구의 중심 좌표 c와 법선 벡터 n을 내적한 값이 -r보다 크면 양의 공간 (절두체 내부) 에 있는 것이고

-r 보다 작으면 절두체와 교차하지 않는 것이다.

16.2.4.3 절두체 대 AABB 교차 판정

AABB와 절두체가 같은 좌표계에 있어야 판정을 할 수 있다.

법선 벡터와 가장 정렬되는 대각선 벡터를 이루는 꼭짓점 P와 Q를 구한 뒤 판정에 사용한다.

 

16.3 절두체 선별

절단 단계는 렌더링 파이프라인 단계에서 후반부에 있기 때문에 절단 되기 전까지 시야 밖에 있는 기하구조들에 대해서도 셰이더 함수가 실행되므로 미리 CPU에서 기하구조를 선별하는 것이 좋다.

 

교차 판정은 좌표계가 같아야 하므로 시야 절두체를 각 인스턴스의 local space로 변환하여 비교하는 방식과 AABB를 world space로 변환하고 시야 절두체도 world space로 변환해서 교차 판정을 수행할 수도 있다.

 

좌표계 변환을 위한 함수는 BoundingFrustum 구조체의 Transform함수를 사용하고 입력 매개변수로 변환 행렬을 넣으면 출력 매개변수로 변환된 BoundingFrustum을 보낸다.

 

인스턴스 버퍼를 update 할 때 각 인스턴스가 절두체 내에 있는 경우에만 버퍼에 인스턴스 자료를 담는다.

절두체 내에 있는 인스턴스 개수를 세어서 renderitem에 저장해두고 DrawIndexedInstanced 함수를 호출할 때 입력으로 넣어주면 실제로 보이는 인스턴스들만 렌더링 파이프라인으로 들어간다.

 

+ Recent posts