220 likes | 439 Views
GPU Gems3 Chapter 2. Animated Crowd Rendering. http://www.kindnap.pe.kr http://cafe.naver.com/shader. introduction. Shader 4.0 버전을 이용한 Skinned Hardware Instancing 을 구현해본다 . A Crowd of Characters Animated Using Skinned Instancing. Hardware Instancing?. 모아 찍는 기술. 오버해드의 원인 캐시 미스
E N D
GPU Gems3Chapter 2. Animated Crowd Rendering http://www.kindnap.pe.kr http://cafe.naver.com/shader
introduction • Shader 4.0 버전을 이용한 Skinned Hardware Instancing을 구현해본다. A Crowd of Characters Animated Using Skinned Instancing
Hardware Instancing? • 모아 찍는 기술 오버해드의 원인 캐시 미스 Render State Texture 풀, 나무, 배경에 적용되는 간단한 Mesh 리소스의 공유 (Texture, VB, IB) 단지 위치,회전 혹은 칼러값 차이
Hardware Instancing? • 하나의 버퍼에 몰아, Draw Call을 최적화 • 이점 Reduce :: Draw Call Reduce :: Cache Miss Reduce :: SetRenderState Reduce :: SetTexture 더 자세한 내용은 http://www.storyq.net/boxes/1841
Hardware Instancing Dx9 • 사용법 In HLSL #define MAX_UNIT_INSTANCING 75 //상수 레지스터의 제한으로 인한 한번을 DP call시 그릴 수 있는 수의 한계를 둠 Float4x3 g_mWorldMatrixArrayInstancing[MAX_UNIT_INSTANCING] : WORLDMATRIXARRAY; //각 인스턴스의 월드행렬 정보의 저장 struct VS_INPUT { float4 vPos : POSITION; float2 vTexCoord0 : TEXCOORD0; float fWorldMatrixIndex : TEXCOORD1; //버퍼중인스턴스의 아이디를 직접 알 수 있는 버퍼의 존재 } Vertex;
Hardware Instancing Dx9 In VS intiMatrixIndex = i.fWorldMatrixIndex; //버택스Input에서 현제 아이드를 참조함 vWorldPos = mul( i.vPos, g_mWorldMatrixArrayInstancing[iMatrixIndex] ); //포지션 개산시 해당 월드행렬의 참조 o.vPos = mul( float4( vWorldPos, 1.0f ), g_mShadowViewProj ); // 이후 일반 연산과 동일한 과정
Hardware Instancing Dx9 • In C Code D3DDevice()-> SetStreamSourceFreq( uiStreamNumber, uiFrequencyParam ); 의 호출
Hardware Instancing Dx9 • 한계점 협소한 상수레지스터(256)의 보유로 많은 수를 Instancing 처리할 수 없음 Shader 2.0버전 기준으로 Vs에서 택스쳐를 샘플링 할 수 없으므로 Skinned Instancing 구현 시 상수 레지스터가 더욱 모자라게 됨
In Article Technique (Use DX10 – shader 4.0) • DX10을 이용한다면 현실적으로 적용하며 효율적인 Skinned animated instancing이 구현가능 • Animation 정보를 택스쳐에 기입 // shader 3.0이상 사용시 vs에서 샘플링 가능 • 상수 레지스터에 기존방법에 + Animation info ( 참조 에니매이션, 프레임정보…)
Technique Cpu 프로그램의 로직을 실행 - (각종 업데이트, AI, 그에따른ani진행) 각 인스턴스에 대한 LOD 그룹화 - 결정된 LOD 그룹에서 매쉬별로 그룹화 LOD 그룹기준으로 각 그룹에 대하여 동일 매쉬를 사용한다면 DrawInstanced();
Technique Gpu VS Load Instance data Load bone matrix(in tex) ani연산 PS 여타와 같은 행위
Technique Constants – Based Shader 4.0기준 상수 레지스터는 4096 (3.0 / 256) 위와 같은 방법으로 연산시 한번에 Dp call당 800개의 instance를 랜더링 가능 10000여기의 오브젝트를 랜더링시13번의 Dp Call 이면 랜더링이 가능함
Technique Constants – Based HLSL struce structPerInstanceData { float4 world1; float4 world2; float4 world3; float4 color; uint4 animationData; }; cbuffercInstanceData { PerInstanceDatag_Instances[MAX_INSTANCE_CONSTANTS]; }
Technique Constants – Based C Struct structInstanceDataElement { D3DXVECTOR4 world1; D3DXVECTOR4 world2; D3DXVECTOR4 world3; D3DXCOLOR color; // Offset in vectors (texels) into the whole data stream // for the start of the animation playing UINTanimationIndex; // Offset in vectors (texels) into the animation stream // for the start of the frame playing UINTframeOffset; UINT unused1; // pad UINT unused2; // pad };
Conditional branching float4x4 finalMatrix; // Load the first and most influential bone weight finalMatrix = input.vWeights.x *loadBoneMatrix(animationData,input.vBones.x); // Conditionally apply subsequent bone matrices if the weight is > 0 if(input.vWeights.y > 0) { finalMatrix += input.vWeights.y *loadBoneMatrix(animationData,input.vBones.y); if(input.vWeights.z > 0) { finalMatrix += input.vWeights.z * loadBoneMatrix(animationData,input.vBones.z); if(input.vWeights.w > 0) finalMatrix += input.vWeights.w * loadBoneMatrix(animationData,input.vBones.w); } }
Geometry Variations • 같은 ani를 참조하고 있지만, 캐릭터의 장비를 다양하게 줄 수 있다. • 하지만 장작된 장비기준으로만 인스턴싱 그룹이 된다. • 자동화를 위하여 익스포터시 모든 장비를 장착한체익스포터 시키고 프로그램 상에서 특정 장비를 선택하게 하는 방식으로 구현할수 있다.
The Level-of-Detail System • 거리 기준으로 정렬 • 거리 기준으로 정렬된 데이터를 매쉬별로정렬 • ANIMATION데이터 또한 LOD 별로 제작되 있음
Other Considerations • Color Variations 베이스가 되는 칼라값 또한 인스턴스 정보에 넣어주어 효과를 줄 수 있으며 기존 app에 적용되어 있다. (LOD 설정 정도의 표시 기능)
Performance • 8600 회사똥컴 24frame / 9547 characters if no instancing 16frame / 9547 characters • 8800 Gtx 34frame / 9547 characters
Conclusion • Instancing 사용합시다. 끝!