Three.jsでWebGLをやろう!【#1基礎、それは一にして全、編】
そもそも、HTMLってどうやって書くんだっけ〜
こんにちは。WANIGAKIです。
ひきつづきThree.jsのお勉強をやっていきましょう。
その前に、これは日記であり、わかりやすい解説をするものではないです。
そのうえ私はフィーリングで技術を学ぶけしからんヤツなので色々と間違ってるかもしれません。ご勘弁を。
さて、そもそもHTMLの記述すらあやふやになっていたので、かる〜くおさらいしましょうか。ほら、この程度のヤツなんですよ。
<html>
<head>
<meta charset="utf-8">
<title>サイトのタイトル</title>
</head>
<body>
<h1>でっけぇ見出し</h1>
</body>
</html>
見たらある程度思い出しますね。まあ詳しくは説明はしません。大事なのはcanvas要素を配置するということです。配置したcanvasにプログラミングでお絵かきをするぞ!その気持ちさえあれば大丈夫です。きっと。
<html>
<head>
<meta charset="utf-8">
<title>Three.jsを学ぶ気持ちがすごい人のサイト</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<script src="./myScript.js"></script>
</head>
<body>
<canvas id='myCanvas' style="background-color: yellow;"></canvas>
</body>
</html>
おもむろに<canvas>を配置し適当なIDをふり、<head>にはThree.jsとこれからいじっていくJavaScriptファイルへのリンクをペタリ。これで大丈夫です。
よっしゃ!JavaScriptを書くぞ書くぞ
ここから先はmyScript.jsのお話です。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
renderer.setSize(960, 540);
}
はい。まずはレンダラーを作ります。THREE.jsはTHREE.WebGLRendererというレンダラーを用意してくれています。Three.jsが準備してくれるものは
「THREE.〜」のように呼び出すようですね。レンダラーを作るのにはHTML内のcanvasを指定する必要があるみたいなんで
canvas: document.querySelector('#myCanvas')
てなかんじで先ほどHTMLにある<canvas>のIDを指定してあげましょう。 renderer.setSizeでサイズも指定してあげましょう。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
renderer.setSize(960, 540);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, 960 / 540);
}
お次は空間そのものであるSceneとそれを撮影するCameraを作ります。PerspectiveCameraでカメラを召喚します。その後ろの(45, 960 / 540)の45は視野角、960 / 540はアスペクト比ですね。
そのカメラは何を映す?
空間「scene」、カメラ「camera」、レンダラー「renderer」ができました。ここに何か物体を召喚しましょう。このままでは真っ暗世界があるのみです。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
renderer.setSize(960, 540);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, 960 / 540);
//立方体用の形「ジオメトリ」を作成
const cubeGeometry = new THREE.BoxGeometry(100, 100, 100);
//立方体用の質感「マテリアル」を作成
const material = new THREE.MeshLambertMaterial({
color: 0x6699bb
});
//ジオメトリとマテリアルを組み合わせ立方体の「メッシュ」を作成
const cubeMesh = new THREE.Mesh(cubeGeometry, material);
}
はい。物体を作るにはそのものの形「ジオメトリ」と質感「マテリアル」、その二つをまず作り、それら二つを組み合わせ「メッシュ」を作る必要があります。
const cubeGeometry = new THREE.BoxGeometry(100, 100, 100);
これで立方体の形ができます 。(100, 100, 100)はそれぞれ幅、高さ、奥行きなので(100,200,100)とかにすれば縦長の直方体になります。
立方体だとか球体だとか、基本的な立体はThree.JSが用意してくれているので「BoxGeometry一丁!」と言えばポンと出してくれますね。「自分で作った3Dモデルを表示させるんじゃー!」って人はちょっと待ってください。そのうち紹介します。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
|
中略
|
//ジオメトリとマテリアルを組み合わせ立方体の「メッシュ」を作成
const cubeMesh = new THREE.Mesh(cubeGeometry, material);
//作ったメッシュを世界「scene」に召喚
scene.add(cubeMesh);
}
立方体を作りました。しかしこの立方体はまだ「世界に存在」していません。召喚したいシーン、先ほど作った世界「scene」に「cubeMesh」を「add」します。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
|
中略
|
//ジオメトリとマテリアルを組み合わせ立方体の「メッシュ」を作成
const cubeMesh = new THREE.Mesh(cubeGeometry, material);
//作ったメッシュを世界「scene」に召喚
scene.add(cubeMesh);
//世界「scene」を「canvas」に映し出す
renderer.render(scene, camera);
}
したらば、その世界「scene」を、カメラ「camera」をつかって
観測「render」しましょう。そうするとcanvasにその様子が映し出されます!!
………
世界は真っ暗。ナンデ!?
ちょっと!まだ立方体は見られないんですか!?
こんなにいっぱいコード書いたんですよ!そろそろ立方体の一つや二つ見せてくれたっていいじゃないですか!とお思いでしょうが、まだやることがあります。先ほどまでのコードで立方体が見えなかった理由は二つありまして、
1、光がない。故に立方体があっても見えていない。
2、カメラと立方体が同じ位置にある。故に何も映らない。
というわけなんですね。それでは解決していきましょう。
window.addEventListener('load', init);
function init() {
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
renderer.setSize(960, 540);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, 960 / 540);
//立方体用の形「ジオメトリ」を作成
const cubeGeometry = new THREE.BoxGeometry(200, 200, 200);
//立方体用の質感「マテリアル」を作成
const material = new THREE.MeshLambertMaterial({
color: 0x6699bb
});
//ジオメトリとマテリアルを組み合わせ立方体の「メッシュ」を作成
const cubeMesh = new THREE.Mesh(cubeGeometry, material);
//作ったメッシュを世界「scene」に召喚
scene.add(cubeMesh);
//ここから先、光源の作成とカメラの位置調整
//光源を作成
const directionalLight = new THREE.DirectionalLight(0xffffff);
//光源を移動
directionalLight.position.set(200, 300, 100);
//光源を原点(0,0,0)に向ける
directionalLight.lookAt(0, 0, 0);
//光源を召喚
scene.add(directionalLight);
//カメラを移動させる
camera.position.set(1000, 1000, 1000);
//カメラを原点(0,0,0)に向ける
camera.lookAt(0, 0, 0);
//ここまで。それでは世界を「観測」しようか...
//世界「scene」を「canvas」に映し出す
renderer.render(scene, camera);
}
ウワ!いきなり増えやがって!もう全部一気にやっちゃいました。といってもポイントは2つ。
//光源を移動
directionalLight.position.set(200, 300, 100);
//カメラを移動させる
camera.position.set(1000, 1000, 1000);
~~.position.set(x,y,z)でモノを移動させること。x,y,zはそれぞれ(ヨコ、タテ、オクユキ)です。
//光源を原点(0,0,0)に向ける
directionalLight.lookAt(0, 0, 0);
//カメラを原点(0,0,0)に向ける
camera.lookAt(0, 0, 0);
~~.lookAt(x,y,z)でその座標を見つめるように回転させること。(0,0,0)にはまだ移動していないcubeMeshがあるので、ライトもカメラもcubeの方を向くことになります。
やった〜!地味すぎる色の立方体がちんまりと現れたゾ!
これでキミも一流のThree.jsニストだ!
長かったですね。キューブ一個表示するのにこれでは先が思いやられますね。ホントはポリゴンでできた色とりどりのゴリラを1000個、縦横無尽に飛び回らせつつ画面にはグリッヂノイズをかけたいのですが、それはまたの機会に。
それでは。