336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이 글은 10년도 글 백업임

---------------------------------


shader constant array를 이용한 Mesh Instancing Game develop

이번엔 인스턴싱에 대해 이야기 해보고자 한다. instancing에 대한 정의 및 정리는 다른 분들이 잘 해주신 것들이 많기에 괜히 내가 어설프게 따로 정리하지는 않는다. 다만 내가 사용 한 조금 다른 방식을 소개하고 조언을 구하고자 한다. 우선 인스턴싱에 대하여 잘 모르시는 분은 다음 링크들을 살펴보면 되겠다.

: 이 글 내에도 더 많은 인스턴싱 뿐 아닌 Batching 관련 용한 링크들이 있다.
: XNA 기준으로 작성이 되어 있지만 함수 프로퍼티만 다를 뿐, 개념 및 설명은 정말 잘 되어 있다.
: DX10 기준으로 설명이 되어 있다. VS에서의 텍스쳐 읽기(VTF)는 Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술에도 응용하고 있다.
http://zeuxcg.blogspot.com/2007/09/particle-rendering-revisited.html
: 파티클에 instancing을 응용하는 방법이 설명되어 있다. 여기서 버텍스의 위치를 정하는 방법은 SpeedTree, SpeedGrass등에서도 쓰이는 방법과 비슷하다.

최근의 대중화된 그래픽카드들은 웬만하면 Shader Model 3.0이상을 지원하므로, 우리 엔진도  secone Vertex Buffer를 사용하는 Hardware Instancing를 이용한다. 
그러기 위해서는 매번 second Vertex Buffer에 대하여 lock/unlock를 수행해야 한다. 나는 buffer lock없이도 오브젝트들을 transform 시키고 컬링에서 걸러질 수 있을 지 고민하다 셰이더 상수 배열을 이용하기로 했다. 위 링크에 나온 방식에서 특별히 크게 다른 것도 아니고, 쉽게 생각 할 수 있는 방식이라 이미 누군가 사용하다 버린(내가 생각했던 것 보다 효울이 그렇게 좋지는 않았기 때문에) 것일 지도 모르겠다.
 - second Vertex Buffer의 자료형은 오로지 float하나만으로 이루어져 있다. 
 - 한번에 수용 가능한 인스턴스의 갯수만큼의 크기 n의 크기로 버퍼를 생성하고, 0,1,2~(n-1)로 채운다. 이 숫자들은 변경될 일이 없으며, 상수 배열의 인덱스로 쓰인다.
 - 셰이더에서는 인스턴스의 트랜스폼을 결정 할 매트릭스 배열 m[n]을 선언한다. 
 - 오브젝트의 위치 변화가 있을떄 혹은 매 프레임마다 인스턴스들의 world matrix들을 m에 셋팅해준다.
 - VS에서는 second stream의 내용을 m[]의 인덱스 첨자로 사용하여 world matrix를 결정하고 transform한다.

이렇게 되면 Vertex Buffer의 실시간 Lock/Unlock비용에서 해방될 수 있다. 
하지만 단점으로는, 
 - 1. 상수 갯수의 제한이 있다보니 한번에 100단위의 갯수를 그려내지 못한다. 이것 저것 따지다보면 기껏 해봐야 3,40개 정도가 수용 가능하다. 하지만, 실제 게임에서 랜더링 하다보면 같은 메쉬를 그 이상 그려낼 일이 많이 없다. 100단위 혹은 1000단위로 그려내는 것은 테스트 컷 외에는 발생하지 않으므로, 이 단점이 큰제약이 되지는 않는다.
 - 2. matrix array를 셰이더로 넘겨주는 것이 생각보다는 무겁다. VB lock보다는 낫긴 하지만 생각보다 드라마틱한 효과는 보지 못했다.
 - 3. 실제 그리려는 인스턴스의 갯수와는 상관 없이 m[n]의 크기에 따라  SetMatrixarray()를 통한 상수 설정 시간이 결정된다. SetMatrixarray(,,1)을 하든 SetMatrixarray(,,40)을 하든 상관 없이 n에 따라 비례한다. 이를 극복할 수 있는 방법이 있으면 조언을 부탁드린다.

만약 우리 게임이 작은 우주선이 2,300개씩 나오는 RTS라면 이 방식이 쓰이지 못할 것이다. 하지만 우리 엔진에는 꽤 적합한 방식이라 생각하고 있다. 작업 양이 그리 크지도 않으므로 이런 방식으로도 한번 시도해보시길 바란다. 작업시 문제점과 개선점도 공유해주시고말이다~ 굽신~굽신~ 


Posted by ozlael
,