OpenGL 에서 GPU 스키닝

1. vertex shader constants
2. vertex shader with bindable uniform
3. vertex shader with VTF (Vertex Texture Fetch)

1. 쉐이더를 지원하는 모든 그래픽 카드에서 가능, SM3 이하 카드에서 상수개수 제한(256 * vec4)이 문제가 됨
2. SM4 이상에서 가능, SM4 에서 이미 충분한 상수 개수(4069 * vec4) 제한
3. SM3 이상에서 가능, 상수개수 제한 없음 (정확히는 텍스쳐 크기로 제한을 받음)

4×3 행렬을 사용했을 때 버텍스 쉐이더 상수 제한이 256 일경우 사용할 수 있는 최대 bone 개수는 80개 정도
(256 / 3 = 85.33333333)… 게다가 다른 상수들을 위한 공간을 확보하고 나면 실제로는 70 개 정도 밖에 여유가 없다.
이를 위해 메쉬를 쪼개든지, 한 메쉬에 영향을 받는 본 개수를 70 개 이하로 줄여야 하는 상황이 된다

VTF 를 이용하면 RGBA_32F_32F_32F_32F 포맷의 1024 x 1 사이즈의 텍스쳐를 이용한다고 할때,
대략 320 개 정도의 bone 을 사용할 수 있다.

실제로 엔진에서는 4096 x 32 (2Mb) 정도 크기의 텍스쳐 잡아놓고(x2 더블 버퍼링), 엔티티 skinning 버퍼로 사용한다
(modular 연산을 피하기 위해 가로로 길게 잡음) 모든 entity 의 skinning 행렬을 가지고 있으므로 instancing 도 가능하다.

PBO(ARB_pixel_buffer_object) 확장을 이용해 버퍼의 내용을 asyncronous 하게 업데이트 가능하고,
TBO(ARB_texture_buffer_object) 확장을 이용하면 좀더 심플하게 메모리 낭비 없이 구현 가능하다

1. direct copy (system memory -> texture)
첫번째 프레임: Copy to Texture1
두번째 프레임: Copy to Texture2

2. PBO
첫번째 프레임: PBO1 -> Texture (DMA copy)
두번째 프레임: PBO2 -> Texture (DMA copy)

3. TBO
첫번째 프레임: TBO1 -> Buffer Texture1
두번째 프레임: TBO2 -> Buffer Texture2

속도는 TBO > PBO > direct copy 순으로 빠름

참고 자료:
http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt
http://en.wikipedia.org/wiki/Shader_Model_4.0#Shader_model_comparison
http://en.wikipedia.org/wiki/Comparison_of_NVIDIA_GPU
http://en.wikipedia.org/wiki/Comparison_of_ATI_Graphics_Processing_Units

Leave a Reply

Your email address will not be published. Required fields are marked *