Three.js 3D入門編 ~ライトとマテリアル~
Three.js概要
Three.jsは、「WebGL」を扱いやすくしたフレームワーク。
Three.jsを使えばJavaScriptの知識だけで簡単に3Dコンテンツが作成できるようになります。
今回はどういう表現ができるか、というのを紹介する記事になります。
WebGLだけで3D表現をするためには、立方体1つ表示するだけでも多くのJavaScriptやGLSLコードを書く必要があります。(24 個の座標 (1 面につき 4 個) の定義が必要)
code:webGL
var vertices = [
// 前面
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// 背面
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// 上面
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// 底面
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// 右側面
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// 左側面
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
Three.jsを使えばJavaScriptの知識だけで3Dコンテンツが簡単に作成できる。
code:js
const geometry = new THREE.BoxGeometry(400, 400, 400);
const material = new THREE.MeshNormalMaterial();
const box = new THREE.Mesh(geometry, material);
three.jsの流れ
code:html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script>
// loadされたらinit関数を実行する
window.addEventListener('load', init);
function init() {
// サイズを指定
const width = 960;
const height = 540;
// レンダラーを作成 ⓵
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
// ディスプレイのピクセルレートを合わせる
renderer.setPixelRatio(window.devicePixelRatio);
// 画面サイズの設定
renderer.setSize(width, height);
// シーン(3D空間)を作成 ⓶
const scene = new THREE.Scene();
// カメラ(視点)を作成 ⓷
// THREE.PerspectiveCamera(画角、アスペクト比、描画開始距離、描画終了距離)
const camera = new THREE.PerspectiveCamera(45, width / height);
camera.position.set(0, 0, +1000);
// 箱を作成 ⓸
// THREE.BoxGeometry(幅, 高さ, 奥行き)
const geometry = new THREE.BoxGeometry(400, 400, 400);
// マテリアルは色や質感の情報 ⓹
// THREE.MeshNormalMaterial:適当なカラーを割り振るマテリアル
const material = new THREE.MeshNormalMaterial();
// メッシュの作成 ⓺
const box = new THREE.Mesh(geometry, material);
// シーンに追加 ⓻
scene.add(box);
// 平行光源 ⓼
const directionalLight = new THREE.DirectionalLight(0xFFFFFF);
directionalLight.position.set(1, 1, 1);
// シーンに追加
scene.add(directionalLight);
// 回転
box.rotation.y += 0.6;
renderer.render(scene, camera); // レンダリング
</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
https://gyazo.com/21b980e048558ba40a0578e1bffcf01d
図解
https://gyazo.com/3d93b13d864c83a76a06261d490f43da
アニメーション
code:js
// 初回実行
tick();
function tick() {
// アニメーション処理
box.rotation.y += 0.01;
renderer.render(scene, camera); // レンダリング
// requestAnimationFrame()は引数として渡された関数を、毎フレーム実行
requestAnimationFrame(tick);
}
https://gyazo.com/d7550cc42f96873ba73ffd34a1f276ed
光源の追加
code:js
const material = new THREE.MeshStandardMaterial({ color: 0xFF0000 });
code:js
const directionalLight = new THREE.DirectionalLight(0xFFFFFF);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
THREE.DirectionalLight
平行光源。ライトの位置と方向を指定し平行に到達する光として使用できる。
code:js
// new THREE.AmbientLight(色, 光の強さ)
const light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
https://gyazo.com/4b28ad1f7f06a813953ac38dc10c1c18
https://gyazo.com/80219d2622225247b862f1bdfcb5f860
THREE.AmbientLight
環境光。空間全体を照らす光として使用できる。
床などを追加したらそれとかも照らされる。
code:js
// new THREE.DirectionalLight(色, 光の強さ)
const light = new THREE.AmbientLight(0xFFFFFF, 1);
https://gyazo.com/eb455dfa1f355c709928da3330c06e4e
https://gyazo.com/3b25421579e2a4918a945c155a439f9c
HemisphereLight
半球光源。上からの光の色と下からの光の色を分けることができる。
code:js
// new THREE.HemisphereLight(空の色, 地の色, 光の強さ)
const light = new THREE.HemisphereLight(0x888888, 0x0000FF, 1.0);
https://gyazo.com/ea8399890970921141a2ea0f122826c3
https://gyazo.com/bc88d90dd46c2ef959fe9dd0c9419687
PointLight
点光源。裸電球のような光源。
code:js
// new THREE.PointLight(色, 光の強さ, 距離, 光の減衰率)
const light = new THREE.PointLight(0xffffff, 2, 50, 1.0);
https://gyazo.com/f3ace6ed1ecf41d30346464c17f359f8
SpotLight
スポットライト。単一の点から一方向に放出されて、円錐のような形に沿う光源。
懐中電灯やスマホのライト、ステージ上のスポットライトのような光源。
code:js
// new THREE.SpotLight(色, 光の強さ, 距離, 照射角, ボケ具合, 減衰率)
const light = new THREE.SpotLight(0xFFFFFF, 4, 30, Math.PI / 4, 10, 0.5);
https://gyazo.com/ddfe599d083ebbd47dda65d2078d47bb
RectAreaLight
矩形光源。矩形平面に均一に放出される光源。明るい窓やストリップ照明などの光源をシミュレートするために使用する。
code:js
// new THREE.RectAreaLight(色, 光の強さ, 幅, 高さ)
const light = new THREE.RectAreaLight(0xFFFFFF, 5.0, 10, 10);
https://gyazo.com/9265401f3038816c0c5c4a4dc936e795
https://gyazo.com/b3c93407117220e40397ba3b3f71b917
ライトのヘルパークラス
code:js
// 照明を可視化するヘルパー
const lightHelper = new THREE.PointLightHelper(light);
scene.add(lightHelper);
マテリアルの変更
MeshBasicMaterial
code:js
const material = new THREE.MeshBasicMaterial({color: 0xFFFFFF});
https://gyazo.com/2a8766173167f3817ff592ad542fc9f3
MeshNormalMaterial
A material that maps the normal vectors to RGB colors.
法線ベクトルをRGBカラーにマッピングしたマテリアル
→面の向きによってRGBカラーをマッピングしたマテリアル
code:js
const material = new THREE.MeshNormalMaterial();
https://gyazo.com/93ae8a95e884420917a30955e00ab0e0
https://gyazo.com/2267b3475572d138ca7efc36b2f57fdb
MeshLambertMaterial
ランバート反射とは、拡散反射表面を理想的に扱った反射モデルである。ランバート反射表面の輝度は、どの角度から見ても一定である。
どの角度から見ても一定
⇒光沢感のない質感
code:js
const material = new THREE.MeshLambertMaterial({color: 0xFFFFFF});
https://gyazo.com/d20487aabca41b3dc54872e943c5905e
MeshPhongMaterial
Phongの反射モデル(フォンのはんしゃモデル; 英: Phong reflection model)とは、3次元コンピュータグラフィックスにおいて、モデリングされた面 (surface) 上の点に影をつけるための照明と陰影(シェーディング)モデルである。Phong照明、Phongライティングとも。
フォンシェーディング(英: Phong shading)は、3次元コンピュータグラフィックスにおける陰影計算の補間技法である。フォン補間と呼ばれることもある。ラスタライズされたポリゴン群をまたいだ法線ベクトルの補間によってピクセルの色を推測する技法であり、「ピクセル単位照明」(per-pixel lighting) を実現するための補間技法として利用される。
code:js
const material = new THREE.MeshPhongMaterial({color: 0xFFFFFF});
https://gyazo.com/4f533ba189305fd384bfbc2997f9a3d4
MeshToonMaterial
トゥーンレンダリング(英:Cel shading)は、3次元コンピュータグラフィックスの一種で、2次元の手描きアニメーション、あるいは漫画やイラスト風の作画(いわゆるアニメ絵)で非写実的レンダリングさせる技術である。
アニメのようなトゥーンシェーディングを実現できるマテリアル
code:js
const material = new THREE.MeshToonMaterial({color: 0xFFFFFF});
https://gyazo.com/520883441a6b66522a579084f0839f58
MeshStandardMaterial
A standard physically based material, using Metallic-Roughness workflow.
メタリック(金属性)―ラフネス(粗さ)ワークフローを使用した標準的な物理ベースのマテリアル。
光の反射や散乱など現実の物理現象を再現できる。
roughnessのプロパティで光沢感の調整ができる。
0のときは光沢の質感、1のときはマットな質感になる。
code:js
const material = new THREE.MeshStandardMaterial({color: 0xFFFFFF, roughness:0.5});
roughness : 0
https://gyazo.com/9a6499e5a24903a47f7f0fa4ac6fd8d6
roughness : 0.5
https://gyazo.com/d356fb4ef9ad8c08fb559fb91cedf14c
roughness : 1
https://gyazo.com/1cef571ed4b759ed9a719753ace7cf56
参考資料
👍 Thaddeus Jiang TJ.icon がいいねしました on 2020/7/27
👍 onuma onuma.icon がいいねしました on 2020/7/29