【Three.js】パーリンノイズでカーテンを作る
オーロラ
はじめに
線を描いてオシャレなものを作りたい。というワケで手始めにカーテンを作ってみようと思います。
作るにあたってこちらの記事を参考にさせていただきました。参考というか、ほぼそのまま。とても分かりやすかったです。ありがとうございます。
線を1本だけ描いてみる
const points = [];
// 始点
points.push(new THREE.Vector3(0, 10, 0));
// 終点
points.push(new THREE.Vector3(10, 0, 0));
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({color: 0xffff00});
const line = new THREE.Line(geometry, material);
scene.add(line);
まずは始点と終点の座標を作って配列に入れましょう。それをTHREE.BufferGeometryのsetFromPoints()に渡してジオメトリを作ります。
で、ジオメトリとマテリアルをTHREE.Lineのコンストラクタに渡せば線が引けます↓。
線を動かす
始点は固定して、終点だけをZ軸のマイナス方向に動かしてみます。
// 線のアニメーション
function drawCurtain() {
line.geometry.attributes.position.array[5] -= 0.1;
line.geometry.attributes.position.needsUpdate = true;
}
3行目のline.geometry.attributes.position.array。コイツ配列でして、中身はこんな風になっています↓。
配列のインデックスは[0]から始まるので[5]の要素をいじってあげましょう。そうするとこんな感じで終点が遠ざかっていきます(動画)↓。
線の動かし方が分かったので、次は線をたくさん作ってランダムに動くようにしてみましょう。
パーリンノイズ
ケン・パーリンさんが作ったから「パーリンノイズ」。かっこいいですね。「パーリンノイズ」って言いたくなる。
このパーリンノイズを使うと「自然な揺らぎ」を作ることができます。煙とか炎とか地形とか。
完全なランダムにするとグチャグチャになっちゃうけど、パーリンノイズだとイイ感じになる。こんな感じです↓。
ランダムではあるんだけど、直前の値と近い値になるようです。ホント、カーテン作るために開発されたんじゃないかってぐらい、カーテン作るのに適してると思いますね。
線をたくさん描く
const lines = [];
for (let i = 0; i < 500; i++) {
const points = [];
points.push(new THREE.Vector3((i - 250) / 10, 50, 0));
points.push(new THREE.Vector3((i - 250) / 10, 0, 0));
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({color: 0xffffff});
const line = new THREE.Line(geometry, material);
scene.add(line);
lines.push(line);
}
まずは、まっすぐな線を500本作って横一列にズラーっと並べます。あとで線一本一本にアニメーションをつけていくので、linesっていう名前の配列に入れておきます。こうなります↓。
ビシーッ。
パーリンノイズでアニメーション
noise.seed(Math.random());
function drawCurtain() {
const time = Date.now() / 10000;
for (let i = 0; i < 500; i++) {
const px = i / 100;
const py = time;
const z = noise.perlin2(px, py) * 20;
lines[i].geometry.attributes.position.array[5] = z
lines[i].geometry.attributes.position.needsUpdate = true;
}
}
パーリンノイズの使い方はとっても簡単。noise.perlin2(px, py)。引数の値が近ければ、戻り値も近くなるようです。使い方は簡単だけど、中身は何やってんのか分かりませんでした。パーリンさんに感謝。
パーリンノイズには他にもperlin3、simplex2、simplex3があります。そちらはまたの機会に…。
こんな感じになります(動画)↓。
3行目のtimeの値が大きいほどカーテンの動きが早くなります。
6行目のpxの値が大きいほど隣の値との差が大きくなり、ギザギザになります↓。
9行目でperlin2の戻り値に20を掛けていますが、これは振り幅になります。大きいほどカーテンの揺れも大きくなります↓。
1行目のnoise.seed(Math.random())ですが、これが実行される度にパーリンノイズが作ってくれるランダムな値が変わるようです。
逆に言うと、これを書いていない状態で、perlin2の引数に毎回同じ値を渡してあげると、毎回同じ結果が返ってきます。
今回はperlin2の引数に時間を渡しているので書かなくても大丈夫なんですけど、なんとなく書いておきました。
時間経過とともに変化するようなモノを作るなら、あんまり関係ないものかも知れません。
線に色をつける
noise.seed(Math.random());
function drawCurtain() {
const time = Date.now() / 10000;
for (let i = 0; i < 500; i++) {
const px = i / 100;
const py = time;
const z = noise.perlin2(px, py) * 20;
lines[i].geometry.attributes.position.array[5] = z
lines[i].geometry.attributes.position.needsUpdate = true;
// HSL色空間
const h = Math.round((i / 500) * 360);
const s = 100;
const l = 30;
const color = new THREE.Color(`hsl(${h},${s}%,${l}%)`);
lines[i].material.color = color;
}
}
HSL色空間(HLS色空間とも言うのかな?)というものがあるそうです。
Hが色相。色を360度の円で表していて、0度が赤で180度が青緑(赤の反対色)。
Sが彩度。小さいほど灰色に近づきます。
Lは輝度。0は黒。100は白。
さらっとしか調べてないので違っていたらごめんなさい。そんなワケでできたのがコレ↓。
デモサイトはこちら。
オーロラですね。オーロラがこんな色してるのかは分かりませんがオーロラです。
あとがき
はい。というワケでパーリンノイズを使ってみました。ホントに便利ですね。ランダムなんだけど「自然」っていうのがスゴイ。煙とか波とかも作ってみたいなぁと思いました。今回は以上です。ありがとうございました。
おしゃれ度
★★★☆☆
ディスカッション
コメント一覧
まだ、コメントがありません