web-dev-qa-db-ja.com

Three.JSで指向性ライトシャドウを作成する方法

DirectionalLightからシャドウを作成することはできますか?

SpotLightを使用すると影が表示されますが、DirectionalLightを使用すると機能しません。

23
eqiproo

はい、間違いなくcan指向性ライトを使用して影を落とします。シャドウをサポートしていないため、MeshBasicMaterialを使用していないことを確認する必要があります。代わりにMeshLambertMaterialまたはMeshPhongMaterialを使用してください。

次の線に沿って、レンダラーのシャドウを有効にする必要があります。

renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;

renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;

renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.5;
renderer.shadowMapWidth = 1024;
renderer.shadowMapHeight = 1024;

そして、オブジェクトごと、およびライトごとに、シャドウキャスティングとシャドウ受信を有効にする必要があります。

dirLight.castShadow = true;
object.castShadow = true;
otherObject.receiveShadow = true;

次にifライトとオブジェクトが適切な位置に配置されます。 dirLightは、objectの影がotherObjectに対してキャストされるようにします。

[EDIT]:これがworking demo同様のことをしたい人のために。

36
Cory Gross

シャドウマップは縮尺に依存することに注意してください。単位距離が1メートルを表し、オブジェクトのサイズが約0.4メートルあるシーンで作業しています。これは、Three.js標準ではかなり小さいものです。この状況にも該当する場合は、いくつかの重要な手順を実行できます。

  • シーンの寸法を考慮して、シャドウカメラのニア/ファープレーンが妥当であることを確認してください。
  • シャドウカメラの上部/左/下部/右の値が大きすぎないことを確認します。そうでない場合、各シャドウの「ピクセル」が非常に大きくなるため、シーン内のシャドウに気付くことさえありません。

これを行う方法を見てみましょう。

デバッグ中

CameraHelper を使用して、ライトごとのデバッグレンダリングを必ずオンにしてください。

scene.add(new THREE.CameraHelper(camera)) 

または、Three.jsの古いバージョン:

light.shadowCameraVisible = true;

これにより、シャドウが計算されているボリュームが表示されます。以下はその例です。

近い平面と遠い平面(黒い十字)と、シャドウカメラの上部/左/下部/右(黄色のボックスの外壁)に注意してください。シャドウ—おそらくここで示しているよりもさらにタイトです。

コード

以下は、役に立つかもしれないコードの一部です。

var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 2, 2);
light.target.position.set(0, 0, 0);
light.castShadow = true;
light.shadowDarkness = 0.5;
light.shadowCameraVisible = true; // only for debugging
// these six values define the boundaries of the yellow box seen above
light.shadowCameraNear = 2;
light.shadowCameraFar = 5;
light.shadowCameraLeft = -0.5;
light.shadowCameraRight = 0.5;
light.shadowCameraTop = 0.5;
light.shadowCameraBottom = -0.5;
scene.add(light);

一部のオブジェクトが影を落とすことを確認します。

object.castShadow = true;

一部のオブジェクトが影を受け取ることを確認します。

object.receiveShadow = true;

最後に、WebGLRendererにいくつかの値を設定します。

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
50
Drew Noakes