スキニング高速化
=================
<%= player('vmdturnglsl.mp4', 320, 240) %>
モデルはMMDより初音ミクVer2.pmdを拝借
モーションは
MikuMikuDanceでバレエモーションより
ピケターンを拝借
(IK無しのモーション)
40FPS
ハードウェアスキニング
----------------------
ソフトウェアスキニングでは各頂点について
__PRETTYPRINT__
deformed=Matrices[boneIndex0] * p * SkinningWeights[boneIndex0] + Matrices[boneIndex1] * p * SkinningWeights[boneIndex1];
という計算をCPUで事前に施したものを頂点配列として使用したがこの部分を頂点シェーダーでやる。
そのためには、追加のuniform変数としてスキニング行列の配列、追加のattribute変数としてスキニング行列参照用のインデックスとその行列のウェイトが必要となる。
ここでは、PMDの仕様(ひとつの頂点が参照するボーン数は2、スキニングウェイトの合計は1)を採用して、行列参照用インデックス値を2つと1つ目のボーンに対するウェイト値(2つ目は1.0からの引き算で算出できる)の計3つを追加の頂点属性として頂点シェーダーに送り込む。
追加のattribute変数
^^^^^^^^^^^^^^^^^^^^^
|TABLE(class=matrix)|
|ROW|
|COL(head)|属性
|COL(head)|glsl変数
|COL(head)|備考
|ROW|
|COL|ボーンインデックス0
|COL|attribute float bone_index0
|COL|頂点属性にintは使えないのでfloatを使っている
|ROW|
|COL|ボーンインデックス1
|COL|attribute float bone_index1
|COL|頂点属性にintは使えないのでfloatを使っている
|ROW|
|COL|ウェイト
|COL|attribute float bone_weight0
|COL(prettyprint)|bone_weight1=1.0-bone_weight0
**追加のuniform変数
|TABLE(class=matrix)|
|ROW|
|COL(head)|備考
|COL(head)|glsl変数
|ROW|
|COL|スキニング行列
|COL|uniform mat4 boneMatrices[?]
**VertexShader
ここで問題になるのがboneMatricesの長さ。
glslで使えるデータ容量はわりと厳しく環境によっても違うらしい。
GeForce6200で試したところ60くらいまでいけた。
10~20に上げたときは速度が改善したが、それ以降それほどは変わらなかった。
ということで指定したボーン数でメッシュ(IndexArray)を分割するコード書く。
**Index配列の分割
<%= source_view('src/glslPMDMeshVMD.py')
<%= source_view('src/glslMesh.py')