Appearance
影を表示する方法
影の描画は処理が重いため、デフォルトではオフになっています。 影を表示するには、以下の4つの設定をすべて行う必要があります。
view.setShadowMap(true);— Viewの影の描画を有効にするlight.setLightShadow(true,opt);— ライトが影を作るようにするobj.setCastShadow(true);— オブジェクトが影を落すようにするfield.setReceiveShadow(true);— 床などが影を受けて描画する ようにする
どれか1つでも欠けると影は表示されません。以下のサンプルで 4つの設定がそろった状態を確認できます(ライトが動くのに合わせて 影も動きます)。
js
import * as a3 from 'a3js';
const view = new a3.Window(600,300);
view.camera.setHeadLight(false);
view.camera.setPosition(0,2,5);
view.camera.lookAt(0,0,0);
view.setShadowMap(true); // (1) Viewの影の描画を有効化
const light = new a3.StandardLights();
const opt = {left:-5,right:5,top:5,bottom:-5};
light.setLightShadow(true,opt); // (2) ライトが影を作るようにする
view.scene.add(light);
const field = await new a3.GLTF('/a3js/assets/grass-ground2.glb').ready;
field.setReceiveShadow(true); // (3) 地面が影を描画するようにする
view.scene.add(field);
const obj = new a3.SampleObject();
obj.setCastShadow(true); // (4) オブジェクトが影を落すようにする
obj.setPositionNow(0,2,0);
view.scene.add(obj);
light.setDebugMode(true); // 影の計算に使うカメラの範囲を表示
// ライトを動かすと影も動く
let t = 0;
while (true) {
t += await view.waitForRender();
light.setPosition(Math.cos(t),1,Math.sin(t));
}View.setShadowMap()
Viewのレンダラが影の計算(シャドーマップ)を行うようにします。 影を使うページ全体のスイッチです。なお、上のサンプルでは ヘッドライトの光が影の表示の邪魔をしないようにヘッドライトを 消して、代わりにStandardLightsを 使っています。
ObjectA3.setLightShadow()
ライトを含むオブジェクトに対して「このライトが影を作る」ことを 設定します。第2引数のオプションで、影の計算に使うカメラの範囲と シャドーマップの解像度を指定できます。
left/right/top/bottom— DirectionalLight(平行光)の場合の 影を計算する範囲。デフォルトは±20。angle— SpotLightの場合の角度。デフォルトはMath.PI/6。near/far— 影を落とせる距離の範囲。デフォルトは0.1〜100。shadowMapWidth/shadowMapHeight— シャドーマップの解像度。 デフォルトは1024×1024。
範囲を広くしたのに解像度がそのままだと影の輪郭が粗くなり、 解像度を上げると処理が重くなります。影を計算する範囲は 必要最小限にするのがきれいで速い影のコツです(上のサンプルでは ±5に絞っています)。
範囲の調整にはlight.setDebugMode(true);が便利です。影の計算に 使われるカメラの範囲が表示されるので、「影が途中で切れる」ときは この範囲からはみ出していないか確認してください(詳しくは その他の機能)。
上のサンプルでもデバッグ表示をONにしてあります。表示される範囲と 影の関係をよく観察すると、ライトが動いてnearの境界(範囲の ライト側の面)がオブジェクトにかかったときに、影の表示が 影響を受ける様子もわかります。left/right/top/bottom だけでなくnear/farも影が正しく出る範囲を決めていることを 確認してみてください。
ObjectA3.setCastShadow()
そのオブジェクトが影を落すようにします。中に含まれる全ての メッシュに設定が適用されます。
ObjectA3.setReceiveShadow()
そのオブジェクトの表面に、他のオブジェクトの影が描画される ようにします。地面や床、壁などに設定します。
なお、1つのオブジェクトにsetCastShadow(true)と setReceiveShadow(true)の両方を設定することもできます (自分も影を落し、他の影も受ける)。
詳細はAPIドキュメントを 参照してください。