Three.js で始める シャドーイング

シャドーイングとは、影をつけるという事。

影があるだけで、
物体をより立体的に捉えやすくなる。

浮いようなものであれば、浮いている事がはっきりとわかる。

それは、我々人間が日々の暮らしの中で、影はこうやって出来るものという体験の記憶があるために、
影をみるだけでこう行った立体物であるはずだと脳が無意識のうちに補完してくれるためである。

シャドーイングの有効化

シャドーイングを有効にする為には、
下記のそれぞれのThree.jsのオブジェクトに影を描画する事、影を生成する対象である事などを設定する必要がある。

デフォルトで全てが有効になっているのではなく、必要なものに設定していく必要がある。

影の描画は計算が膨大になるため、省略出来るところは省いておいた方が良い。

各オブジェクトの影描画機能を有効化する。

  • レンダラー (shadowMap=true)
  • 光源 (castSadow=true)
  • 影生成元 (castShadow=true)
  • 影描画先 (receiveShafow=true)
// レンダラー
let renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;

// 光源
let light = new THREE.DirectionalLight(0xFFFFFF, 0.8);
light.castShadow = true;

// 影生成元
let cube = new THREE.Mesh(new THREE.BoxGeometry(3, 3, 3), new THREE.MeshLambertMaterial());
cube.castShadow = true;

// 影描画先
let floor = new THREE.Mesh(new THREE.PlaneGeometry(50, 50), new THREE.MeshLambertMaterial());
floor.receiveShadow = true;

castShadowとreceiveshadowは両方trueに設定する事もできる。
たとえば、cubeが沢山並んでいる場合に、cube1からの影がcube2に描かれるなどの場合、
cube2から、影は伸びるし、cube1からの影が描画される対象でもある。

シャドーカメラの設定

シャドーカメラとは、
カメラに投影されていない領域を影として処理する技法。

光源オブジェクトのshadow.cameraプロパティに保持されている。

このカメラ設定が
デフォルトでは小さすぎる為、以下のように設定しておく。

let light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
light.position.set(30, 100, 20);
light.castShadow = true;

// シャドウカメラの領域設定
light.shadow.camera.position.set(0, 100, 0);
light.shadow.camera.left   = -30;
light.shadow.camera.right  = 30;
light.shadow.camera.top    = 30;
light.shadow.camera.bottom = -30;
scene.add(light);

// カメラヘルパーで領域を可視化できる。
let cameraHelper = new THREE.CameraHelper(light.shadow.camera);
scene.add(cameraHelper);

このカメラの領域をイメージする事は難しいため、Three.js には可視化する為のヘルパークラスが用意されている。
ヘルパーを生成して、シーンに追加しておくだけで、このシャドーカメラの領域がフワイヤーレームで可視化できる。
イメージしやすくなるので、一度ヘルパーを使って可視化しておくと良いだろう。

レンダラーの設定

レンダラーには、シャドーマップのサイズと、フィルタリングを選択する事ができる。

シャドーマップ

シャドーカメラの領域内での解像度、
サイズを増やす事で、高精細の影をつくることがかのう。

同じサイズのまま、シャドーカメラの領域を広げると、バッファサイズは増えない為に、引き伸ばされる形で描画される。

フィルタリング

renderer.shadowMap.type に影の描画方法を設定する事ができる。

  • THREE.BasicShadowMap
  • THREE.PCFShadowMap
  • THREE.PCFSoftShadowMap

THREE.BasicShadowMap

影の有る無しの2値化のみで描画をおこなう。
境界線がギザギザになってしまうので、綺麗に描画する為にはシャドーマップの解像度を上げる必要がある。
単純な描画のため、一番描画速度が早い。

THREE.PCFShadowMap

何も設定しない場合に、Three.js ではデフォルトとなっている。
ぼかしのようなもので、影の面積割合から描画色を決定する。

THREE.PCFSoftShadowMap

上記の、PCFShadowMap の結果から更に、隣り合う影との間を線形補間して描画する。

コメントを残す