クリエイティブコーディング – Three.js[後編]

こんにちは、コーダーのdanです。
今回は、Three.js[前編]の続きで、波のような動きについて説明していきます。

目次

3Dオブジェクトの作成の流れ

まずは、3Dオブジェクトの頂点を操作して、波のような動きを作り出す処理を行なっているSTEP2に焦点を当てます。

STEP
Geometry(ジオメトリ)の作成

Geometry は、3Dオブジェクトの形状や構造を定義します。

STEP
Material(マテリアル)の設定

Material は、ジオメトリの表面の見た目を定義します。
色や透明度、光沢などを設定でき、テクスチャも適用可能です。

uniform vec2 uFrequency;
uniform float uTime;

varying vec2 vUv;
varying float vElevation;

void main()
{
    vec4 modelPosition = modelMatrix * vec4(position, 1.0);

    float elevation = sin(modelPosition.x * uFrequency.x - uTime) * 0.1;
    elevation += sin(modelPosition.y * uFrequency.y - uTime) * 0.1;

    modelPosition.z += elevation;

    vec4 viewPosition = viewMatrix * modelPosition;
    vec4 projectedPosition = projectionMatrix * viewPosition;

    gl_Position = projectedPosition;

    vUv = uv;
    vElevation = elevation;
}
頂点シェーダー
  • 入力される頂点の位置(position)を基に、波状の高さ(elevation)を計算
  • 計算された頂点位置をカメラ座標系に変換し、最終的にスクリーン上に描画するための座標(gl_Position)を設定
  • vUv(UV座標)とvElevation(波の高さ)は、フラグメントシェーダーで使用
uniform vec3 uColor;
uniform sampler2D uTexture;

varying vec2 vUv;
varying float vElevation;

void main()
{
    vec4 textureColor = texture2D(uTexture, vUv);
    textureColor.rgb *= vElevation * 2.0 + 0.65;
    gl_FragColor = textureColor;
    // gl_FragColor = vec4(vUv, 1.0, 1.0);
}
フラグメントシェーダー

頂点シェーダーからの補間された値(色、テクスチャ座標、法線、およびジオメトリの頂点に関連するその他の属性)を受け取ります。

シェーダーとは…

「処理ロジック」を記述するもので、直接データ(素材やデータ)を所有していません。
シェーダーは、マテリアルのカスタマイズや特別な視覚効果を実現する部分で使用します。
素材やデータは、テクスチャが所有しています。

UV座標は、2Dのテクスチャを3Dのオブジェクトに正しく貼り付けるために必要なものです。
UV座標を「四角いシール」だと思ってください。
シールの左下が (0.0, 0.0)、右上が (1.0, 1.0) という数字で表されていて、この座標を使ってシールに模様や色をつけていきます。

STEP
Textures(テクスチャ)の追加

Textures は、マテリアルに画像データを貼り付けて、よりリアルな表現を可能にします。
テクスチャ画像を読み込んで、マテリアルに設定します。

STEP
Mesh(メッシュ)の生成

Mesh は、Geometry(形状)と Material(表面)を組み合わせて、3Dオブジェクトを生成します。
Meshはシーンに追加して、表示されるオブジェクトを作ります。

STEP
シーンへの追加

作成したMeshをシーンに追加し、レンダリングします。

STEP
結果のレンダリング

カメラとライトを設定し、レンダラーでシーンを表示します。

座標変換の流れ

次に、STEP2の処理の中で行われている座標変換の流れを見てみます。

STEP
ローカル座標 → ワールド座標(modelMatrixを適用)

1. ローカル座標: オブジェクト内部で相対的な座標
2. モデル座標: モデル行列で位置、回転、スケールを適用した座標
3. ワールド座標: ワールド行列で全体の空間に配置された座標

vec4 modelPosition = modelMatrix * vec4(position, 1.0);
float elevation = sin(modelPosition.x * uFrequency.x - uTime) * 0.1;
elevation += sin(modelPosition.y * uFrequency.y - uTime) * 0.1;
modelPosition.z += elevation;

uFrequency: 波の頻度(x方向とy方向で異なる周波数)
uTime: 時間の進行(アニメーションを実現)
0.1: 波の振幅(波の高さを制御)
modelPosition.z += elevation: 頂点が波状の動きをするように変形

STEP
ワールド座標 → ビュー座標(viewMatrixを適用)

4. ビュー座標: カメラの位置や向きを考慮した座標

vec4 viewPosition = viewMatrix * modelPosition;
STEP
ビュー座標 → スクリーン座標(projectionMatrixを適用)

5. スクリーン座標: 最終的に画面に描画される2Dの座標

vec4 projectedPosition = projectionMatrix * viewPosition;
gl_Position = projectedPosition;

2D空間での変換後の頂点の位置は、事前定義された変数 gl_Position を介して返されます。

この記事をシェアする
  • URLをコピーしました!

この記事を書いた人

Webコーダーです。
自分は飽き性だから、学び続けることができるWeb制作は刺激も多く好きです。
JavaScriptは何度も嫌になったけど、この道を選択して良かったと思っています。
この記事が、悩みの解決の糸口や新しい出会いになりましたら幸いです。

目次