Three.jsで影を表示し影のエッジをぼかす(Three.js[r145]を使用)
この記事では、影の表示方法やぼかし方を詳しく解説し、リアルな3Dシーンを作るためのポイントを紹介します。
Three.jsでシャドーマップを有効にすると影を表示することができます。
また、影のエッジをぼかすことも出来ます。
- レンダラーでシャドー(影)マップを有効にする
- renderer.shadowMap.enabled = true;
- ライトの「影を落とす」設定を有効にする
- ライト.castShadow=true;
- メッシュの「影を落とす」設定を有効にする
- メッシュ.castShadow=true;
- メッシュの「落ちてきた影を表示する」設定を有効にする
- メッシュ.receiveShadow=true;
- ライトで「影のエッジをぼかす」強さを設定する
- ライト.shadow.radius=4;
マウス左ドラッグで回転、右ドラッグでカメラの移動、ホイールで拡大縮小できます。
スワイプで回転、画面に2本指を触れてなぞるとカメラの移動、ピンチイン/アウトで拡大縮小できます。
ソースコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=yes">
<script src="./js/three.min.js"></script>
<script src="./js/OrbitControls.js"></script>
<script>
var scene,camera;
var main = function () {
//描画先canvasを取得して幅と高さ取得
let can=document.getElementById('can');
let w = parseInt(can.style.width);//幅取得
let h = parseInt(can.style.height);//高さ取得
//■シーン
scene = new THREE.Scene();
//■カメラ
//THREE.PerspectiveCamera( 画角(度), アスペクト比, カメラに写る最短距離, カメラに写る最長距離 );
camera = new THREE.PerspectiveCamera(20, w/h, 0.1, 10000);
camera.position.set(-50, 100, 150);//カメラの位置を設定
//camera.rotation.set(0,0,0);//カメラの角度を(0度,0度,0度)にする
camera.lookAt(new THREE.Vector3(0, 0, 0));//カメラの向きを(0,0,0)座標にする
scene.add(camera);//カメラをシーンに追加
//■レンダラー
renderer = new THREE.WebGLRenderer({canvas:can, antialias: true});//アンチエイリアス有効
renderer.setSize(w, h);
//シャドー(影)マップを有効にする
renderer.shadowMap.enabled = true;
renderer.setClearColor(0x000000, 1);//背景色を設定
//■光源
//環境光(すべての物体にすべての方向から与える光)光の当たらない部分でも真っ黒にならない
var AmbientLight=new THREE.AmbientLight(0xffffff,0.4);
scene.add( AmbientLight );//環境光をシーンに追加
//スポットライト(色,強さ,距離,角度)
const spotLight=new THREE.SpotLight(0xffffff, 2,1000,Math.PI/8);
spotLight.position.set(100,400,300);
spotLight.target.position.set(0,0,0);
spotLight.castShadow=true;//影を表示可能にする
spotLight.shadow.mapSize.width = 1024; //デフォルト512で大きくすると影がきれいになる
spotLight.shadow.mapSize.height = 1024; //デフォルト512で大きくすると影がきれいになる
spotLight.shadow.radius=4; //影のエッジをぼかす強さを設定する
scene.add(spotLight);
scene.add(spotLight.target);
//■ランバートシェーディング材質(光源の影響を受ける光沢の無い材質)の作成
let material=new THREE.MeshLambertMaterial({color:0x6699FF});
//■直方体ジオメトリの作成(幅、高さ、奥行き)
let boxGeometry=new THREE.BoxGeometry(40, 30, 20);
//■直方体ジオメトリとランバートシェーディング材質からメッシュを作成する
let mesh=new THREE.Mesh(boxGeometry, material);
mesh.castShadow=true; //影を他のメッシュに落とす
scene.add(mesh); //メッシュをシーンに追加
//■平面ジオメトリの作成(幅、高さ)
let planeGeometry=new THREE.PlaneGeometry(500,500);
//■平面ジオメトリとランバートシェーディング材質からメッシュを作成する
let planeMesh=new THREE.Mesh(planeGeometry, material);
planeMesh.rotation.x=-Math.PI/2;//x軸で-90度回転
planeMesh.position.set(0,-40,0);//座標移動
planeMesh.receiveShadow=true;//落ちてきた影を表示する
scene.add(planeMesh);
//■オービットコントロールの作成(マウスの左右ボタンドラッグ、ホイール等でカメラが動くようになる)
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0,0,0);
controls.update();
renderLoop();
}
function renderLoop () {
requestAnimationFrame(renderLoop);
renderer.render(scene, camera);
}
window.addEventListener('DOMContentLoaded', main, false);
</script>
</head>
<body>
<canvas id="can" style="width:500px; height:300px;-ms-touch-action:none;touch-action:none;">
</canvas>
</body>
</html>
