Three.jsの続きです。前回はThree.js入門のの回る箱をいろいろ打ち替えてみました。今回は「マテリアル」と「ライティング」を見てきます。それでは行きましょう!
【目次】
前回記事
※参考:【Three.js】回る箱をいろいろ打ち替えてみる - クモのようにコツコツと
Three.jsを習得するためにやったことまとめ
qiita.com
入門編の「回る箱」おさらい
ICS「Three.js入門」の「入門編」で作った回る箱。
See the Pen three.js 01 by イイダリョウ (@i_ryo) on CodePen.
※参考:簡単なThree.jsのサンプルを試そう - ICS MEDIA
JSコード
// ページの読み込みを待つ 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); // シーンを作成 const scene = new THREE.Scene(); // カメラを作成 const camera = new THREE.PerspectiveCamera(45, width / height); camera.position.set(0, 0, +1000); // 箱を作成 const geometry = new THREE.BoxGeometry(400, 400, 400); const material = new THREE.MeshNormalMaterial(); const box = new THREE.Mesh(geometry, material); scene.add(box); tick(); // 毎フレーム時に実行されるループイベントです function tick() { box.rotation.y += 0.01; renderer.render(scene, camera); // レンダリング requestAnimationFrame(tick); } }
マテリアルとは何か
今回はその続き、「Three.jsのマテリアルの基本」を見ていく。
※参考:Three.jsのマテリアルの基本 - ICS MEDIA
まずマテリアルとは何か?*1
該当ページにはこうある。
マテリアルとは物体の質感設定のことです。
代表的なマテリアルとして「単色塗りのマテリアル」と「画像を使ったマテリアル」の二種類があります。
なお、よく似た単語に「シェーダー」「テクスチャ」もある。
マテリアル
モデル表面の反射率や粗さなど、描画設定の集まり。テクスチャ
色や模様を表現するビットマップ画像。シェーダー
ピクセル毎の描画色を計算するスクリプト。
テクスチャは画像でシェーダーは設定値でその両方を含む表面の描画設定がマテリアルか。
Three.jsのオブジェクト作成手順
Three.js入門の該当ページにはこうある。
Three.jsのオブジェクトの作成手順 ①マテリアルを作成 ②ジオメトリを作成 ③メッシュを作成
またわからない言葉が出てきた。ジオメトリとはなんぞや?メッシュとは?
Three.js入門の次ページ「ジオメトリ」に解説があった。
形状(ジオメトリとも言います)を指定することで「球体」や「直方体」、「平面」などさまざまな3Dのオブジェクトを表示できます
Three.jsでは形状とマテリアルを結合しメッシュを作成することによって、表示可能な3Dのオブジェクトを得ることができます。
※参考:Three.jsのジオメトリの基本 - ICS MEDIA
表面の描画設定(マテリアル)と形状(ジオメトリ)を結合して作成したメッシュがオブジェクトになると。
ジオメトリには馴染みはなかったが3DCGでも一般的な言葉のようだ。
ジオメトリとは、幾何学、形状、などの意味を持つ英単語。コンピュータグラフィックスにおける描画対象の形状や、形状を定義づける頂点の座標や線分、面などの図形を表す式の係数といったデータの組み合わせを意味することが多い。
メッシュについては「ポリゴンの集まり」という意味があるようだ。
ポリゴン:多角形のこと(三角形、四角形、五角形・・etc)
メッシュ:ポリゴンの集まりのこと
サーフェス:面のこと
ジオメトリを箱から球体に
変数geometry
を変更
// ジオメトリを作成(球体) const geometry = new THREE.SphereGeometry(300, 30, 30);
THREE.BoxGeometry()
クラスをTHREE.SphereGeometry()
クラスに変更した。
変数名box
も形状に影響されないようにmesh
に変更した。
//メッシュを作成 const mesh = new THREE.Mesh(geometry, material);
変数box
が適用されている場所が二箇所あったので変更する。
//シーンにメッシュを適用
scene.add(mesh);
// 毎フレーム時に実行されるループイベントです function tick() { mesh.rotation.y += 0.01; renderer.render(scene, camera); // レンダリング
回る箱が球体になった!
See the Pen three.js 15 by イイダリョウ (@i_ryo) on CodePen.
マテリアルを赤色に
次、マテリアルの設定
// マテリアルを作成 const material = new THREE.MeshStandardMaterial({color: 0xFF0000});
変数material
のTHREE.MeshNormalMaterial()
クラスをTHREE.MeshStandardMaterial()
クラスに変更。引数は連想配列でcolor
キーの値は0xFF0000
(RGBの赤色を意味する)
さあどうだ!
See the Pen three.js 16 by イイダリョウ (@i_ryo) on CodePen.
お、真っ暗になってしまった。。
Three.jsの「マテリアル」の記事にTHREE.MeshNormalMaterial()
の解説があった。
THREE.MeshNormalMaterialクラスはノーマルのカラーをRGBで可視化するマテリアルです。ライティングを必要としないため、手軽に動作確認するときに役立つでしょう。
※参考:Three.jsのさまざまなマテリアル - ICS MEDIA
THREE.MeshNormalMaterial()
クラスは自ら光っているのでライトが必要なかったわけだ。通常のマテリアル設定ではライティングを設定しないと真っ暗になってしまう。
ライティング設定
ということでライティングを設定する。オブジェクトに光を当てるって実写的にで3Dならではな感じがするなぁ。
// 平行光源 const directionalLight = new THREE.DirectionalLight(0xFFFFFF); directionalLight.position.set(1, 1, 1); // シーンに追加 scene.add(directionalLight);
- 変数
directionalLight
にTHREE.DirectionalLight()
クラスを代入。引数は0xFFFFFF
(白色) directionalLight
のposition
オブジェクトのset()
メソッドに引数を3つ(いずれも値は1)scene
にdirectionalLight
を追加する
THREE.DirectionalLightクラス
平行光源。ライトの位置と方向を指定し平行に到達する光として使用できます。
THREE.DirectionalLight
は一箇所から直線上に照らしている光。太陽とか電灯みたいなイメージ。
THREE.AmbientLightクラス
環境光。空間全体を照らす光として使用できます。
ちなみに環境光というのもあるらしい(今回は書いていない)
さあどうだ!
See the Pen three.js 17 by イイダリョウ (@i_ryo) on CodePen.
お、赤い球体が出てきた!
マテリアルに画像を配置する
最後に、マテリアルを色ではなくビットマップ画像を配置してみる。
// 画像を読み込む const loader = new THREE.TextureLoader(); const texture = loader.load('(画像パス)/hoge.jpg'); // マテリアルを作成 const material = new THREE.MeshStandardMaterial({map: texture});
- 変数
loader
にTHREE.TextureLoader()
クラスを代入 - 変数
texture
にloader
のload()
メソッドで画像ファイルを読み込み - 変数
material
のTHREE.MeshStandardMaterial()
クラスの引数をmap
キーに変更し、値をtexture
に
これで先ほどの赤色がビットマップ画像になる。どうだ!
See the Pen three.js 18 by イイダリョウ (@i_ryo) on CodePen.
やた!イイダリョウのプロフィール画像(風街ばあじょん)が貼られた!
JSコードはこんなんなりました。
// ページの読み込みを待つ 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); // シーンを作成 const scene = new THREE.Scene(); // カメラを作成 const camera = new THREE.PerspectiveCamera(45, width / height); camera.position.set(0, 0, +1000); // ジオメトリを作成(球体) const geometry = new THREE.SphereGeometry(300, 30, 30); // 画像を読み込む const loader = new THREE.TextureLoader(); const texture = loader.load('https://s.cdpn.io/profiles/user/305282/512.jpg'); // マテリアルを作成 const material = new THREE.MeshStandardMaterial({map: texture}); //メッシュを作成 const mesh = new THREE.Mesh(geometry, material); //シーンにメッシュを適用 scene.add(mesh); // 平行光源 const directionalLight = new THREE.DirectionalLight(0xFFFFFF); directionalLight.position.set(1, 1, 1); // シーンに追加 scene.add(directionalLight); tick(); // 毎フレーム時に実行されるループイベントです function tick() { mesh.rotation.y += 0.01; renderer.render(scene, camera); // レンダリング requestAnimationFrame(tick); } }
最後に
ということでThree.js入門に再入門しました。なんと、前回は2018年!昨年はVue.jsに集中したため1年以上空いてしまった。。
その間、長めのJSコードに触れる機会も多く、当時よりコードの読解力が増えたように感じました。今度こそ中段せずにコンスタントに継続して行きたく思います。
次回は入門編の続き「ジオメトリ」を見て行きたく思います。それではまた!
Three.jsを習得するためにやったことまとめ
qiita.com
*1:待て、リアル(現実)、なんてダジャレを言っている場合ではない!