Three.jsをはじめよう。深みとドラマを与えるライティング技術【第4回】

前回、「マテリアルとテクスチャ」を学び、物体にリアルな質感を与える方法を身につけました。しかし、今のあなたの作成した画面を見てみてください。せっかく綺麗に作った物体も、どこかその空間から浮いているように感じませんか?(浮いてはいますが…)

その違和感の正体は、現実世界には必ず存在する光の偏りや影の欠如です。3Dの世界において、光は単に物を明るくするだけでなく、空間の広がりや、物体の重み、そしてサイト全体の「雰囲気」を作り出すディレクターの役割を果たします。

「影がうまく出ない」「ライトを置いたら色が白飛びしてしまった」……。これらは誰もが通る道です。第4回となる今回は、そんなライティングの悩みを解決し、本物感がある空間演出の秘密を一緒に紐解いていきましょう。

空間を彩る4つの「光」を使い分ける

前回質感を感じてもらう為に登場はさせてしまいましたが、今回はそのライトの中から基本となるこの4つを紹介します!
この4つを覚えれば、ほとんどのシーンに対応できます。

AmbientLight(環境光)

スタジオ全体をぼんやりと照らす、太陽の照り返しのような光です。

役割
影を完全に真っ黒にしないための「底上げ」の光。
特徴
どこからでも均一に照らすため、これだけだと立体感は出ません。
コツ
強すぎると色がぼやけるため、控えめ(強度0.2〜0.5程度)に設定するのがセオリーです。

DirectionalLight(平行光源)

太陽のように、非常に遠くから平行に降り注ぐ光です。

役割
メインの照明。はっきりとした影を作ります。
特徴
位置ではなく「向き」が重要になります。
使い所
屋外のシーンや、製品をパキッと明るく見せたいときに最適です。

PointLight(点光源)

電球やロウソクのように、一点から全方向に広がる光です。

役割
特定の場所を強調するアクセント。
特徴
距離が離れるほど光が弱まります。
使い所
空間に奥行きを出したり、製品の特定のパーツを際立たせたい時に使います。

SpotLight(スポットライト)

懐中電灯のように、特定の方向へ円錐状に広がる光です。

役割
舞台演出のような、ドラマチックな強調。
特徴
光の広がる角度や、エッジのぼかし具合(半影)を調整できます。

影を出すための3つの設定

さて、ここが本番です。Three.jsで影を出すには、ちょっとした設定が必要です。なぜなら、影の計算はパソコンにとって非常に重い処理であるため、デフォルトでは「オフ」になっているからです。

設定1:レンダラーの許可

まず、映写機であるRendererに「影を計算してもいいよ」と許可を出します。

renderer.shadowMap.enabled = true;

設定2:ライトの許可

次に、光側に「この光は影を作る光だよ」と教えます。

directionalLight.castShadow = true;

※ AmbientLight は全方向からの光なので影は作れません。

設定3:物体の許可

最後に、物体一つひとつに役割を与えます。

mesh.castShadow = true;// 影を落とす側
mesh.receiveShadow = true;// 影を受ける側(床など)

「影が出ない!」と悩んだときは、この3つの設定が漏れていないか確認してみましょう。

影のクオリティを上げる

設定はできたけれど、影が「カクカクしている」あるいは「一部が欠けている」といった問題に直面することがあります。これは制作現場でも起こる調整作業です。

影の解像度(MapSize)を上げる

デフォルトの影は解像度が低いため、カクカクして見えます。これを美しくするには、設定を書き換えます。

sunLight.shadow.mapSize.set(2048, 2048);// 2の累乗を指定

影の範囲(Camera Helper)を最適化する

影を作るライトには、実は内部的に「影専用のカメラ」が備わっています。このカメラに映っていない範囲には影が出ません。

開発中は CameraHelper を使って、影の範囲が正しく物体を包んでいるかを確認しましょう。

const helper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(helper);

実際に「ライティング」をコードで書く

では、第3回までの球体と床を、美しく照らしてみましょう。

// --- 1. 環境光で全体のトーンを整える ---
const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);

// --- 2. メインの太陽光を追加して影を落とす ---
const sunLight = new THREE.DirectionalLight(0xffffff, 1.0);
sunLight.position.set(5, 5, 5);
sunLight.castShadow = true;

// 影の品質を高める設定
sunLight.shadow.mapSize.set(2048, 2048);
sunLight.shadow.camera.left = -5;
sunLight.shadow.camera.right = 5;
sunLight.shadow.camera.top = 5;
sunLight.shadow.camera.bottom = -5;

scene.add(sunLight);

// --- 3. 物体の設定 ---
// 球体(影を落とす)
sphere.castShadow = true;

// 床(影を受ける)
const floor = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10),
    new THREE.MeshStandardMaterial({ color: 0x888888 })
);
floor.rotation.x = -Math.PI * 0.5; // 水平に寝かせる
floor.receiveShadow = true;
scene.add(floor);

サイトを重くしないための節約術

最後に、WEB制作において最も重要な「パフォーマンス」の話をします。 3D空間を明るくしようとしてライトをたくさん追加すると、ブラウザはどんどん重くなり、スマホで見た時にカクついてしまいます。

ライトの数を絞る

基本は「3灯ライティング(メイン、サブ、バック)」に留めるのが理想です。

影を落とすライトは1つにする

すべてのライトに castShadow = true を設定するのは厳禁です。最も印象的な影を一つだけ選び、他は補助光として使いましょう。

焼き付けという選択肢

動かない背景などの影については、リアルタイムで計算するのではなく、あらかじめ画像(テクスチャ)に影を書き込んでしまう手法もあります。これは高度なテクニックですが、サイトの高速化には絶大な効果があります。

今回のまとめと次回のステップ

お疲れ様でした!今回のステップを終えて、Three.jsの制作物に確かな「重み」と「リアリティ」が生まれたはずです。 光と影は、WEBサイトにおいてブランドの「品格」を伝える言葉以上のメッセージになります。

今回の学びのポイント

ライトの種類
Ambient(全体), Directional(太陽), Point(電球), Spot(演出)。
影を作る
Renderer・Light・Mesh、すべてに許可が必要。
影の調整
MapSizeとCamera範囲で美しさをコントロールする。
最適化
美しさのために、あえて「光を絞る」勇気。

さて、これまでは立方体や球体といった単純な形を扱ってきましたが、次はもっと複雑なものを扱ってみましょう。

次回、第5回では、Blenderなどの3Dソフトで作られた「外部モデル(GLTF/GLB)」の読み込みに挑戦します。いよいよ、本物の3DアセットがWEBサイト上で動き出します!

「自社の製品を、光の演出にこだわったリッチなサイトで見せたい」という想いがあれば、ぜひ私たちのチームにご相談ください。技術と感性で、心を動かすWEB体験を共に作り上げましょう。

それでは、また次回!