Three.js で多粒子のアニメーションの勉強中。
その際、どうやっても 影 が表示されずに困ったのでメモまで。
以下のサイトでもハマリどころが紹介されているが、今回は別の原因だった。
- [WebGL] Three.jsで影を表示する
- Three.js 影ができない原因
ライトの影設定
Lightオブジェクトの影設定 castShadow
をOnにする。
デフォルトではOff (false) になっている。
var light = new THREE.DirectionalLight(0xFFFFFF);
light.position.set(0, 0, 1000);
light.castShadow = true; // これ!!
scene.add(light);
あと、基本ですが、Lightの位置も念のため確認しておく。
床面に影を出したい場合、
- ライト -> 物体 -> 床
の順になっていないと、当然影は出ない。
物体の影設定
これも明示的にOn (true) にしておくのがよい。
var cubeObj = new THREE.Mesh(
new THREE.CubeGeometry(10,10,10),
new THREE.MeshLambertMaterial({color: 0xff0000, ambient:0xFF0000}));
cubeObj.castShadow = true; // これ!
scene.add(cubeOjb);
床面の影設定
こちらは影の受け手 (描画される方) としての設定をOnにする。
var plane = new THREE.Mesh(new THREE.PlaneGeometry(100, 100, 5, 5),
new THREE.MeshLambertMaterial({color: 0x999999, ambient:0x050505}));
plane.receiveShadow = true; // これ!
Rendererの影設定
Rendererにも影設定がある。何個あるねん...
var renderer = new THREE.WebGLRenderer({antialias: true});
:
renderer.shadowMapEnabled = true; // これ!
ちなみに、最新のThree.js (執筆時はr73) では、shadowMapEnabled
から shadowMap.enabled
に置き換わった模様。shadowMapEnabled
だと置き換える旨のWarningがログ出力される。
renderer.shadowMap.enabled = true;
ShadowMapの設定
上述のところまでやると大抵の場合は影が出るはず。
なのに影が出ない...
今回、多粒子のサンプルを作っていたが、一個一個のオブジェクト(Sphere) のサイズが小さい場合、デフォルトのライト設定だと影が表示されなかった。
オブジェクトのサイズは変えたくない場合、以下のようにライトの影設定を変更するとよい。
var light = new THREE.DirectionalLight(0xFFFFFF);
light.position.set(0, 0, 1000);
light.shadowMapWidth = 2048; // これ!
light.shadowMapHeight = 2048; // これ!
light.castShadow = true;
scene.add(light);
shadowMapWidth
および shadowMapHeight
のデフォルト値は 512
。
どのぐらいのオブジェクトサイズで、どのぐらいの値がよいかは、表示したい影の質感と相談で決めるとよい 。