Three.js:マウスによる背景の動き + レンズフレア
上記動画のメモです。
いくつか書き換えている部分があります。
デモサイト
my git
VSCodeでの下準備
- 「Three.js」と検索
- 左側のcodeの中の”download”をクリック
- ダウンロードしたzipを解凍
- プロジェクトのフォルダを作成し、VSCodeで開いておく
- 解凍したzipの「build」,「jsm」2つをそのプロジェクトの中に入れておく
・build
・jsm : examples > jsm - 「lens flare」と検索し、好きな画像をプロジェクトの中に「textures」というフォルダを作り入れておく
現状
プロジェクトの中に「build」「jsm」「textures」というフォルダがある状態
box作成
03:20 index.html, script.js 作成
03:40 htmlコーディング
04:12 jsの記述——————-
04:34 土台作成
06:55 箱作成
10:40 平行光源
11:30 レンダラー
13:10 各種修正(カメラ、箱の回転)
15:35 ポイント光源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MouseMove Three.js</title>
</head>
<body>
<script src="script.js" type="module"></script>
</body>
</html>
import * as THREE from "./build/three.module.js"
let camera, scene, renderer;
init();
function init() {
// camera
camera = new THREE.PerspectiveCamera(
40,
window.innerWidth / window.innerHeight,
1,
15000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
const size = 250;
const geometry = new THREE.BoxGeometry(size, size, size);
const material = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0xffffff,
shininess: 50,
});
// boxを2500個作成
for(let i = 0; i < 2500; i++) {
const mesh = new THREE.Mesh(geometry, material);
mesh.position.x = 8000 * (2.0 * Math.random() - 1.0);
mesh.position.y = 8000 * (2.0 * Math.random() - 1.0);
mesh.position.z = 8000 * (2.0 * Math.random() - 1.0);
// 回転度合いを決める
mesh.rotation.x = Math.random() * Math.PI;
mesh.rotation.y = Math.random() * Math.PI;
mesh.rotation.z = Math.random() * Math.PI;
scene.add(mesh);
}
// 平行光源
const dirLight = new THREE.DirectionalLight(0xffffff, 0.03);
scene.add(dirLight);
// ポイント光源
addLight(0.08, 0.3, 0.9, 0, 0, -1000)
function addLight(h, s, l, x, y, z) {
const light = new THREE.PointLight(0xffffff, 1.5, 2000);
light.color.setHSL(h, s, l);
light.position.set(x, y, z);
scene.add(light);
}
// renderer
renderer = new THREE.WebGL1Renderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
}
マウス操作 + レンズフレア
18:30 マウス操作
24:00 レンズフレア
// シーンなどが使えるようにモジュールをすべてインポート
import * as THREE from "./build/three.module.js";
// マウス操作
import { FlyControls } from "./jsm/controls/FlyControls.js";
// レンズフレア
import { Lensflare, LensflareElement } from "./jsm/objects/Lensflare.js";
let camera, scene, renderer;
let controls;
// 現在の経過時間を出力する
const clock = new THREE.Clock();
init();
// 初期化関数
function init() {
// カメラ
camera = new THREE.PerspectiveCamera(
40, // 視野角
window.innerWidth / window.innerHeight, // アスペクト比
1, // 開始距離
15000 // 終了距離
);
camera.position.z = 250; // カメラを引きでみる
// シーン
scene = new THREE.Scene();
const size = 250;
const geometry = new THREE.BoxGeometry(size, size, size); // 箱の大きさ設定
const material = new THREE.MeshPhongMaterial({ // 箱の色など設定
color: 0xffffff, // 色:白
specular: 0xffffff, // 鏡面反射
shininess: 50, // 輝度
});
// 箱を2500個作成
for(let i = 0; i < 2500; i++) {
// geometry と material をまとめるmeshを作成
const mesh = new THREE.Mesh(geometry, material);
//位置をランダムに決める
mesh.position.x = 8000 * (2.0 * Math.random() - 1.0);
mesh.position.y = 8000 * (2.0 * Math.random() - 1.0);
mesh.position.z = 8000 * (2.0 * Math.random() - 1.0);
// 回転度合いをランダムに決める
mesh.rotation.x = Math.random() * Math.PI;
mesh.rotation.y = Math.random() * Math.PI;
mesh.rotation.z = Math.random() * Math.PI;
scene.add(mesh);
}
// 平行光源
const dirLight = new THREE.DirectionalLight(0xffffff, 0.03); // 色, 光の強さ
scene.add(dirLight);
// レンズフレアを追加
const textureLoader = new THREE.TextureLoader();
const textureFlare = textureLoader.load("./textures/LensFlare.jpg");
// ポイント光源
addLight(0.08, 0.3, 0.9, 0, 0, -1000)
function addLight(h, s, l, x, y, z) { // 色相:hue, 彩度:saturation, 輝度:light
const light = new THREE.PointLight(0xffffff, 1.5, 2000); // 色, 光の強さ, 距離(, 減衰量)
light.color.setHSL(h, s, l); // 光の色
light.position.set(x, y, z); // 光の位置
scene.add(light);
// レンズフレア設定
const lensflare = new Lensflare(); // Lensflare関数をインスタンス化
lensflare.addElement(
new LensflareElement(textureFlare, 700, 0, light.color)
);
scene.add(lensflare);
}
// レンダラー
renderer = new THREE.WebGLRenderer(); // 今回はWebGLRenderer を使用
renderer.setSize(window.innerWidth, window.innerHeight); // 画面いっぱいいっぱいに表現
renderer.outputEncoding = THREE.sRGBEncoding; // レンズフレアを明るく描画
document.body.appendChild(renderer.domElement); // bodyにレンダラーを入れる
// マウス操作
controls = new FlyControls(camera, renderer.domElement);
controls.movementSpeed = 2500; // 左クリック、右クリック時の速度
controls.rollSpeed = Math.PI / 20; // マウス操作時の速度
animate();
}
// マウス操作のアニメーション
function animate() {
requestAnimationFrame(animate); //自分(animate関数)を毎フレーム呼び出す
const delta = clock.getDelta(); //経過した時間を取得
controls.update(delta); // deltaをアップデートすることによってマウス操作ができるようになる
renderer.render(scene, camera); // シーンとカメラをレンダリング
}
メニュー、タイトルの追加
29:00 cssの設定
30:00 Google Fonts
30:50 ヘッダーメニュー
33:11 タイトル
+ α
動画では紹介していなかったけれどgitに入っていたものについて
import Stats from "./jsm/libs/stats.module.js";
let container, stats;
animate(); // 記述する場所を変更
function init() {
// divを作成しそこに描画
container = document.createElement("div");
document.body.appendChild(container);
container.appendChild(renderer.domElement); // containerにレンダラーを入れる
// document.body.appendChild(renderer.domElement); // bodyにレンダラーを入れる
// ステータスバー作成
stats = new Stats();
container.appendChild(stats.dom);
}
function animate() {
stats.update();
}
function init() {
// リサイズしたら自動でウインドウをリサイズする
window.addEventListener("resize", onWindowResize);
}
// リサイズしたときに画面いっぱいいっぱいにする
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
平行光線の色をHSLで指定
dirLight.color.setHSL(0.1, 0.7, 0.5);