本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

GLSLスキニング

■GLSLでスキニングシェーダー書いてみた

わりとGLSLでスキニングシェーダーをやったという記事を見かけないので
ここで書いてみます。

大変だった点はGLSLでは、Cのようなキャストを受け付けない点。
そのためブレンドインデックスをどうやってint型にするかで悩みました。
実際には、下記のソースコードに示すように int( )で囲ってやる程度で済む話なのですが、
知らないと結構悩みます。

*備考

マトリックスを使わずにfloat4 (すなわちvec4)でやっているのは
単に自分のスタイルなだけです。
先輩のシェーダースタイルに影響された可能性が大です。
matrix型のほうが変換がmulで書ける分だけソースコードはすっきりします。
float4の4つという表現だと、シェーダー定数設定をするコードがすっきりします。
またMatrixをfloat4x3型として使っているような場合で効率よくシェーダー定数を使うことが出来ます。

他にはライティングが適当です。
平行光源と若干のアンビエント成分いれたつもりのコードです。

*ソースコード(VertexProgram)

1頂点あたり4ボーンのスキニングシェーダーです。
1回のマトリックスパレットは36個です。

36個にした理由は、tiny.xがこの個数で描けるからです。

#version 120
attribute vec4 in_position;
attribute vec3 in_normal;
attribute vec2 in_texcoord0;
attribute vec4 in_blendindices;
attribute vec4 in_blendweight;
varying vec4 outCol;
varying vec2 outTexcoord0;
uniform vec4 gViewProj[4];
uniform vec4 gMatrixPalette[4 * 36 ];
uniform vec4 gDiffuse;

void main() {
  int  index[4];
  index[0] = int(in_blendindices.x);
  index[1] = int(in_blendindices.y);
  index[2] = int(in_blendindices.z);
  index[3] = int(in_blendindices.w);
  float weight[4] ;
  weight[0] = in_blendweight.x;
  weight[1] = in_blendweight.y;
  weight[2] = in_blendweight.z;
  weight[3] = in_blendweight.w;
  vec4 pos = vec4(0,0,0,1);
  vec3 nrm = vec3(0,0,0);
  for( int i = 0; i < 4; i++ ) {
    int idx = index[i];
    float w = weight[i];
    pos.x += dot( gMatrixPalette[ idx*4 + 0 ], in_position ) * w;
    pos.y += dot( gMatrixPalette[ idx*4 + 1 ], in_position ) * w;
    pos.z += dot( gMatrixPalette[ idx*4 + 2 ], in_position ) * w;
    nrm.x += dot( gMatrixPalette[ idx*4 + 0 ].xyz, in_normal.xyz ) * w;
    nrm.y += dot( gMatrixPalette[ idx*4 + 1 ].xyz, in_normal.xyz ) * w;
    nrm.z += dot( gMatrixPalette[ idx*4 + 2 ].xyz, in_normal.xyz ) * w;
  }
  gl_Position.x = dot( gViewProj[0], pos );
  gl_Position.y = dot( gViewProj[1], pos );
  gl_Position.z = dot( gViewProj[2], pos );
  gl_Position.w = dot( gViewProj[3], pos );
  outCol = gDiffuse * max( 0.1, dot( in_normal, vec3( 0.7, 0.7, -0.7) ) );
  outTexcoord0 = in_texcoord0;
}
OpenGLプログラミング
すらりんをフォローする
すらりん日記

コメント

タイトルとURLをコピーしました