はじめに

Three.js で複数のライトの実装を試してみたので、記事にまとめておきます。

スポットライトを使うと暗闇の中、キャラクター座標を追従して明かりを照らすような事も可能です。

複数のライト

Three.js では、複数の光源を使ってシーンを照らすことができます。一般的な光源には以下の種類があります。

  1. 環境光(AmbientLight): シーン全体に均等に光を当てます。陰影を作ることはありませんが、暗いシーンで全体に少し明るさを加えるために使用されます。
  2. 平行光源(DirectionalLight): 特定の方向から光が平行に照射されます。太陽光のような効果を作ることができます。
  3. スポットライト(SpotLight): 光の範囲を特定の角度に制限し、スポットを当てるように照らす光源です。焦点を合わせることができ、シャドウにも対応しています。
  4. 点光源(PointLight): 点から放射される光です。全方向に光が広がり、距離に応じて光の強さが減衰します。

これらを組み合わせてシーンを照らすことができます。

1. 環境光(AmbientLight)

AmbientLight は、Three.js の光源の一つで、シーン全体に均等に光を与える効果があります。AmbientLight は、特に他の光源(例えば、DirectionalLight や PointLight)と組み合わせて使用することで、シーンをより自然に照らすことができます。

環境光の基本的な設定

AmbientLight の最も基本的な使い方は、色と強度を設定することです。

const ambientLight = new THREE.AmbientLight(0x404040, 0.5);  // 色と強度を指定
scene.add(ambientLight);
  • color: 照らす光の色を指定します。ここでは、0x404040(グレーっぽい色)を使っていますが、任意の色を設定できます。
  • intensity: 光の強度を設定します。0 は光を全く当てない状態で、1 は最大の強度です。

環境光の効果

AmbientLight は、シーン全体に均等に光を当てるため、暗いシーンやシャドウが目立つ部分に対して補完的な光源として非常に便利です。ただし、AmbientLight 単体ではシャドウや光の強弱を作ることができません。そのため、他の光源と組み合わせることが推奨されます。

複数の環境光を使う

複数の環境光をシーンに追加することも可能ですが、通常は1つの環境光を使うことが一般的です。異なる強度や色の環境光を使って、シーンに複数の光源が影響するようにすることもできます。

const ambientLight1 = new THREE.AmbientLight(0x404040, 0.3);  // 弱い環境光
const ambientLight2 = new THREE.AmbientLight(0x808080, 0.7);  // 強い環境光
scene.add(ambientLight1);
scene.add(ambientLight2);

これで、シーン全体が均等に明るくなり、ライトが当たっていない部分でも、若干の光が当たるようになります。

注意点

  • AmbientLight のみではシャドウや光の強弱を作ることはできません。シャドウを作りたい場合は、DirectionalLight や PointLight を追加する必要があります。
  • intensity を適切に調整して、シーンが過剰に明るくならないように注意しましょう。強すぎる環境光は、他の光源の効果を弱めてしまいます。

2. 平行光源(DirectionalLight)

DirectionalLight は、Three.js の光源の一つで、一方向から光を平行に照射する光源です。主に、太陽光のようにシーン全体に均等に光を当てる役割を果たします。AmbientLight と異なり、DirectionalLight はシャドウを作ることができ、ダイナミックな照明効果をシーンに追加します。

平行光源の基本的な設定

DirectionalLight を使うには、色と強度を設定し、光源の位置を指定します。position を設定することで、光がシーン内でどの方向から照射されるかを決めます。

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);  // 色と強度を指定
directionalLight.position.set(5, 10, 5);  // 光源の位置を設定
scene.add(directionalLight);
  • color: 光の色を指定します。ここでは、0xffffff(白)を指定していますが、0xff0000(赤)や 0x00ff00(緑)など、任意の色を設定できます。
  • intensity: 光の強度を設定します。1 が標準の強度で、値が大きいと強い光になります。

平行光源の向き(ターゲット設定)

DirectionalLight は、光源の位置だけでなく、光がどの方向を照らすかを決めるターゲットを設定することもできます。ターゲットの位置を変更することで、照射方向を変えることができます。

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 5);  // 光源の位置
directionalLight.target.position.set(0, 0, 0);  // 照らすターゲットを設定
scene.add(directionalLight);
scene.add(directionalLight.target);  // ターゲットをシーンに追加

ターゲットは THREE.Object3D オブジェクトで、ターゲットの位置を指定することで、平行光源がどの方向を照らすかを決定します。

平行光源の影の設定

DirectionalLight では、光源がシャドウを落とす設定を追加することができます。castShadowtrue に設定することで、光源から照射された光が、シーンの物体に影を落とすようになります。

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 5);
directionalLight.castShadow = true;  // シャドウを落とす
scene.add(directionalLight);

また、影の描画設定をさらにカスタマイズするためには、shadow プロパティを使って、シャドウの詳細な設定を調整することができます。

directionalLight.shadow.mapSize.width = 512;  // シャドウマップの解像度を設定
directionalLight.shadow.mapSize.height = 512;
directionalLight.shadow.camera.near = 0.5;   // シャドウが描画される近距離
directionalLight.shadow.camera.far = 50;     // シャドウが描画される遠距離

複数の平行光源を使用する場合

複数の光源を使ってシーンを照らすことも可能です。DirectionalLight を複数作成し、シーン内で異なる方向から光を当てることができます。

const directionalLight1 = new THREE.DirectionalLight(0xff0000, 1);
directionalLight1.position.set(5, 10, 5);  // 光源1の位置
scene.add(directionalLight1);

const directionalLight2 = new THREE.DirectionalLight(0x0000ff, 1);
directionalLight2.position.set(-5, -10, -5);  // 光源2の位置
scene.add(directionalLight2);

これにより、シーン内に異なる方向から光を照射することができ、より立体的でダイナミックなライティングを作ることができます。

DirectionalLight は、太陽光のように平行光線をシーンに当てる光源です。シーン全体に均等に光を与え、シャドウを作ることもできるため、照明効果として非常に強力です。ターゲットを設定することで、光源の照射方向を変更でき、複数の光源を使うことで、より複雑で立体的なシーンを作成できます。

ポイント:

  • DirectionalLight は平行光源で、指定した位置から光を照射します。
  • ターゲットを設定して、照射方向を指定できます。
  • シャドウを設定することで、シーンにリアルな影を追加できます。
  • 複数のDirectionalLight を使って、異なる方向から光を照射できます。

3. スポットライト(SpotLight)

SpotLight は、Three.js の光源の一つで、特定の方向と範囲に光を集中的に照射するための光源です。スポットライトは、焦点を合わせることができ、角度、距離、強度、減衰などを設定できるため、シーン内で注目するべき対象を照らす際に使われます。例えば、スポットライトを使うことで、舞台のライトやヘッドライトのような効果を作成することができます。

スポットライトの基本的な設定

スポットライトの基本的な作成方法は次の通りです。色、強度、距離、角度などを指定して、シーンの中に光を追加します。

const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 4, 0.1, 1);
spotLight.position.set(10, 10, 10);  // 光源の位置
scene.add(spotLight);
  • color: 照射する光の色を設定します。0xffffff(白)を指定していますが、任意の色を使うことができます。
  • intensity: 光の強度を設定します。値が大きいと、光が強くなります。
  • distance: 光が届く最大の距離を設定します。これを設定することで、光が届く範囲を制限できます。
  • angle: 光の照射角度を設定します。ここでは Math.PI / 4(45度)に設定しており、光が広がる範囲を指定します。
  • decay: 光の減衰率を設定します。通常は 1 で問題ありません。

スポットライトのターゲット設定

スポットライトを使うとき、光がどこを照らすかをターゲットオブジェクトで指定することができます。target を使って、スポットライトが照らす位置を動的に変更できます。

const targetObject = new THREE.Object3D();  // 空のオブジェクトをターゲットとして使用
targetObject.position.set(0, 0, 0);  // 照らす対象を設定
spotLight.target = targetObject;  // ターゲットをスポットライトに設定
scene.add(targetObject);

ターゲットを設定することで、スポットライトはその位置を常に照らします。ターゲットは、THREE.Object3D を使って作成し、その位置を設定します。

スポットライトの影の設定

スポットライトもシャドウを落とすことができます。castShadow プロパティを使って、スポットライトから落ちる影を有効にすることができます。

spotLight.castShadow = true;  // スポットライトが影を落とす

さらに、シャドウのクオリティや範囲を調整することができます。mapSize を変更してシャドウマップの解像度を上げると、シャドウの精度が向上します。

spotLight.shadow.mapSize.width = 1024;  // シャドウマップの解像度を高くする
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 1;  // シャドウの描画開始位置
spotLight.shadow.camera.far = 50;  // シャドウの描画範囲

これで、スポットライトの影の精度を向上させ、リアルな影の描画を実現できます。

スポットライトの範囲を可視化

デバッグ用に、スポットライトがどの範囲を照らしているのかを可視化することができます。THREE.SpotLightHelper を使用して、光の範囲を確認できます。

const spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);

これにより、スポットライトの光の範囲が可視化され、光がどの部分を照らしているかを確認することができます。

複数のスポットライトを使用する場合

複数のスポットライトをシーンに追加することができます。例えば、異なる方向から光を照射するために、複数のスポットライトを作成してシーンに追加します。

const spotLight1 = new THREE.SpotLight(0xff0000, 1, 100, Math.PI / 4, 0.1, 1);
spotLight1.position.set(10, 10, 10);  // 光源1の位置
spotLight1.target.position.set(0, 0, 0);  // ターゲット1
scene.add(spotLight1);
scene.add(spotLight1.target);

const spotLight2 = new THREE.SpotLight(0x00ff00, 1, 100, Math.PI / 4, 0.1, 1);
spotLight2.position.set(-10, 10, 10);  // 光源2の位置
spotLight2.target.position.set(0, 0, 0);  // ターゲット2
scene.add(spotLight2);
scene.add(spotLight2.target);

これで、異なる方向から異なる色のスポットライトを照射し、シーンにダイナミックな照明効果を追加することができます。

SpotLight は、特定の方向に光を集中的に照射する光源で、光の強度、角度、距離、減衰を調整できます。ターゲットを設定することで、スポットライトが照らす方向を動的に変えることができ、影を落とすこともできます。SpotLight を使うことで、シーンに強い焦点を当てた光を作ることができ、映画やゲームのようなダイナミックな効果を実現できます。

ポイント:

  • スポットライトの光の強度、距離、角度、減衰を設定。
  • ターゲット設定で照らす位置を動的に変更。
  • シャドウを設定して、リアルな影を作成。
  • デバッグ用に光の範囲を可視化できる。

4. 点光源(PointLight)

次は 点光源(PointLight) の説明です!点光源は、シーン内の特定の点から全方向に光を放つ光源です。ライトがすべての方向に均等に広がり、距離に応じて光が減衰するため、非常にリアルな照明効果を作ることができます。

記事の構成例

## 4. 点光源(PointLight)

PointLight は、Three.js の光源の一つで、特定の点から全方向に光を放つ光源です。PointLight は、ライトが均等に全方向に広がるため、部屋の中のランプや街灯、ヘッドライトなど、特定のエリアを均等に照らす用途に最適です。さらに、距離に応じて光の強度が減衰する効果も持っています。

### 点光源の基本的な設定

PointLight を使うには、色、強度、距離、減衰率などを設定します。これらの設定を変更することで、光がどの範囲まで届き、どのくらいの強さで照らすかを調整できます。

```javascript
const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2);  // 色、強度、距離、減衰を指定
pointLight.position.set(10, 10, 10);  // 光源の位置を設定
scene.add(pointLight);
  • color: 光の色を指定します。0xffffff(白)を指定していますが、任意の色を設定できます。
  • intensity: 光の強度を設定します。1 が通常の強度で、値が大きいと光が強くなります。
  • distance: 光が届く最大の距離を設定します。distance を指定することで、光の範囲を制限できます。
  • decay: 光が距離に応じて減衰する度合いを設定します。decay が1だと、距離が長くなるほど光が弱くなります。

点光源の減衰効果

PointLight では、減衰(decay)を設定することで、光が届く範囲内でどの程度強さが変化するかを調整できます。減衰率を変更することで、光がどれだけ遠くまで届くか、またはどれだけ速く光が弱まるかを制御できます。

例えば、減衰を強くすると、光が遠くに届きにくくなります。

const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2);  // 光の強度、距離、減衰を指定
pointLight.decay = 2;  // 減衰率を2に設定
pointLight.position.set(10, 10, 10);  // 光源の位置を設定
scene.add(pointLight);

点光源の影の設定

PointLight もシャドウを落とすことができますが、スポットライトや平行光源に比べて、シャドウの設定が少し複雑になる場合があります。castShadow を設定して、シャドウを有効化することができます。

pointLight.castShadow = true;  // 点光源がシャドウを落とす

また、PointLight でのシャドウマップの解像度やシャドウカメラの範囲を調整することも可能です。

pointLight.shadow.mapSize.width = 1024;  // シャドウマップの解像度を設定
pointLight.shadow.mapSize.height = 1024;
pointLight.shadow.camera.near = 0.5;    // シャドウの開始位置
pointLight.shadow.camera.far = 50;      // シャドウの描画範囲

複数の点光源を使用する場合

PointLight はシーン内で複数使用することができます。例えば、部屋の中に複数のランプを配置する場合に使います。異なる位置に点光源を配置することで、シーン内の複数のエリアを均等に照らすことができます。

const pointLight1 = new THREE.PointLight(0xffffff, 1, 100, 2);
pointLight1.position.set(10, 10, 10);  // 光源1の位置
scene.add(pointLight1);

const pointLight2 = new THREE.PointLight(0xff0000, 1, 100, 2);
pointLight2.position.set(-10, 10, 10);  // 光源2の位置
scene.add(pointLight2);

これにより、異なる色や位置で複数の点光源を使い、シーン全体を均等に照らすことができます。

点光源の可視化

点光源の範囲を可視化するために、デバッグ用にTHREE.PointLightHelper を使って、光の範囲を確認することができます。

const pointLightHelper = new THREE.PointLightHelper(pointLight, 1);
scene.add(pointLightHelper);

これにより、点光源の光の範囲が可視化され、どこまで光が届いているかを確認できます。

PointLight は、特定の点から全方向に光を放つ光源で、距離に応じて光の強度が減衰する特性を持っています。主に、ランプや街灯、ヘッドライトなど、エリア全体を均等に照らすために使われます。distance と decay を適切に設定することで、光の届く範囲や減衰を調整できます。

ポイント:

  • PointLight は、全方向に光を均等に広げます。
  • 距離と減衰の設定を使って、光の強さを調整できます。
  • シャドウの設定で、点光源から落ちる影を制御できます。
  • 複数の点光源を使ってシーン全体を照らすことができます。

これで、PointLight の基本的な使い方が分かり、シーンに均等でリアルな照明効果を加えることができるようになります

5.追従型スポットライト

最後に、冒頭の動画でも紹介したキャラクターを追従して照らすスポットライトの実装方法の紹介。

以下の例では、スポットライトをキャラクターの位置に追従させる方法を示します。この方法で、キャラクターが動くたびにスポットライトがその位置に合わせて更新され、常にキャラクターを照らし続けます。

実装コード例

function createSpotLight(targetPosition) {
  if (!config.light.isSpotLight) return;

  // スポットライトの作成
  config.light.spotLight = new THREE.SpotLight(0xffffff, 1, 10, Math.PI / 4, 0.1, 1);

  // スポットライトの位置設定(光源の位置)
  config.light.spotLight.position.set(...config.light.spotLightPosition);

  // スポットライトの強度、距離設定
  config.light.spotLight.distance = config.light.spotLightDistance;
  config.light.spotLight.intensity = config.light.spotLightIntensity;

  // スポットライトのターゲット設定
  config.light.target = new THREE.Object3D();  // 空のオブジェクトをターゲットとして使用
  config.light.target.position.set(...targetPosition);  // キャラクターの位置をターゲットに設定

  // スポットライトが影を落とす設定
  config.light.spotLight.castShadow = true;

  // スポットライトの描写範囲を可視化する(デバッグ用)
  config.light.spotLightHelper = new THREE.SpotLightHelper(config.light.spotLight);
  if (config.light.isSpotLightHelper) config.scene.add(config.light.spotLightHelper);

  // シーンにスポットライトとターゲットを追加
  config.scene.add(config.light.spotLight);
  config.scene.add(config.light.target);

  // スポットライトのターゲットの方向を合わせる
  config.light.spotLight.target = config.light.target;

  // キャラクターの位置が更新されるたびに、ターゲットを移動させる
  updateSpotLightTargetPosition();
}

// キャラクターの位置にスポットライトを追従させる更新関数
function updateSpotLightTargetPosition() {
  const newPosition = [
    config.character.box.position.x,  // キャラクターの位置(X軸)
    config.character.box.position.y,  // キャラクターの位置(Y軸)
    config.character.box.position.z   // キャラクターの位置(Z軸)
  ];

  // ターゲットの位置をキャラクターの位置に合わせる
  config.light.target.position.set(...newPosition);

  // スポットライトのターゲットの位置を更新
  config.light.spotLight.target.position.copy(config.light.target.position);
}

// 例: キャラクターが移動するたびに呼ばれる更新処理
function animate() {
  // キャラクターの位置が変わったら、スポットライトも追従させる
  updateSpotLightTargetPosition();

  // 他のアニメーション処理...
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

説明

  1. スポットライトの作成: config.light.spotLight でスポットライトを作成し、位置や強度、距離などの設定を行います。

    • spotLight.position.set(...config.light.spotLightPosition) でスポットライトの初期位置を設定します。
    • spotLight.target.position.set(...targetPosition) でターゲット(キャラクター)の位置を設定します。
  2. ターゲットの追従: config.light.target はスポットライトが照らすターゲットです。キャラクターの位置が更新されるたびに、target.position.set(...newPosition) を呼び出してターゲットの位置を更新します。

  3. 更新関数: updateSpotLightTargetPosition 関数は、キャラクターの位置に合わせてスポットライトのターゲットを動かす処理です。この関数は、キャラクターが動くたびに呼ばれることを想定しています。

  4. アニメーション内での更新: animate 関数内で、キャラクターの移動に合わせて updateSpotLightTargetPosition を呼び出し、スポットライトのターゲットを更新します。

ポイント

  • config.character.box.position は、キャラクターの位置情報です。キャラクターが動くたびに、その位置にスポットライトを追従させます。
  • ターゲットの位置更新: spotLight.target.position.copy(config.light.target.position) を使って、ターゲットの位置が変更されるたびにスポットライトもターゲットを照らすように更新します。
  • 影の設定: castShadow = true を設定することで、スポットライトが影を落とすことができます。

応用

この実装を応用すれば、例えばプレイヤーが動くたびに、スポットライトがキャラクターを追いかける演出を作ることができます。スポットライトの強度や距離を変更することで、特定のエリアを明るくしたり、暗くしたりするダイナミックなライティング効果を実現できます。