2010年6月30日水曜日

NyMmdに影行列をやってみる

追記(2010/07/05): ARTK_MMDのコードではrenderForShadowってのがあって影行列適応時はこっちで描いてた.



動機
前回の続き.


やってみた
0. 以前の状況からスタート.


1. jp.nyatla.nymmd.test.MmdTest.javaの編集
1.1 MmdTestクラスにフィールドの追加
private float[] ShadowMatrix_ary = new float[16]; //影行列4x4


1.2 MmdTestクラスにメソッド追加
 private static void CalcShadowMatrixf(float[] planeAry, float[] lightPosAry,
float[] shadowMatrixAry) {
float dot = 0.0f;
for (int i = 0; i < 4; i++) {
dot += planeAry[i] * lightPosAry[i];
}

for (int loopY = 0; loopY < 4; ++loopY) {
for (int loopX = 0; loopX < 4; ++loopX) {
shadowMatrixAry[loopY * 4 + loopX] = -planeAry[loopY]
* lightPosAry[loopX];
if (loopX == loopY) {
shadowMatrixAry[loopY * 4 + loopX] += dot;
}
}
}
}

1.3 MmdTestクラス'public void init(GLAutoDrawable drawable);'メソッドの最後, 'return;'直前に以下を追加.
  {
_gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
float plane_ary[] = { 0.0f, 1.0f, 0.0f, 0.0f };
_gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, fLightPos, 0);
fLightPos[2] *= -1.0f;
CalcShadowMatrixf(plane_ary, fLightPos, ShadowMatrix_ary);
}

1.4 MmdTestクラス'public void display(GLAutoDrawable drawable):'メソッドの'this._render.render();'直後に以下を追加.
   {
_gl.glDisable(GL.GL_LIGHTING);
_gl.glDisable(GL.GL_LIGHT0);
_gl.glPushMatrix();
_gl.glMultMatrixf(ShadowMatrix_ary, 0);
_gl.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
//_gl.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
this._render.render();
_gl.glPopMatrix();
_gl.glEnable(GL.GL_LIGHTING);
_gl.glEnable(GL.GL_LIGHT0);
}


2. 実行
2.1 “VM arguments:に'-Djava.library.path=./lib'を入れる”を忘れずに.
2.2 pmd, vmdの順でファイルを指定する.


結果
できた(pmd: '初音ミク'(MMD添付モデル),vmd: '【MMD】みくみくにしてあげる♪【してやんよ】【Project DIVA】' 感謝).


モデルによっては明るめの色(0.4, 0.4, 0.4)を影に指定しても問題なさそう.テクスチャの有無が問題かしら?影に色がついてしまうモデルもあった.
内部で指定しているのだろうか?'_gl.glDisable (GL.GL_TEXTURE_2D);'とかは意味なかったな.はて?


追記
jp.nyatla.nymmd.MmdPmdRenderGL.javaのMmdPmdRenderGLクラスにあるrenderメソッド内でテクスチャの有無でgl.glEnable(GL.GL_TEXTURE_2D);を呼び出している箇所があった.
そこでこのメソッドの呼び出し時のGL_TEXTURE_2Dの状態に応じて,実行するかどうか判定するようにした.
で.影の描画時にはコード側でglDisable(GL.GL_TEXTURE_2D)としてからrenderメソッドを呼ぶようにしてあげた.
これで前述の影に色がついてしまうモデルでも色がつかず,指定した影の色での描画となることができた(pmd: '初音ミクmetal'(MMD添付モデル),vmd: '【MMD】みくみくにしてあげる♪【してやんよ】【Project DIVA】' 感謝).


jp.nyatla.nymmd.MmdPmdRenderGL.java MmdPmdRenderGLクラス renderメソッド内
   boolean b = gl.glIsEnabled(GL.GL_TEXTURE_2D);
if (条件 && b == true) {
// テクスチャあり

} else {
// テクスチャなし

}
…描画他…
if (b) {
gl.glEnable(GL.GL_TEXTURE_2D);
}



jp.nyatla.nymmd.test.MmdTest.java MmdTestクラス displayメソッド内
   {
_gl.glDisable(GL.GL_LIGHTING);
_gl.glDisable(GL.GL_LIGHT0);
_gl.glDisable(GL.GL_TEXTURE_2D);
_gl.glPushMatrix();
_gl.glMultMatrixf(ShadowMatrix_ary, 0);
//_gl.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
_gl.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
this._render.render();
_gl.glPopMatrix();
_gl.glEnable(GL.GL_LIGHTING);
_gl.glEnable(GL.GL_LIGHT0);
_gl.glEnable(GL.GL_TEXTURE_2D);
}


0 件のコメント: