意外と設定がめんどくさいのでメモとして残しておきます。
ちなみに、実際に動作するデモをjsdo.itに上げてあります。
影の有効化
enabled-shadow
///////////////////////////////////////////////////////////////////////
// 各種、shadowのレンダリングに必要な設定を有効化
// ライトの影表示を有効化
light.castShadow = true;
// Boxの影を有効化
box.castShadow = true;
// 地面の影を受ける設定を有効化
plane.receiveShadow = true;
// レンダラーの影レンダリングを有効化
renderer.shadowMapEnabled = true;
ライトとレンダラの影設定は必須
影をレンダリングするには、いくつかのオブジェクトの設定を有効化する必要があります。
まず必要なのがライトとレンダラの設定です。
light.castShadow = true
とrenderer.shadowMapEnabled = true
の部分ですね。
このふたつは、オブジェクトがどうであれ設定が必要です。
影をレンダリングしたいオブジェクトの影を有効化
次に必要なのがオブジェクトごとの設定です。
ここで注意しないといけないのが、「影を落とす」ことと「影を受ける」ことは別物、ということです。
なのでそれぞれanObject.castShadow
(影を落とす)とanObject.receiveShadow
(影を受ける)を個別に設定する必要があります。
つまり、影を落とすが影を受けない、というようなことも設定可能、ということです。
コード全文
とりあえず動くコードを全文載せておきます。
ちなみに以下のコードはThree.jsのr70で動作確認しています。
が、基本的な考え方はどのバージョンでも同じです。
shadow-on-threejs
(function () {
'use strict';
// カメラ作成
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(100, 150, 300);
// シーンを作成
var scene = new THREE.Scene();
// ライトを作成
var light = new THREE.DirectionalLight(0x999999);
light.position.set(100, 100, 100);
// Boxを作成
var box = new THREE.Mesh(
new THREE.BoxGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({
color: 0xaa0000
})
);
// 地面用のPlaneを作成
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(1000, 1000, 10, 10),
new THREE.MeshLambertMaterial({
color: 0xdddddd
})
);
plane.position.y = -150;
plane.rotation.x = -Math.PI / 2;
// レンダラーを作成
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0xffffff);
renderer.setSize(window.innerWidth, window.innerHeight);
// 各種オブジェクトをシーンに追加
scene.add(light);
scene.add(box);
scene.add(plane);
camera.lookAt(box.position);
///////////////////////////////////////////////////////////////////////
// 各種、shadowのレンダリングに必要な設定を有効化
// ライトの影表示を有効化
light.castShadow = true;
// Boxの影を有効化
box.castShadow = true;
// 地面の影を受ける設定を有効化
plane.receiveShadow = true;
// レンダラーの影レンダリングを有効化
renderer.shadowMapEnabled = true;
////////////////////////////////////////////////////////////////////////
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
}());