★2013年5月8日訂正
この回にはかつて、
シャドウマップと面のカリングに関する内容が書いてあったのですが、
なんか間違っていたので削除しました(^_^;)

デプスマップを作る際にカリング無しでやってみると、
床に落ちる影がうまく行くように見えていたため、
この方法で良いと思い込んでしまっていました。

正しくは、
こちらのページで解説されているように、
「背面ポリゴンを描画するようにしているのは,影の領域がオブジェクトの(光源に対する)背面から始まるようにするためです.こうしないと影の領域がオブジェクトの光の当たっている面と重なってしまい,影が日向の領域にはみ出てしまうことがあります」
ということのようです。

こちらのページの図も参照すると理解しやすい感じです。

要するにおもての面をカリングしてデプスマップを作るのが正解、
ということのようです。
three.js でのデフォルトのままで良かったのですね。

ただ、
何故か結果が変なんですよねー。
ミクさんのモデルは、スカートや袖の内側とか
ポリゴンが貼られてない所があるため、
これが影響しているくさいんですが、
どうもうまい解決法が思いつかない・・・嗚呼

前回の続きです。
セルフシャドウがオカシイ感じの件ですが、
改善できました。

アレのせいかも、
と薄々感じてはいたのですが、
やはりアレのせいでした(^_^;)

順を追って書いてみます。

さて、
ミクさんのモデルは、スカートや袖の内側とか
ポリゴンが貼られてない所があるため、
普通にレンダリングするとその部分が透けてしまいます。
その状況はこちらで確認できます。
ただ、こちらで書いたように
edge処理による裏面描画で自動的にうまく行くようになっています。

ところがシャドウマップではこのことが問題となっていました。
光源から視た深度マップを作成する際、
モデルの裏面は除外(Culling)して処理します。
視点から見えない裏面を対象にするのは無駄なので当然な処理なわけですが、
ミクさんのモデルの場合はポリゴンが貼ってなくて
透けてしまう部分があるため
不自然な深度マップが出来てしまっていたのです。

そこで、
THREE.ShadowMapPlugin を改造して、
オブジェクト単位にCullingを無効にできるようにしました。
本来は対象にしなくても良い「面」についても描画することになるため、
処理的には冗長になってしまうのですが、仕方ありません。
以下の様な感じに改造しました。

THREE.ShadowMapPlugin = function ( ) {
	.
	.
	this.update = function ( scene, camera ) {
		.
		.
		_gl.enable( _gl.CULL_FACE );
		_gl.frontFace( _gl.CCW );
		if ( _renderer.shadowMapCullFrontFaces ) {
			_gl.cullFace( _gl.FRONT );
		} else {
			_gl.cullFace( _gl.BACK );
		}
		.
		.
		// render depth map
		for ( i = 0, il = lights.length; i < il; i ++ ) {
			.
			.
			// render regular objects
			for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
				webglObject = renderList[ j ];
				if ( webglObject.render ) {
					object = webglObject.object;
					.
					.

					// ADD
					if (object.shadowMapCullDisable) {
						_gl.disable( _gl.CULL_FACE );
					} else {
						_gl.enable( _gl.CULL_FACE );
					}

					if ( buffer instanceof THREE.BufferGeometry ) {
						_renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
					} else {
						_renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
					}
					.
					.

ちなみに、

material.side = THREE.DoubleSide;

とやるとモデルのマテリアルを両面ポリゴン化することができるので、
これをやればCulling無効と同じになるはずと思って
やってみたのですがうまく行きません。
調べてみたらShadowMapPluginでは深度マップを生成するために、
専用のマテリアルが使用されていました。
(普通に考えれば、こういう実装になるよね)
つまりモデル側のマテリアルは無視されることになるので、
両面ポリゴン化しても効果はないわけです。
いいアイデアと思ったんですが、
そうは問屋がおろさない、ですね(^_^;)

ということで、
改善されたセルフシャドウなミクさんはこちらです。

諸般の事情でちょっとローディングに時間がかかりますが、しばらく待ってみてください。なお、ChromeなどのWebGL対応のブラウザで見てください。PCパワーもそれなりに必要となるかもしれません。あまりにも時間がかかり過ぎるようならば、リロードして再度試してみてください。

コメントする

メールアドレスが公開されることはありません。が付いている欄は必須項目です。