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? 모아 찍는 기술 오버해드의 원인 캐시 미스 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 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 int iMatrixIndex = 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 struct PerInstanceData { float4 world1; float4 world2; float4 world3; float4 color; uint4 animationData; }; cbuffer cInstanceData PerInstanceData g_Instances[MAX_INSTANCE_CONSTANTS]; }
Technique Constants – Based C Struct struct InstanceDataElement { D3DXVECTOR4 world1; D3DXVECTOR4 world2; D3DXVECTOR4 world3; D3DXCOLOR color; // Offset in vectors (texels) into the whole data stream // for the start of the animation playing UINT animationIndex; // Offset in vectors (texels) into the animation stream // for the start of the frame playing UINT frameOffset; UINT unused1; // pad UINT unused2; // pad };
Palette Skinning Using an Animation Texture
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를 참조하고 있지만, 캐릭터의 장비를 다양하게 줄 수 있다. 하지만 장작된 장비기준으로만 인스턴싱 그룹이 된다. 자동화를 위하여 익스포터시 모든 장비를 장착한체 익스포터 시키고 프로그램 상에서 특정 장비를 선택하게 하는 방식으로 구현할수 있다.
Geometry Variations
The Level-of-Detail System 거리 기준으로 정렬 거리 기준으로 정렬된 데이터를 매쉬별로 정렬 ANIMATION 데이터 또한 LOD 별로 제작되 있음
Other Considerations Color Variations 베이스가 되는 칼라값 또한 인스턴스 정보에 넣어주어 효과를 줄 수 있으며 기존 app에 적용되어 있다. (LOD 설정 정도의 표시 기능)
Performance 8600 회사똥컴 24frame / 9547 characters if no instancing 8800 Gtx 34frame / 9547 characters
Conclusion Instancing 사용합시다. 끝!