본문 바로가기

컨퍼런스 노트/NDC

(NDC2015) 한 그루 한 그루 심지 않아도 돼요

(NDC2015) 한 그루 한 그루 심지 않아도 돼요


1.듀랑고와 절차적 생성

- 듀랑고의 메인 키워드 : 생존, 투쟁, 개척

> 따라서 환경이 매우 중요하다.

> 환경에 따라서 삶의 터전, 자원 채집, 사냥터, 전장이 좌우된다.


- 듀랑고의 섬은 플레이어의 집이자, 탐험 목적지이자, 다른 부족을 만나는 곳이다.

> 그런 많은 섬들을 일일이 만들기에는 너무 많고 너무 크다.


- 그래서 듀랑고 개발팀은 절차적 생성에 많은 공을 들인다.

> 즉, 컨텐츠를 수동으로 만드는 것이 아니라 알고리즘으로 생성하는 것

> 처음에는 그래픽 텍스쳐, 메쉬에 주로 쓰였지만, 최근에는 사운드, 음성 합성, 게임 월드, 던전, 레벨 생성 등

  폭 넓은 분야에 사용된다.(심지어 영화의 군중 장면까지도)

  ※ 위키피디아의 Procedural generation 항목


2. 현황과 요구 조건 파악

*World Gen 순서

- 세계의 생성

> 대륙/섬의 형태를 결정

> 강, 호수의 모양과 분포를 결정

> 벽 지형의 모양과 분포를 결정

> 타일별 군계, 고도, 습도 정보를 결정


- 식생 시뮬레이터

> 월드젠에서 넘겨준 정보에 맞춰 나무와 암석을 심음

> 나무와 암석의 종류와 분포를 결정

> 특정 주기마다 나무와 암석을 추가로 심거나 제거


- 동물 제어기

> 동물을 배치하고 행동패턴을 결정

> 해당 타일의 식생 정보에 맞는 동물 배치


* 기존 식생 시뮬레이터의 로직

- 특정 땅 타일의 군계 정보를 확인해서

- 해당 군계의 나무/관목/풀/돌 분포 확률과

- 각 식물의 출현 확률로 심을 대상을 선정

- 예: 출현확률 0.2 / 밀집도 70 / 이름 전나무 / ID 엔티티ID / 출현군계 타이가


- 프로토에서는 귀엽게 보였으나, 실제 리소스로 배치하자 대단히 이상해보였다.

- 특정 지역에 지나치게 몰려있거나 군계가 이상하게 설정되는 사태 발생


* 추가적인 요구들

- 원하는 자연물을 쉽게 찾을 수 있어야 된다.

- 진행에 필수적인 자원은 곳곳에 있어야 된다.

- 속도를 개선해야 한다. 너무 로딩이 길다.

- 군계별로 에셋들 색조 모두 맞춰놨다. 너무 휑하거나 빽뺵하지 않게 해야 된다.



3. 자료 조사

- 원리를 알면, 정확하게 그릴 수 있고, 의도에 맞춰 모델링할 수 있다.

- 원리를 알면, 정확하게 계산할 수 있고, 의도에 맞춰 모델링할 수 있다.

- 따라서 생태학의 원리를 조금만 공부해보자!


- 기존에 쓰던 식생 단위는 "군계"였다.

  (예 : 툰드라, 한대림, 열대림, 사바나, 아열대 등)


- 하지만 식생 단위를 규모별로 세분화하면

> 개체

> 군집

> 분층 군락

-------------> 이 위까지가 실제로 플레이어가 보게되는 단계이다.

> 식물 군락

> 1~3단계 지형

> 군계 : 하지만 시뮬레이션은 군계 단위로 하고 있었다




- 예를 들어 사바나라는 군계에는



- 또 예를 들어 열대림이라는 군계에는


- 실제 식생분포의 모델도



- 파괴에 대한 숲의 역동적인 반응 : 평형 - 파괴 - 재성장 - 경쟁 - 개척종 소멸

> 이걸 개체단위 시뮬레이터에선 어떻게 구현할까?

> 작은 풀 심기 - 관목 심기 - 커다란 나무를 심되 나무 아래의 관목과 풀을 없애기



4. 비전 공유

- 조사한 내용을 바탕으로 식생 시뮬레이터를 만들 끝 그림을 전체 팀과 공유


- 새로운 식생 시뮬레이터의 비전

> 플레이어의 위화감을 줄인다 : 식생의 점이적 변화(차차 옮겨감)

> 플레이어가 환경을 자연스럽게 받아들이게 만든다. : 모자이크, 패치, 코리더 등의 형태

> 플레이어가 필요한 자원의 위치를 직관적으로 찾을 수 있게 만든다. : 예를 들어 갈대는 물가

> 플레이어의 행동에 따라 식생이 역동적으로 반응할 기반을 만든다.


5. 세부 로직 디자인

-  식생이 군계를 넘나들면서 점이적으로 변화하게 만드는 스트레스 요인들 적용할 것


- 로직 디자인 한장 요약

> 이 로직은 연산량이 무지막지하다.

> 식물 크기별로 차지하는 타일 수가 다르다.

> 식물이 파괴 후 재생성 될 때마다 계산을 다시 해야 된다.

> 계산 속도가 빨라야 된다.

> 해답은 "21세기 정원사의 OpenCL 경험담"에서



6. 식물 데이터 작성

- 식물 별로 덩치출현 조건, 소멸 조건을 정해주자.

> 수십 종의 모든 식물을 크기별로 줄을 세운다.

> 풀, 나무 등에 따라 덩치 값을 정한다.(높이, 반경-타일)

> 반경 몇 m만큼 다른 식물들 눈치를 볼 것을 정한다.

> 출현/소멸 조건은 어떻게 되는지 결정한다.

(반경 Nm안에 특정 관목이 M그루가 있어야 생성 가능한 나무라거나 동종 10그루면 생성이 불가능하거나.)


- 식물 형태, 종류에 따라 군계 별로 배치하여 상대적 온도/습도 범위를 정해준다.

(특정 온도와 습도 범위 안에서만 살 수 있다.)


7. 개선하기

- 온도와 습도

> 처음에는 같은 군계면 온도를 모두 동일하게 했다

> 경계면이 지나치게 갑작스럽게 바뀐다.

> 온도맵을 점진적인 형태로 변경

> 한 군계는 온도를 특정 범위로 갖도록 하고, 범위가 조금씩 중첩되도록 해서 자연스럽게 변화되도록 한다.

> 나무 속성에 추가!


- 군계 속성

> 눈 덮인 나무가 흙 위에, 눈 안 덮인 나무가 눈 위에 있는 현상 발생

> 식물 별로 군계를 화이트/블랙 리스트 형태로 관리(등장할 수 있는 군계를 한정)

> 나무 속성에 추가!


- 염도와 디스턴스 필드

> 염도가 있는 바다 옆에 갈대가 있는 문제 발생

> 해안선 기준으로 거리를 측정해서 '염도' 속성을 추가하자!

> 새로 계산해야 되니 물 렌더링할 때 사용하는 '디스턴스 필드'를 활용하자!

(※디스턴스 필드 : 물 경계 렌더링할 때 쓰는 값. 바다 뿐만 아니라 강, 호수에서도 쓸 수 있다.)

> 나무 속성에 추가!


- 벽 지형과 디스턴스 필드

> 벽 지형 주변에 큰 나무가 심어져 벽 지형이 안 보인다.

> 벽 지형도 경계선 기준으로 디스턴스 필드를 만들면 될 것이다.

> 나무 속성에 추가!

> 벽 지형 주변엔 바위가 등장하도록!


- 멀티 스테이지

> 갈대가 빽뺵하지 않고 너무 듬성듬성하게 나온다

> 여러번 시뮬레이션 돌리면? -> 으아 모든 식생이 빽빽해진다.

> 식물 별로 스테이지(그룹)를 구분해서, 같은 스테이지 내의 식물끼리만 경쟁하도록 하자.

> 그럼 같은 스테이지 안의 식생 숫자가 적을 수록 더 많이 생성된다.


- 최종 식생 결과물


- 새로 발생한 문제 : 플레이어가 애써 가꾼 마을이 새로 생긴 나무에 파묻힌다. -> 해결 중!


8. 동물 이야기

- 개별 동물은 어느 정도 되어가는데, 무리짓는 동물이 아쉽다. "사파리를 만들자!"


- 동물 행동학 원리를 공부하자


- 무리를 구성하는 것은 상대적으로 쉽다

> 펭균 : 10마리

> 오리 : 어미1, 새끼 6

> 늑대 : 우두머리1, 추종자 4

> 코끼리 : 수컷1, 암컷3, 새끼1


- 무리답게 '움직이게' 하는 것은 생각 좀 해야 된다.



- 개체는 주변 인식과 행동만 하고, 판단은 무리 AI가 하여 개체는 그 명령에 따른다.

> 반경 10m안의 호수로 물을 마시러가라 -> 네 알겠습니다.

> 가는 길에 플레이어가 나타났습니다 -> 위험하지 않으니 일단 물 마셔라


- 무리AI의 위험 판단은 어떻게?

> 하이에나는 사냥감에 따라 무리 수를 변동한다.

> 얼룩말도 하이에나의 숫자에 따라 위험을 판단한다.

> 동물 AI 역시 플레이어 숫자에 따라 위험을 판단하도록 구성

> 추가적으로 플레이어 레벨에 따라 위험을 판단하도록 구성

> 추가적으로 플레이어 장비에 따라 위험을 판단하도록 구성


9. 결론

- 시뮬레이션에 공을 들이는 이유? 

> 수족관 처럼 짜여진 곳도 재미있겠지만, 해수욕장처럼 하고 싶은 데로 자유롭게 놀 수 있는 놀이터를 만들자


- 요약

> 시뮬레이션이 "즐거운 놀이터"가 되려면 플레이어의 멘탈 모델을 만족해야 된다.

> 듀랑고는 높은 표현 수준에 맞춰 생태계 시뮬레이션을 풍성/정교하게 만들고 있다.

> 모사하려는 현실의 구성 원리를 이해하면, 시뮬레이션을 만드는 데에 큰 도움이 된다.

> 기능을 구현할 떄에는 '비전 공유 - 빠른 프로토타이핑 - 반복 개선'이 중요하다.

> 가장 좋은 해법은 동료들에게서 나온다. 항상 상황을 공유하자.