影を作ってみる
影を作ってみる
Easy3Dはver5.0.0.1現在において、まだシャドウマップには対応していない。
そのため、影を地面に落とすには工夫が必要です。
無理やりな方法で、キャラクターの斜め方向から光が当たった場合の影を作成してみました。
実用は無理があると思うので冗談半分にでも受け止めてください。
ver5.0.1.6以降から影表示機能が追加されました。
これでこのページは、めでたくネタページへと昇進することができました。よかったよかった。いや、マジで。
基本的なやり方
真上に光源、真下に影が出来た場合を作ってみます。
まずはモデルを2つ用意します。
- <影の元になるモデル>影を作るキャラクターのsigモデル。
- <影用モデル>影を作るキャラクターのsigモデルと同じ形状の黒いモデル。
説明の便宜上、
影の元になるモデルの形状データ識別IDをhsid1。
影用モデルの形状データ識別IDをhsid2。
とします。
影の元になるモデルはいつものように表示してください。
影用モデルは、次のようにして影モデルを平らにつぶします。
E3DSetScale hsid2,, 1.0, 0.0, 1.0, 2
つぶしたら、影の元になるモデルがある地面座標に表示します。
これで、影が出来ました。
この影の欠点は、
- 不透明色しか使えない。半透明はできないようです。
- 結果的にモデルを2つ表示することになりますので、その分動作が重くなります。
- 影は平面なので、凹凸のある地面に表示すると地面にめり込んだりします。
このようにいろいろと問題はありますが、板ポリゴンに貼り付けた影ではなく
モデルの形をした影を造ることが出来ます。
今回のネタはこの手法を応用して斜めから光が当たった場合の影を作ってみたいと思います。
斜めから光が当たったの影を作る原理
説明がめんどくさいので、図を元に記号で説明します。すみません。
DC方向に平行光があたっている場合、影はOCに出来ます。
OAのモデルをDC方向に平面につぶしてOCに貼り付ければよさそう?ですが、
しかしE3DSetScaleではXY,YZ,ZX平面のどれかの平面にしかつぶすことが出来ません。
そこで、キャラクターから見て斜め方向からあたった光の影を作るにはこのように考えます。
光はこれまでどおり真上から当たっているとして、キャラクターを傾けてしまえばいいわけです。
こうすれば、斜めから光が当たった場合の影を作成することが出来ます。
このとき、光が向かってくる角度とキャラクターを傾ける角度に注意が必要です。図のような関係になっています。
またこのとき出来る影は光が来る方向DB(DC)に垂直な平面、OBになります。
では元の図に戻ります。
さて先ほどの方法で作成した影は長さはOB分しかありません。
本来ならOC分の長さが必要なので、地面に投影しても影が短くなってしまいます。
長さを補正してやる必要があります。
図から、
sin(θ) = |OB| / |OC|
ですのでOCの長さは、
|OC| = |OB| / SIN(θ)
となります。OBはもともとの影の長さなので、これを 1/SIN(θ) 倍すればよいことになります。
E3DSetScaleを使って長さを補正すればOKです。
引き伸ばすときは、Z方向のみやX方向のみのように1方向のみにする必要がある点を忘れてはいけません。
伸ばしてから回転、です。
ボーンで回転
しかし問題があります。
キャラクターをE3DRotate系命令で回転して平面につぶしても、キャラクターのローカル座標でつぶされるので
思うような角度でつぶすことが出来ません。
この問題は、ボーンで回転させることで解決します。
ボーンで回転させた場合、キャラクターのローカル座標には影響がありません。
ボーンの直接操作はe3dhsp3_motoinpoint.hspを参考にすることが出来ますので詳しくはそちらを。
私はボーンやモーションについてはほとんど詳しくありませんので、詳細解説は省略させてもらいます。
サンプル
必要なデータはEasy3Dのサンプルに含まれているので、適当に用意してください。
サンプル:e3d3038.hsp
ボーン関係の操作はよく分からないので、スクリプトはかなりのやっつけ仕事です。
わけも分からずe3dhsp3_motoinpoint.hspの一部をコピペして使っていたりします。
こういうこともできると言うサンプルだとお考えください。
問題点
・基本的なやり方で作成した影もそうなのですが、半透明の影は作れません。真っ黒などの不透明色しか使えません。
・基本的なやり方の影に比べさらに処理が複雑になるので、処理が重くなることが予想されます。
また、ボーンを操作するのでモーションにも影響が出そうです。
と言うわけですので、影が無いとゲームが成立しないなど、どうしても影がなければいけない
という場合以外は使わないほうがいいように思います。