Three.js が Facebook Metaverse 3D ダイナミック ロゴ効果を実現

Three.js が Facebook Metaverse 3D ダイナミック ロゴ効果を実現

この記事では、主に、基本的なモデル リング、トーラス ノット、パイプラインとモデル生成、モデルの読み込み、アニメーションの追加、クリック イベントの追加、マテリアルの変更など、Three.js + Blender テクノロジー スタックを使用して Meta のクールな 3D ダイナミック ロゴを実現する方法について説明します。

背景

Facebook最近、親会社の名称をMetaに変更し、正式に元宇宙🪐分野への参入を開始したことを発表しました。この記事では主に、基本的なモデルリング、トーラスノット、パイプラインとモデル生成、モデルの読み込み、アニメーションの追加、クリックイベントの追加、マテリアルの変更など、 Three.js + Blenderテクノロジースタックを使用してMetaのクールな3DダイナミックLogo実現する方法について説明します。

メタバースとは何ですか?

メタバースという用語は、 1992のニール・スティーブンソンの《雪崩》に由来しており、現実世界と並行してMetaverseと呼ばれる仮想世界があり、現実世界のすべての人がネットワーク アバターAvatarを持っていることを説明しています。維基百科、メタバースを次のように説明しています: リンク認識と共有機能を備えた将来のインターネットに基づく3D仮想空間であり、収束性と物理的な持続性を示す仮想拡張物理現実です。

メタバースの内包は、情報革命5G/6G 、インターネット革命web3.0 、人工知能革命、さらにはVRARMR 、特にゲームエンジンを含む仮想現実技術革命の成果を吸収し、人類に伝統的な物理世界と並行するホログラフィックデジタル世界を構築する可能性を示し、情報科学、量子科学、数学、生命科学の相互作用を引き起こし、科学的パラダイムを変え、伝統的な哲学、社会学、さらには人文科学システムの突破口を開き、すべてのデジタル技術を包含しています。映画《頭號玩家》のワンシーンのように、将来、人々はいつでもどこでもアイデンティティを切り替え、物理世界とデジタル世界を自由に行き来し、仮想空間と時間ノードで構成されたメタバースで生活し、学ぶことができるようになるでしょう。

成果を達成する

早速本題に入り、この記事の例の実装効果を見てみましょう。

🔗プレビュー: https://dragonir.github.io/3d-meta-logo (モデルのサイズが大きいため、読み込みの進行が遅くなる可能性がありますので、しばらくお待ちください)

開発と実装

📌 : 上記のサンプルアニメーションはトライアル 4 を示しています。試行錯誤のプロセス (トライアル 1、トライアル 2、トライアル 3) を確認したくない場合は、トライアル 4 に直接ジャンプして、詳細な実装プロセスを表示できます。問題は失敗したプロセスに記載されています。解決策をご存知の場合は、コメント欄でお気軽に共有してください。

開発の前に、 Meta Logoを見てみましょう。折りたたまれてねじれた円であることがわかります。そのため、実装する際には、円を実装することから始めることができます。

トライアル 1: THREE.TorusGeometry

Three.jsが提供する基本的なジオメトリはTHREE.TorusGeometryで、ドーナツ🍩のようなシンプルなグラフィックです。主なパラメータ:

  • radius : オプション。リングの半径のサイズを定義します。デフォルト値は1です。
  • tube : オプション。トーラスのチューブの半径を定義します。デフォルト値は0.4です。
  • radialSegments : オプション。リングの長さに沿ったセグメントの数を定義します。デフォルト値は8です。
  • tubularSegments : オプション。リングの幅に沿ったセグメントの数を定義します。デフォルト値は6です。
  • arc : オプション。描画される円の長さを定義します。値の範囲は02 * πです。デフォルト値は2 * π (完全な円) です。

構文例:

3.TorusGeometry(半径、チューブ、放射状セグメント、管状セグメント、円弧);

😭 失敗: リングをひねる方法が見つかりませんでした。

トライアル 2: THREE.TorusKnotGeometry

THREE.TorusKnotGeometryを使用すると、3 次元のトーラス ノットを作成できます。トーラス ノットは、チューブが何度もねじれたような特殊なノットです。主なパラメータ:

  • radius : オプション。完全な円の半径を設定します。デフォルト値は1です。
  • tube : オプション。パイプの半径を設定します。デフォルト値は0.4です。
  • radialSegments : オプション。パイプ断面のセグメント数を指定します。セグメント数が多いほど、パイプ断面は滑らかになります。デフォルト値は8です。 tubularSegments : オプション。パイプラインのセグメント数を指定します。セグメント数が多いほど、パイプラインはスムーズになります。デフォルト値は64です。
  • p : オプション。ジオメトリを回転対称軸を中心に回転する回数を決定します。デフォルト値は2です。
  • q : オプション。ジオメトリが内側のリングの周りを何回回転するかを決定します。デフォルト値は3です。

構文例:

3.TorusKnotGeometry(半径、チューブ、放射状セグメント、管状セグメント、p、q);

😭 失敗: 手動による歪みの度合いを制御する方法が見つかりませんでした。

トライアル3: THREE.TubeGeometry

THREE.TubeGeometry 、3 次元スプラインに沿ってチューブを押し出します。いくつかのポイントを指定してパスを定義し、 THREE.TubeGeometryを使用してチューブを作成できます。主なパラメータ:

  • path : このプロパティは、 THREE.SplineCurve3オブジェクトを使用して、パイプラインがたどるパスを指定します。
  • segments : このプロパティは、このチューブを構築するために使用されるセグメントの数を指定します。デフォルト値は64です。パスが長いほど、指定するセグメントの数が多くなります。
  • radius : このプロパティはチューブの半径を指定します。デフォルト値は1です。
  • radiusSegments : このプロパティは、パイプの円周のセグメント数を指定します。デフォルト値は8です。セグメントの数が多いほど、パイプは丸く見えます。
  • closed : このプロパティをtrueに設定すると、パイプの先頭と末尾が接続されます。デフォルト値はfalseです。

コードサンプル

// ...
var controls = 新しい関数 () {
  //ポイント座標 this.deafultpoints = [
    [0, 0.4, -0.4],
    [0.4, 0, 0],
    [0.4, 0.8, 0.4],
    [0, 0.4, 0.4],
    [-0.4, 0, 0],
    [-0.4, 0.8, -0.4],
    [0, 0.4, -0.4]
  ]
  this.セグメント = 64;
  this.radius = 1;
  this.radiusSegments = 8;
  this.closed = true;
  ポイントは[]です。
  this.newPoints = 関数 () {
    var ポイント = [];
    (var i = 0; i < controls.deafultpoints.length; i++) {
      var _x = controls.defaultpoints[i][0] * 22;
      var _y = controls.defaultpoints[i][1] * 22;
      var _z = controls.defaultpoints[i][2] * 22;
      points.push(新しいTHREE.Vector3(_x, _y, _z));
    }
    controls.points = ポイント;
    コントロールを再度描画します。
  };
  this.redraw = 関数 () {
    redrawGeometryAndUpdateUI(gui、シーン、コントロール、関数() {
      generatePoints(controls.points, controls.segments, controls.radius, controls.radiusSegments, を返します。
        コントロールを閉じます);
    });
  };
};
コントロール。新しいポイント();
関数 generatePoints(ポイント、セグメント、半径、半径セグメント、閉じた) {
  if (spGroup) scene.remove(spGroup);
  spGroup = 新しい THREE.Object3D();
  var material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: false });
  points.forEach(関数(ポイント) {
    var spGeom = new THREE.SphereGeometry(0.1);
    var spMesh = new THREE.Mesh(spGeom, マテリアル);
    spMesh.position.copy(ポイント);
    spGroup を追加します。
  });
  シーンを追加します(spGroup);
  新しい THREE.TubeGeometry(新しい THREE.CatmullRomCurve3(points), segments, radius, radiusSegments, closed) を返します。
}
// ...

😊 勉強成功。しかし、パイプで形成される円は十分に丸くありません。完全な円弧を実現するには正確な座標が必要ですが、座標を計算する方法はまだ見つかっていません。

トライアル4: Blender + Three.js

これはTHREE.TubeGeometryを使用して実現できますが、効果は良くありません。滑らかなリングを実現するには、パイプに正確なねじれリング曲線パス関数を追加する必要があります。私の数学的能力が限られているため🤕️ 、ねじれた円弧のパスを計算する方法はまだ見つかっていません。そこで、モデリングレベルから解決することにしました。

成功😄 : しかし、 Blenderを使用してモデリングするのに多くの時間を費やしました💔

モデリングチュートリアル

B站ある大物が投稿したこのお宝動画を見つけました。これで私の問題が解決しました。

🎦 : [ダイナミックデザインチュートリアル] AE+Blender で遊ぶには? Facebookメタバースのダイナミックロゴは完全に分析され、100%学習されました

Blenderを使ったモデリング

モデリングにはBlenderを使用し、アニメーションを伝達できるfbx形式でエクスポートします。エクスポート時に、烘焙動畫オプションをチェックすることを忘れないでください。

依存関係の読み込み

<script src="./assets/libs/three.js"></script>
<script src="./assets/libs/loaders/FBXLoader.js"></script>
<script src="./assets/libs/inflate.min.js"></script>
<script src="./assets/libs/OrbitControls.js"></script>
<script src="./assets/libs/stats.js"></script>

シーンの初期化

var container、stats、controls、compose、camera、scene、renderer、light、clickableObjects = []、mixer、mixerArr = []、manMixer;
var clock = new THREE.Clock();
初期化();
アニメーション化();
関数init() {
  コンテナ = document.createElement('div');
  document.body.appendChild(コンテナ);
  // シーン scene = new THREE.Scene();
  シーンを透明にする
  scene.fog = 新しい THREE.Fog(0xa0a0a0, 200, 1000);
  // パースペクティブ カメラ: 視野、アスペクト比、近い平面、遠い平面 camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
  カメラの位置を設定します(0, 4, 16);
  カメラ.lookAt(新しいTHREE.Vector3(0, 0, 0));
  // 半球光源: 屋外効果のためのより自然な光源を作成します。light = new THREE.HemisphereLight(0xefefef);
  ライトの位置を設定します(0, 20, 0);
  シーンにライトを追加します。
  // 指向性ライト light = new THREE.DirectionalLight(0x2d2d2d);
  ライトの位置を設定します(0, 20, 10);
  ライトをキャストします。
  シーンにライトを追加します。
  // アンビエントライト var ambientLight = new THREE.AmbientLight(0xffffff, .5);
  シーンにアンビエントライトを追加します。
  // グリッド var grid = new THREE.GridHelper(100, 100, 0xffffff, 0xffffff);
  グリッドの位置を設定します(0, -10, 0);
  グリッドの不透明度 = 0.3;
  グリッドのマテリアルを透明にする
  シーンにグリッドを追加します。
  レンダラー = 新しい THREE.WebGLRenderer({ アンチエイリアス: true、アルファ: true });
  レンダラーのピクセル比を設定します。
  レンダラーの出力エンコーディング = THREE.sRGBEncoding;
  レンダラーのサイズを設定します。
  //背景色を透明に設定しますrenderer.setClearAlpha(0);
  // 有効にする shadowrenderer.shadowMap.enabled = true;
  コンテナに子要素を追加します。
  // レンズ コントローラーを追加します。controls = new THREE.OrbitControls(camera, renderer.domElement);
  コントロールのターゲットを設定します(0, 0, 0);
  コントロールを更新します。
  window.addEventListener('resize', onWindowResize, false);
  // パフォーマンスプラグインを初期化します。stats = new Stats();
  コンテナに子要素を追加します。
}
// 画面ズーム関数 onWindowResize() {
  カメラのアスペクト比は window.innerWidth または window.innerHeight です。
  カメラの投影マトリックスを更新します。
  レンダラーのサイズを設定します。
}

📌シーン初期化の詳細なプロセスを知りたい場合は、私の別の記事「three.js を使用してクールな Acid スタイルの 3D ページを実現する」をお読みください。

ロゴモデルを読み込んでいます

FBXLoaderを使用してモデルをロードし、モデルの位置とサイズを設定します。

var ローダー = new THREE.FBXLoader();
loader.load('assets/models/meta.fbx', 関数(メッシュ) {
  mesh.traverse(関数(子) {
    子がメッシュである場合
      子.castShadow = true;
      子.receiveShadow = true;
    }
  });
  メッシュの回転y = Math.PI / 2;
  メッシュの位置を設定します(0, 1, 0);
  メッシュスケールを0.05に設定します。
  シーンを追加します(メッシュ);
});

材料の追加

この記事のLogoMeshPhysicalMaterialを使用しています。これは、照明計算をより適切にシミュレートできるPBR物理マテリアルです。ハイライトメッシュマテリアルMeshPhongMaterialレンダリング効果はよりリアルです。 THREE.TextureLoaderを使用して、マテリアルにmap属性を追加し、モデル テクスチャをロードします。下の画像は金属テクスチャのテクスチャマップです。

var texLoader = new THREE.TextureLoader();
loader.load('assets/models/meta.fbx', 関数(メッシュ) {
  mesh.traverse(関数(子) {
    子がメッシュである場合
      if (child.name === 'ベジェ円') {
        child.material = 新しい THREE.MeshPhysicalMaterial({
          マップ: texLoader.load("./assets/images/metal.png"),
          金属度: .2,
          粗さ: 0.1、
          露出: 0.4
        });
      }
    }
  });
})

アニメーションを追加

  • AnimationMixerオブジェクトは、シーン内の特定のオブジェクトのアニメーション プレーヤーです。シーン内の複数のオブジェクトが個別にアニメーション化される場合、オブジェクトごとに 1 つのAnimationMixerを使用できます。
  • AnimationMixerオブジェクトのclipActionメソッドは、アニメーションの実行を制御できるインスタンスを生成します。
loader.load('assets/models/meta.fbx', 関数(メッシュ) {
  メッシュ.アニメーション.マップ(アイテム => {
    メッシュ.traverse(子 => {
      // モデルには複数のオブジェクトがあり、それぞれに異なるアニメーションがあるため、この例ではベジェ円メッシュにのみアニメーションを追加します if (child.name === 'Bezier circle') {
        ミキサーを新しい THREE.AnimationMixer(child); にします。
        ミキサーArr.push(ミキサー);
        アニメーションクリップを item にします。
        アニメーションクリップの継続時間 = 8;
        clipAction を mixer.clipAction(animationClip).play() にします。
        アニメーションクリップ = clipAction.getClip();
      }
    })
  })
});

アニメーションを追加した後は、 requestAnimationFrameでアニメーションを更新することを忘れないでください。

関数アニメーション() {
  レンダラー.レンダリング(シーン、カメラ);
  // このメソッドの 2 回の実行間の時間間隔を取得します。let time = clock.getDelta();
  // ロゴアニメーションを更新 mixerArr.map(mixer => {
    ミキサー && mixer.update(時間);
  });
  // キャラクターアニメーションを更新 manMixer && manMixer.update(time);
  統計情報を更新します。
  アニメーションフレームをリクエストします(アニメーション化します);
}

読み込みの進行状況を表示

FBXLoader 2 つのコールバック関数も返します。これらを次のように使用して、モデルの読み込み進行状況の表示と読み込み失敗のロジック実装を表示できます。

<div class="読み込み中" id="読み込み中">
  <p class="text">読み込みの進行状況<span id="progress">0%</span></p>
<div>

var ローダー = new THREE.FBXLoader();
loader.load('assets/models/meta.fbx', メッシュ => {
}, 解像度 => {
  // 読み込みの進行状況 let progress = (res.loaded / res.total * 100).toFixed(0);
  document.getElementById('progress').innerText = progress;
  (進捗状況 === 100)の場合{
    document.getElementById('loading').style.display = 'なし';
  }
}, エラー => {
  // ロード失敗 console.log(err)
});

成果を達成する

クリックして素材を変更

ページのクリック イベントをリッスンし、 HREE.Raycasterを通じて現在のクリック オブジェクトを取得します。例を示すために、クリック オブジェクトのマテリアルをTHREE.MeshStandardMaterial変更し、ランダムなcolormetalnessroughnessを与えました。

// raycaster とマウス変数を宣言します var raycaster = new THREE.Raycaster();
var マウス = new THREE.Vector2();
関数 onMouseClick(イベント) {
  // マウスのクリック位置に基づいて、レイキャスターが必要とするポイントの位置を計算します。画面の中心を原点とし、値の範囲は -1 ~ 1 です。
  マウスのx = (イベントのクライアントX / ウィンドウのインナー幅) * 2 - 1;
  mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
  // マウスポイントの位置と現在のカメラマトリックスに基づいてレイキャスターを計算します
  raycaster.setFromCamera(マウス、カメラ);
  // レイキャスターのラインがすべてのモデルと交差する配列コレクションを取得します。let intersects = raycaster.intersectObjects(clickableObjects);
  交差する長さが0より大きい場合
    console.log(交差[0].オブジェクト)
    selectedObj = intersects[0].objectとします。
    selectedObj.material = 新しい THREE.MeshStandardMaterial({
      色: `#${Math.random().toString(16).slice(-6)}`,
      金属性: Math.random(),
      粗さ: Math.random()
    })
  }
}
window.addEventListener('click', onMouseClick, false);

📌メッシュ素材の詳細については、記事末尾のリンクを参照してください。

キャラクターモデルを読み込んでいます

キャラクターモデルの読み込みプロセスは、 Logoモデルの読み込みプロセスと同じです。かめはめ波を実行するキャラクターを追加しましたが、 Logoモデルの回転アニメーションと完璧にフィットするとは思っていませんでした😂

loader.load('assets/models/man.fbx', 関数(メッシュ) {
  mesh.traverse(関数(子) {
    子がメッシュである場合
      子.castShadow = true;
      子.receiveShadow = true;
    }
  });
  メッシュの回転y = Math.PI / 2;
  メッシュの位置を設定します(-14, -8.4, -3);
  メッシュスケールを設定します(0.085, 0.085, 0.085);
  シーンを追加します(メッシュ);
  manMixer = 新しい THREE.AnimationMixer(メッシュ);
  animationClip = mesh.animations[0] とします。
  clipAction を manMixer.clipAction(animationClip).play() にします。
  アニメーションクリップ = clipAction.getClip();
}, 解像度 => {
  進捗状況を (res.loaded / res.total * 100).toFixed(0) とします。
  document.getElementById('progress').innerText = progress + '%';
  if (数値(進捗) === 100) {
    document.getElementById('loading').style.display = 'なし';
  }
}, エラー => {
  コンソール.log(エラー)
});

この記事のサンプルキャラクターモデルは mixamo.com から取得したもので、何百ものキャラクターと何千ものアクションを自由に組み合わせて免費ダウンロードできます。好きなキャラクターやアニメーションアクションを選択して、 Three.js練習することができます。

要約する

この記事に含まれる主な知識ポイントは次のとおりです。

  • THREE.TorusGeometry : トーラス。
  • THREE.TorusKnotGeometry : トーラスノット。
  • THREE.TubeGeometry : チューブ。
  • Blender :モデリング。
  • FBXLoader : モデルをロードし、ロードの進行状況を表示します
  • TextureLoader : テクスチャをロードします。
  • THREE.AnimationMixer : アニメーションを読み込みます。
  • THREE.Raycaster : モデル上のクリックをキャプチャします。

🔗コード: https://github.com/dragonir/3d-meta-logo

参考文献

[1] three.jsを使用してクールなアシッドスタイルの3Dページを作成する

[2] ThreeJsにおけるマテリアルの理解

[3] スリーのアニメーションの第一印象

[4] メタバースとは何ですか?

著者: dragonir 記事URL: https://www.cnblogs.com/dragonir/p/15574412.html

Three.js で Facebook Metaverse 3D ダイナミック ロゴを実装する方法についての記事はこれで終わりです。Three.js 3D ダイナミック ロゴに関するその他の関連コンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • three.js を使って立体的な矢印線を描く詳細な手順
  • three.js を使用してクールなアシッドスタイルの 3D ページ効果を実現します
  • three.js で 3D ダイナミック テキスト効果を実現する方法
  • 露滴アニメーション効果を実装するための Three.js サンプル コード
  • three.js でのマルチスレッドの使用とパフォーマンステストの詳細な説明
  • JavaScript Three.js でテキストを作成する最初の経験

<<:  UTF-8 ファイルの Unicode 署名 BOM (バイト オーダー マーク) の問題

>>:  DIV共通属性コレクション

推薦する

Linux カーネル デバイス ドライバー カーネル リンク リストの使用上の注意

/******************** * カーネルにおけるリンクリストの応用********...

大規模なウェブサイトアーキテクチャを設計・構築する際に考慮すべき10の課題

ここでは、PHP、JSP、または .NET 環境については説明しません。アーキテクチャの観点から問題...

カレンダーウィジェットのネイティブJS実装

この記事の例では、カレンダーウィジェットを実装するためのjsの具体的なコードを参考までに共有していま...

MySQL 最適化: キャッシュ最適化

何人かのブロガーが私の記事を評価してくれたのは嬉しいです。マークと知り合ってからは、私は彼をフォロー...

要素内の TimePicker は時間の一部を無効にします (分単位で無効)

プロジェクトの要件は、日付と時刻を選択し、現在の時刻以降の時刻のみを選択し、最小レベルを分単位で無効...

CentOS 7のインストールと設定方法のグラフィックチュートリアル

この記事は、CentOS 7の詳細なインストールチュートリアルを参考のために記録します。具体的な内容...

Nginx ロケーション設定のチュートリアル (ゼロから)

基礎位置の一致順序は、「最初に正規表現に一致し、次に共通表現に一致」です。実際のロケーションの一致順...

HTMLインライン要素とブロックレベル要素の基本概念と使用例

HTML タグには、インライン要素とブロックレベル要素の 2 種類があります。まず、インライン要素と...

Docker 大規模プロジェクトのコンテナ化変革

仮想化とコンテナ化は、クラウドベースのプロジェクトでは避けられない 2 つの問題です。仮想化は純粋な...

docker run後にコンテナがExited (0)と表示される問題を解決する

Centos7 上で openresty 用の Dockerfile を作成し、ビルドしました。 d...

Dockerを使用してコンテナリソースを制限する方法

覗き見の問題サーバーでは、IIS サービスが複数のサイトを展開していると仮定すると、サイトの 1 つ...

DockerプライベートライブラリHarborのアーキテクチャとコンポーネントの説明

この記事では、Harbor アーキテクチャの構成と、実行時に各コンポーネントを使用する方法について説...

Dockerコンテナデータボリュームの原理と使用法の分析

コンテナデータボリュームとはデータがコンテナ内にある場合、コンテナを削除するとデータは失われます。例...

Linuxカーネルをコンパイルする方法

1. 必要なカーネルバージョンをダウンロードする2. オペレーティングシステムにアップロードする3....

MySQL の基本ステートメントを最適化するための 10 の原則の概要

序文データベースの応用において、プログラマーは継続的な実践を通じて多くの経験を積んできました。これら...