Three.js 影の描画(シャドウマッピング)
今回は、Three.jsの「影」について、書きます。
今回の内容は「シャドウマッピング」と専門的には言うのかな?
Three.jsの場合、影をつけるには、4つの準備が必要です。
- レンダラー・・・shadowMapEnabled = true
- 光源・・・castShadow = true
- 物体1・・・castShadow = true
- 物体2(地面など)・・・receiveShadow = true
この4つのオブジェクトのプロパティに「影(シャドウマッピング)の有効化」を設定する必要があります。
ややこしいのが物体の影の設定です。
影を受ける物体には、「receiveShadow = true」にして、影を作る物体には、「castShadow = true」にします。
写真で、解説するとこんな感じです。
写真の場合だと、影を作っているのは、青い球です。なので青い球に「castShadow = true」を設定します。地面であるピンク色の物体は、影を受けているので、「receiveShadow = true」を設定します。
地面は「receiveShadow = true」、それ以外の物体は「castShadow = true」と覚えとくと、いいと思います。
で、実際のコードはコチラです。
①レンダラー
//レンダラーオブジェクトの生成 var renderer = new THREE.WebGLRenderer({antialias: true}); //影の有効化(レンダラー) renderer.shadowMapEnabled = true;
②光源
//光源(DirectionalLight)の生成 var light = new THREE.DirectionalLight(0xcccccc,1.6); //影の有効化(光源) light.castShadow = true;
③物体1
//球の生成 var sphere = new THREE.Mesh( new THREE.SphereGeometry(50, 100, 100), new THREE.MeshPhongMaterial({ color: 0x0000ff })); //影の有効化 sphere.castShadow = true; //シーンオブジェクトに追加 scene.add(sphere);
④物体2
//地面(PlaneGeometry)の生成 var plane = new THREE.Mesh( new THREE.PlaneGeometry(1000, 1000, 1, 1), new THREE.MeshLambertMaterial({ side: THREE.DoubleSide, color: 0xCD5C5C })); //影の有効化 plane.receiveShadow = true; //シーンオブジェクトに追加 scene.add(plane);
実行すると、こんな感じです。
で、上の影をよく見ると、少しギザギザです。
もっと綺麗に影を描画する方法は、このようにします。
//DirectionalLight var light = new THREE.DirectionalLight(0xcccccc,1.6); //影の有効化 light.castShadow = true; //影の高細密化 light.shadowMapWidth = 2048; //追加 light.shadowMapHeight = 2048; //追加
光源を生成している所に、「shadowMapWidth」と「shadowMapHeight」を追加すれば、綺麗な影が描画されます。
実行すると、こうなります。
綺麗な影が出ています。
デフォルトでは、「shadowMapWidth」と「shadowMapHeight」は、それぞれの値は「512」となっています。
「shadowMapWidth」と「shadowMapHeight」の値が大きいほど、処理は重くなります。当然ですが(笑)
最後に、影を受けるのは、地面だけでは、ありません。
他の物体も影を受ける時があります。
上の写真のように、「赤色の球の影」を「青い球」が受けています。(赤色の枠線で囲った所です。)
このようにするには、青い球に「receiveShadow = true」を追加すれば、出来ます。
実際のコードは、これです。
//青い球の生成 var sphere = new THREE.Mesh( new THREE.SphereGeometry(50, 100, 100), new THREE.MeshPhongMaterial({ color: 0x0000ff })); //影の有効化 sphere.castShadow = true; sphere.receiveShadow = true; //追加 //シーンオブジェクトに追加 scene.add(sphere); //赤い球の生成 var sphere2 = new THREE.Mesh( new THREE.SphereGeometry(50, 100, 100), new THREE.MeshPhongMaterial({ color: 0xFF0000 })); sphere2.castShadow = true; scene.add(sphere2); //地面(PlaneGeometry)の生成 var plane = new THREE.Mesh( new THREE.PlaneGeometry(1000, 1000, 1, 1), new THREE.MeshLambertMaterial({ side: THREE.DoubleSide, color: 0xCD5C5C })); //影の有効化 plane.receiveShadow = true; //シーンオブジェクトに追加 scene.add(plane);
Three.jsの影は、今回書いたこと以外にも、細かい設定が色々あります。
その辺は、また今度書きます。
これで終わりです。
ご不明な点などがありましたら、遠慮なくご質問ください。
ありがとうございました!