eDrawings 분산형 데이터 관리 - SolidWorks...프로젝트 관리 프로세스 관리 ... • 최종 설계의 보다 효율적인 검토 및 릴리즈를 위해 설계 및 ...
04_장면 관리 개요
Transcript of 04_장면 관리 개요
2
+ 게임에서 처리하는 개체수가 많아지거나, 표현 영역이 넓어질 경우, 렌더링, 충돌 체크 등의 지역적인 처리에 좀 더효율적인 접근이 필요하다.
+ 개체 수 = 씬에 1000개의 오브젝트가있는데, 실제로 평균적으로 화면에 렌더링 되는 것이 50개 정도라고 하면 장면 관리가 필요하다고 할 수 있다.
+ 영역의 넓이 = 1Km 에 오브젝트들이분포되어 있을 때 시야 거리가 10M 라면 모든 오브젝트의 단순 뷰 컬링보다효율적인 방법이 필요하다.
+ 게임에서 개체를 검색할 필요가 있는많은 분야에서 장면 관리가 필요하다.
오브젝트 렌더링, 충돌처리영향주는 라이팅 검사근접한 오브젝트 리스트
I. INTRODUCTION장면 관리 (Scene Managing) 개요
GTA3 – Rockstar Studios
3
렌더링 관점
+ 게임에서는 렌더링 속도가 큰 영향을줌 => "가장 빠른 렌더링은 그리지 않는 것 “
+ 장면 관리는 화면에 렌더링 된 가능성이 있는 것들만 최소의 탐색으로 빠르게 검색
충돌처리 관점
+ 한 프레임에 N개의 오브젝트에 물리를 적용할 경우 오브젝트간의 충돌 검사사 N x (N-1) 번 일어나게 됨 => “가장 좋은 것은 충돌 가능성이 없는 오브젝트들과는 충돌 검사를 하지 않는 것”
+ 장면관리 => 최소의 탐색으로 충돌가능성 있는 오브젝트만 검색
정리하면
+ 많은 오브젝트들 중에서 처리하고자하는 영역에 포함된, 결과에 영향을 줄가능성이 있는 개체만 빠르게 검색하는것이 장면 관리의 기본
게임에서 많이 사용 되는 기법
+ 쿼드트리+ 옥트리+ k-d 트리+ BSP
장면 관리 역할
4
일반적인 장면 관리 기법들의 공통점
+ 계층적으로 공간을 분할 구성하여 개체 리스트를 관리한다.
+ 모두 트리 구조로 되어 있다.
+ 특정 노드(부모)의 하위 노드(자식)가Test에 통과하지 않는 다면 그 이하는검사할 필요가 없다.
+ 재귀적인 탐색에 적합한 형태다.
+ 알고리즘적인 접근이기 때문에 영역의 크기와 용량이 비례하지 않는다.
공통적인 수도코드 (Pseudo Code)
II. 일반적인 장면 관리 기법
탐색(노드, 검사영역) {
for(i=0; i<자식수; i++) {
if (포함(노드.자식[i].바운드, 검사영역)) {
if (노드.자식[i].속성 == 리프) {
for(j=0; j<노드.자식[i].아이템수; j++) {
if (포함(노드.자식[i].아이템[j], 검사영역))
처리(노드.자식[i].아이템[j])
}
} else
탐색(노드.자식[i], 검사영역)
}
}
}
5
+ 두 가지 축(일반적으로 X, Y)로 각 노드를 계속해서 4분할 하는 방식
+ 게임에서 높이축의 영향을 적게 받는경우 많이 사용된다.
+ 타일 베이스와 비교하면 영역의 크기에 따라 검색 속도의 영향을 적게 받으며 (개체의 수가 같다면 단순히1km맵과 100km 맵은 큰 차이가 없다.), 용량역시 영향을 받지 않는다.
+ 이상적인 트리인 경우 깊이는 log4N으로 6만개의 개체일 경우에도 깊이가4 레벨 정도로 적다
+ 공간 기준으로 트리를 구성할 경우에는 효과적으로 복잡한 곳은 깊이, 아닌곳은 낮게 설정된다.
1. 쿼드트리(Quadtree)
6
트리 만들기
+ 현재 노드에 포함된 모든 아이템들을중심점을 기분으로 각 영역에 포함된것들로 나눈다. (중심점의 결정에 따라트리의 모양이 달라진다.)
+ 각 영역에 포함된 것들로 트리를 만들어트리의 최상위 노드를 자식으로 붙인다.
+ 트리의 깊이가 너무 깊어지거나 오브젝트수가 적당한 수 이하인 경우 더 이상 나누지 않으며, 이 노드를 리프(Leaf)라고 부르며 아이템들 리스트를 가지고있다.
트리를 나누는 중심점
+ 트리를 구성할 때 가장 영향을 많이주는 부분으로 가장 균형 잡힌 트리를위해서는 포함된 아이템을 4등분할 수있는 지점이다.
트리 생성(1)
7
+ 일반적으로는 공간을 균일하게 분할한다. => 비교적 공평한 결과가 나오며, 동적인 개체 위치 이동 등으로 트리의모양이 잘 깨지지 않는다.
나누는 영역에 아이템이 겹치는 경우
+ 겹치는 모든 노드에 포함시킨다.
트리의 노드 수가 약간 증가할 수 있으나, 검색에 큰 무리는 없다.
하나의 아이템(개체)의 여러 개의 리프에 포함되기 때문에 하나의 아이템이여러 개 검색 될 수 있으므로 중복 검색에 대한 처리가 필요하다.
+ 노드에 아이템을 포함시키고 하위 노드에 넣지 않는다.
리프에 중복되어 등록되지 않으나, 상위에 등록될 경우 실제 결과와 상관없이 검색되기 때문에 수가 많으면 효율이 떨어질 수 있다.
+ 느슨한 노드를 만든다.
겹치는 경우 4 영역 중 임의의 하나의영역에 포함시킨다.
리프에 중복 등록되지 않는다
하위 노드는 포함한 아이템들로 바운드 영역을 새로 구한 후 저장한다.
트리 생성(2)
8
트리 생성(3)
CQuadTree::_NODE * CQuadTree :: BuildTree(RECT *rectlist, int * itemidx, intnum, const RECT &bound, int lv)
{
int * temp = new int [num];
int i, n, side;
_NODE * node;
node = new _NODE;
memset(node, 0, sizeof(_NODE));
node->pivot.x = (bound.left + bound.right) / 2;
node->pivot.y = (bound.top + bound.bottom) / 2;
for(side=0; side<4; side++)
{
RECT localbound = Divide(bound, node->pivot, side);
for(i=0, n=0; i<num; i++)
if (ContactTest(rectlist[itemidx[i]], localbound) == true)
temp[n++] = itemidx[i];
if (n == 0){ // null node
node->child[side] = NULL;
} else
if (lv+1 >= _MAX_DEPTH || n <= _MAX_ITEM)
{ // leaf
int * leaf = new int [n+1];
for(i=0; i<n; i++)
leaf[i] = temp[i];
leaf[i] = -1;
node->child[side] = leaf;
node->mask |= 1<<side;
} else
{ // node
node->child[side] = BuildTree(rectlist, temp, n, localbound, lv+1);
}
}
delete [] temp;
return node;
}
9
탐색 알고리즘
+ 앞서 소개한 탐색 수도코드와 같다.
+ 하위 노드가 바운드에 속하는 지 검사하고, 속하는 경우 하위 노드가 리프인지 검사해서 리프인 경우 그리기, 아니면 다시 재귀적으로 검색한다.
쿼드트리 탐색 (1)
{
int * leaf = (int*) node->child[side], i;
for(i=0; leaf[i] >= 0; i++)
{
if (m_UpdateCntList[leaf[i]] != m_UpdateCnt)
{
if (ContactTest(m_RECT, g_TestList[leaf[i]]) == true)
{
FillRect(m_HDC, &g_TestList[leaf[i]], NULL);
m_UpdateCntList[leaf[i]] = m_UpdateCnt;
}
}
}
} else
Explorer(rect, (_NODE*) node->child[side]);
}
}
}
}
void Explorer(const RECT & rect, _NODE * node)
{
for(int side=0; side<4; side++)
{
if (node->child[side] != NULL)
{
if ((side==0&&rect.left<=node->pivot.x&&rect.top<=node->pivot.y) ||
(side==1&&rect.right>=node->pivot.x&&rect.top<=node->pivot.y) ||
(side==2&&rect.left<=node->pivot.x&&rect.bottom>=node->pivot.y) ||
(side==3&&rect.right>=node->pivot.x&&rect.bottom>=node->pivot.y)) {
if (node->mask&(1<<side))
10
하위노드가 검색 영역과 겹치는 지 검사하는 방법
+ 서브 바운드를 구해서 영역과 검사검사 속도는 느리지만, 뷰 프러스텀
컬링시에는 이 방법만 유효한다
+ 중심점과 영역과 검사아래 0번 평면의 경우 중심점과 검색
영역의 left, top으로 판단 가능하다.
쿼드트리 탐색 (2)
+ 비트 마스트를 이용한 중심점과 영역검사
두 번째 연산 방식을 비트 세팅을 이용해서 방법으로 처리가 간단해진다. (셈플의 _OPTIMIZE 전처리기 이용한부분 참조)
이용 가능한 특성
+ 노드가 완전히 검사 영역안에 있다면하위 노드는 모두 영역안에 포함된다.
+ 리프가 검사 영역안에 있다면 상위모든 노드는 영역을 포함한다
+ 분할 지점이 영역 안에 있다면 모든자식은 영역을 포함한다.
11
샘플 어플리케이션
+ 화면 상에 임의의 크기의 많은 수의개체들 분포되어 있을 때 임의의 영역의 개체를 선택할 경우 단 몇 번의 탐색으로 영역에 포함되는 개체를 얻을 수있다.
+ 선택 영역 : 보라색
+ 영역 안에 있는 리프에 있는 아이템 : 백색 개체, 백색 아웃라인 개체
+ 최종 선택 영역안에 있는 개체 : 백색
http://digibath.com/noerror/download/2dquadtree.zip
쿼드트리 샘플
12
+ X, Y, Z축의 3가지 축 성분으로 공간을 분할한다.
+ 쿼드트리와 거의 대부분의 특성이 동일하다.
+ QuadTree 에 축이 하나 추가된 형태라고 볼 수 있다.
+ 공간적으로 골고루 분포된 형태의 씬에 적합하다.
+ 예를 들어 메시의 삼각형 단위의 충돌 디테일을 가진다면 내부적으로는 각트라이 앵들을 Octree 형태로 가지고있으면 효율적이다.
+ 공간을 8등분하기 때문에 탐색 복잡도는 훨씬 작아진다. 이상적인 경우O(log8N).
+ 쿼드트리와 마찬가지로 균일한 크기로 노드를 분할 할 경우 유연하게 동적인 개체 관리도 가능하다
2. 옥트리 (Octree)
13
+ 옥트리나 쿼드 트리의 경우 아이템들이 한 라인을 이루거나 한 평면에 위치할 경우 비효율적으로 트리가 구성된다.
쿼드 트리의 가지가 2개인 채로 계속구성된다거나, 옥트리에서 아이템의 Y값이 모두 0이라거나 하는 식으로.
+ k-d 트리는 두개의 가지를 이진 트리의 일종으로 노드의 아이템을 이분할하기 좋은 축을 선택해서 트리를 생성한다.
+ 나누는 축은 한가지 요소 (x, y, z중의하나) 만으로 분할 되기 때문에 탐색 연산이 적고, 간단하다.
+ 옥트리나 쿼드 트리에 비해 아이템의분포에 큰 영향 없이 균형 있는 트리가구성된다.
+ 아이템이 자주 옮겨 다닐 경우 트리균형을 깰 수 있기 때문에, 동적인 개체보다는 정적인 개체에 적합하다.
3. k-d Tree
14
+ 기본적인 트리의 속성은 이전의 트리들과 동일하다.
+ k-d 트리와 마찬가지로 두개의 가지를 가지는 이진 트리의 형태를 가진다.
+ 분할하는 평면은 축에 고정되어 있는것이 아니라 임의의 평면이 된다. (즉, 아이템을 나눌 때 형태의 영향을 덜 받게 되며, 나누는 평면에 겹치는 경우를줄일 수도 있다.)
+ 정적인 개체들에 대해서 균형 잡힌트리를 구성하는 것이 일반적이며 동적인 개체 관리에는 적합하지 않다.
+ 트리를 생성하는 시간이 많이 걸린다. (각 노드를 균형 있게 이분하는 평면을구하기가 쉽지 않다.)
퀘이크의 사례
+ 폴리곤으로 트리를 구성했으며, 노드에 페이스 리스트가 있고, 리프는 공간을 나타낸다.
+ 겹치는 폴리곤이 생길 경우 실제로폴리곤을 분할해서 정확하게 노드에 속하도록 되어있다.
+ 뷰 컬링의 경우 카메라의 위치와 노드의 분할 평면과의 위치로 탐색한다.
+ 충돌도 bsp특징을 이용해서 최적의탐색이 가능하다
4. BSP
15
+ 단순히 영역 검사나 뷰 컬링을 이용한 장면 관리 기법이 아니라 기하적인특성을 이용하는 장면 관리 기법.
+ 기하적인 연산이 들어가기 때문에 탐색이 일반적인 탐색보다는 부담스러울수 있기 때문에 렌더링 할 때 주로 사용된다.
+ 포탈은 특별한 형태의 장면 관리 기법이다.
+ 오컬루젼 컬링, PVS는 독립된 장면관리 기법은 아니지만 장면 관리 기법에 붙어서 같이 사용되는 기술이다.
+ 실내 지형에는 포탈이 적합하다.
+ 거대한 개체가 필드상에 존재하는 ㄱ여우에는 오컬루젼 컬링이 도움이 된다.
+ 닫힌 지형이거나, 언덕, 성벽등의 특징 있는 지형에서는 PVS가 도움이 된다.
III. 렌더링 컬링을 위한장면 관리 기법
16
특징
+ 노드는 트리 구성이 아닌 연결이 자유로운 그래프로 구성된다.
+ 기본적으로 노드는 기하적으로 구성되어 있기 때문에 개체 수의 영향을 받지 않으며, 개체의 이동에 따라 노드가바뀌지 않으므로 동적으로 처리 가능하다.
기본 원칙
+ 각 노드는 특정 영역으로 구성되며노드의 연결부는 포탈이 존재한다.
+ 임의의 노드에서 포탈이 보이지 않을경우 연결된 노드는 안 보인다.
+ 포탈을 통해서 보인 노드에서 다음노드로 연결 검사할 때는 상위 포탈을통해서 보이는 지 검사한다.
렌더링 수도 코드
1. 포탈(portal)
탐색(노드) {
그린다(노드)
for(i=0; i<자식수; i++) {
if (노드.자식[i].닫혔나 == false) {
if (화면에보이나(노드.자식[i].포탈)) {
탐색(노드.자식[i])
}
}
}
}
17
기타
+ 연결된 노드가 작은 포탈을 통해 보일 경우 미리 렌더링된 이미지로 처리로 처리 가능하다.
+ 게임 내에서 문이나 도구로 포탈을가릴 경우 포탈 구조와 연동해서 연결된 노드를 렌더링하지 않을 수 있다
+ 특별한 형태로 지형이 구성되어야 하며, 포탈의 설정, 노드 결정 등의 데이터 수집 어려움으로 쉽게 적용하기 힘들다.
+ 실내 지형에 적합하다.
포탈(2)
http://www.cs.virginia.edu/~luebke/publications/portals.html
18
+ 앞의 개체에 의해 뒤의 오브젝트가완전히 가려지는 지 검사하는 방식 => “가장 빠른 것은 그리지 않는 것”
구현방법
+ 기하적인 방법 : 기하적인 연산으로가리는 오브젝트에 의해 렌더링할 개체의 바운드가 완전히 가려지는 지 검사한다.
+ 하드웨어적인 방법 : 실제로 작은(!) 뷰에 가리는 오브젝트를 렌더링한 후렌더링할 계체를 그 뷰에 실제로 랜더링해서 화면에 찍힌 픽셀 수를 세어서0인 경우 완전히 가렸다고 판단한다.
기타
+ 연산량이 적은 편은 아니므로, 적절한 설정이 필요하며, 실제로 지형상 많은 걸 가려주는 거대한 개체가 존재해야 효과가 있다.
2. 오컬루젼컬링(occlusion culling)
19
PVS(Potentially Visible Set)
+ 보일 가능성이 있는 집합이란 의미.
+ 쿼드트리, 옥트리, BSP에 상관없이임의의 리프에서 보일 가능성이 있는리프의 리스트를 알 수 있다.
+ 보일 가능성이 있는 리프의 리스트는실시간으로 계산한 데이터가 아닌 미리계산된 값을 사용한다.
+ 구성상 일괄적인 기하적 특성이 없지만, 탑, 산등의 시야를 가지를 것들이있을 때 그런 것들에 의해 절대로 볼 수없는 리프를 찾는 것
+ 미리 계산하는 값이기 때문에 빌드타임의 영향을 거의 안 받으므로 부르탈 포스 알고리즘(Brutal Force Algorithm – 가능한 많은 경우를 직접
대입하여 확률적으로 해결)을 활용할수 있다.
+ 정적인 데이터다.
퀘이크 사례
+ 임의의 리프에 있을 때 보일 가능성있는 모든 리프의 정보를 RLE + 비트데이타로 가지고 있다.
3. PVS