Three.js とは何ですか?

0 株式
0
0
0
0

導入

Three.js は多くの機能を備えているため、他の 3D 分野との関連性がやや分かりにくい場合があります。また、その範囲は常に進化しているため、簡単にまとめることは難しく、ここでの考察は主観的なものとなります。.

JavaScript 3Dライブラリ

このプロジェクトの目標は、軽量で使いやすい3Dライブラリを作成することです。このライブラリはレンダリングを提供します。 、 、CSS3D、WebGL です。.

これはgithubリポジトリの公式説明です。実はかなりうまくまとめられていますが、この文中の各トピックはそれぞれが幅広いトピックであり、three.jsが扱うのはそれだけではありません。.

このライブラリ自体はJavaScriptで記述されており、JavaScript環境での使用を想定しています。多くの場合、クライアント側、つまりデバイスのWebブラウザで実行されます。しかし、Node.jsやヘッドレスブラウザを利用すれば、サーバー側でも使用できます。まず思い浮かぶのはレンダリングでしょう。サーバー上でプレビュー画像を表示するといった用途もあるでしょうが、three.jsには豊富な数学ライブラリがあるため、3D計算だけを指す場合もあります。これは非常に幅広い用語です。「3D」という言葉には様々な意味があり、多くの場合「グラフィックス」を思い浮かべます。.

three.js を使ったプロジェクトの多くは、ユーザーインタラクションによって即座に視覚的なフィードバックが得られるリアルタイム 3D グラフィックスです。その他の種類の 3D グラフィックスとしては、映画に登場する様々なエフェクトや人工キャラクター、あるいは印刷物や Web カタログで目にする様々な「レンダリング」などがあります(例えば、IKEA の Web サイトは製品写真がすべてコンピューターで生成された 3D グラフィックスで溢れています)。.

これらすべてのうち、3D数学はサブセットです。3Dグラフィックスは数学なしでは実現できませんが、コンピュータ言語はデフォルトでは3Dの概念を理解しません。そこでライブラリが登場し、これらの数学演算を抽象化し、場合によっては最適化し、Matrix4や.dot()のような高水準インターフェースを公開します。.

Three.jsには、3D数学に特化したクラスを含む独自の数学ライブラリが付属しています。この数学処理のみを扱うスタンドアロンライブラリもありますが、Three.jsでは、これははるかに大規模なシステムのサブセットにすぎません。.

レンダリングもライブラリの大きな役割の一つですが、ここでも少し複雑になります。WebGLは非常に特殊で、他のライブラリとは一線を画しています。.

Canvas、SVG、CSSでは、レンダリングは完全に3Dで行われます。これらのAPIには、非3Dオブジェクトを描画するためのライブラリが多数用意されているか、デフォルトで非3Dオブジェクトを描画します(CSSは2Dの長方形を描画し、Canvasは様々な2D図形を描画します)。しかし、実際に3Dレンダリングを行うには、魔法のようなタッチと3Dの計算が必要です。.

魔法のようなタッチは、主にインターフェースの抽象化という形で実現されます。例えば、要素の3D状態の管理などです。 <div> CSSで3Dに変換するのは非常に難しいです。Canvas APIを使って3D風に描画するには、多くのロジックが必要です。WebGLははるかに複雑です。.

Three はこれらすべての API を render() のような単純なものに抽象化しますが、そのためには「3D ワールド」がどのようなものであるかを示す汎用的な表現が必要です。.

シーン図

three.jsには、「3Dワールド」の一般的な抽象化として機能する領域があります。シーングラフとは、3Dシーン(ワールド)内のオブジェクト同士の関係性を記述するために使用されるデータ構造です。これはベクターグラフィックスの階層構造を記述する便利な方法であるため、実際には3Dである必要はありません。より具体的には、「ルートノード」を持つ「ノード」から枝分かれする「ツリー」です。three.jsでは、このデータ構造の基底クラスはObject3Dです。.

これはDOMツリーとほぼ同じです。THREE.Sceneも同様です <body> となり、それ以外はすべて枝になります。DOMでは物事を配置できますが、その範囲は比較的限られています。回転は通常、軸を中心に行われ、左右または上下に動かします。3Dシーングラフでは、より自由度が高くなります。.

シーン3は仮想DOMのようなものです。このツリー上で操作を実行し、状態を設定します。そして、その状態のスナップショットを視覚的に取得したい場合(例えば、連続ループやユーザーインタラクション/状態変化など)は、render(シーン)を呼び出します。何かが変化した際にDOMツリー全体を更新したくない場合、要素は、たとえ 1 つの要素の位置が変わっただけでも、ビュー全体をクリアしてすべてを再描画する必要があります。.

1つ <div> 1つは <div> THREE.Mesh(&#039;sun&#039;)-&gt;THREE.Mesh(&#039;earth&#039;) という親子関係に似ています。CSS ルールは THREE.Material に似ており、color:&#039;red&#039; のような記述によって魔法が起こり、何かが赤くなります。最後に、threeRenderer.render(scene) の呼び出しは、ブラウザが CSS ルールを含む HTML ページを読み込むのと似ています。.

Mesh、Scene、Camera、Lightはすべてこの汎用クラスのサブクラスです。これにより、「シーン」に「ボックス」を追加したり、「カメラ」に「ライト」を追加したりできるようになります。.

シンプルな構造は非常にフラットです。ルートノードは「世界」とみなされ、「地面」、「家」、「太陽」、「カメラ」を子ノードとして持つことができます。.

THREE.Scene('world')
|-THREE.Mesh('ground')
|-THREE.Mesh('house')
|-THREE.Light('sun')
|-THREE.Camera('main')

これは、レンダラーに入力して視覚的な結果を得るのに十分な情報です。シーンによっては、地面と丘の上の家という異なるものを表す2つのグリッドがあります。照明はそれらの照明方法(朝、昼、フラッシュライト)を定義し、オブジェクト(カメラ)は私たちの視点、つまり世界の見方を定義します。.

結果は異なる場合があります。たとえば、CSS は非常に軽いレンダリングに制限されていますが、WebGL は影と一般的に高い忠実度を提供できます。.

この構造を通して、3Dワールドが管理されます。季節によって日光が家屋にどのような影響を与えるかをシミュレートしたい場合は、プログラムによってワールド内の光の位置と方向を変更します。シーングラフの役割は、この「位置」フックを公開することですが、実際にアニメーション化するには、独自のロジックを実装する必要があります。3Dシーンをアニメーション化する簡単な方法は、three.jsの「トゥイーン」ライブラリを使用することです。.

これらはすべて理論上のみに当てはまることであり、シーンのレンダリングを自由に変更することはできないかもしれません。しかし、これは主に「マテリアル」がシーングラフと重複し、レンダリングと連動していることによるものです。例えば、 <div> または、WebGL マテリアルで表現できる金属としては表示されませんが、赤色にすることはできます。これはすべてのマテリアルで可能です。.

結局のところ、Object3D は依然として汎用的であり、ノード間の空間的および階層的な関係は「シーン グラフ」を通じて記述されます。.

簡単に言えば、これは scene.add(my_foo) を複数回呼び出した後に得られるシーン変数です。.

ウェブGL

WebGLは非常に特殊なため、既存のthree.jsアプリケーションの99%で使用されていると考えられます。これは大きなトピックなので、まずは代替手段について簡単に概観しておく価値があるかもしれません。.

キャンバス、CSS、SVG

これらはすべてAPIです。プログラマーがブラウザに特定のものを描画するように指示するために使用できるインターフェースです。CSSはWeb上で最も一般的なインターフェースです。CSSがないと、すべてがプレーンテキストのように見えるからです。歴史的には、3Dとは何の関係もありませんでした。.

Canvas は実際には描画に同じ WebGL 要素を使用しますが、コンテキストが異なります。このコンテキストは実際には「2D」と呼ばれますが、そもそも 3D は擬似的なものであり、現実のものであれ仮想のものであれ、常に何らかの 2D 面を描画するため、このコンテキストを使って 3D グラフィックスを描画することもできます。.

SVGは、ロゴやアイコンなどの表現によく使われる、3D以外のAPIです。しかし、線などの基本的な要素を表現できるため、3Dコンテキスト(地図上のオーバーレイや、空間認識可能なUI/HUD要素など)でも表現できます。.

共通点は、どれも3Dでの使用を想定していないということです。もう一つの重要な特徴は、これらはすべて高レベルであるということです。つまり、以前は別の用途を想定していたのです。例えば、これら3つはすべて「円」の描画方法を知っています。Canvasではこれは明示的な図形ですが、CSSでは境界線の半径を指定しなければならない場合もありますが、最終的には円への非常に直接的なアクセスが可能になります。.

WebGLは非常に低レベルで、3Dグラフィックスの概念についてはあまり理解していません。3Dグラフィックスは特定の数学的計算を必要とし、しかも膨大な量になります。高解像度の画面とそのピクセル数を少し考えてみてください。もし、ある量の光が表面にどのような影響を与えるかを判断するために、各ピクセルごとに計算を行う必要があり、これを1秒間に60回も実行しなければならないとしたら、その計算量は膨大になります。.

グラフィックプロセッサ

ノートパソコン、デスクトップパソコン、携帯電話、さらには腕時計など、ほとんどのコンピューターには、これらの3D演算を効率的に計算し、インタラクティブなグラフィックスの表示を可能にする何らかのハードウェアデバイスが搭載されています。これはグラフィックス・プロセッシング・ユニット(GPU)と呼ばれます。.

メインプロセッサとは異なり、並列に実行される特定の数学演算など、異なる目的のために構築されています。.

ブラウザプログラミングに JavaScript を使用するのと同様に、グラフィック カードプログラミングには WebGL を使用します。.

まあ、概念的にはその通りですが、実際には全く異なるものです。WebGLはJavaScriptコード(命令)と、実際に計算を行う全く異なる言語(GLSL)で構成されています。HTMLとJavaScript、そしてそれらがページ上でどのように連携するかには、いくつかの類似点があります。.

2次元と3次元

このハードウェアアクセラレーションの恩恵を受けるのは3Dだけではありません。ビデオ処理にも有効です。グラフィックカードをプログラムすることで、色を変更したり、ライブビデオフィードの画像を変更したりできます。.

WebGLは非常に低レベルで汎用的です。2Dや3Dについては理解できませんが、メモリ、バッファ、コマンドキュー、シェーダーなどについては理解できます。.

並列プログラミングの扱い方は、JavaScriptでのプログラミングとは異なります。よくある問題は、異なるスレッドが共有変数にどのようにアクセスするかということです。.

この異なるパラダイムとは、GLSLと呼ばれる全く別の言語が存在することを意味します。これは、あらゆる低レベルグラフィックスAPIに搭載されているシェーディング言語です。大きな数値を扱う実際のロジックはGLSLで記述しますが、唯一の利点は機械語を書かなくて済むことです。.

WebGL APIのもう一つの部分は、GPUに何かを指示するためのJavaScriptバインディングです。シェーダーは「計算Aを実行する」、バインディングは「100万回実行する」といった具合です。.

Aが何であるかを計算するのはプログラマー次第です。3D関連の何かかもしれませんし、ビデオをぼかすカーネルかもしれません。.

これらの計算とコマンドを抽象化していくと、three.js になります。.

連携して動作するレンダリング

非常に理にかなったユースケースの一つは、レンダラーを組み合わせて「3D」に適したものを描画することです。WebGLは大量の数値を処理し、非常にリアルな画像を作成できますが、テキストや一部の線の処理には弱いです。レンダリングされたテキストの追加レイヤーはCSSとキャンバスレンダラーで処理でき、パスや様々な線はSVGで処理できます。.

3.WebGLレンダラー

これらの低レベルの処理はすべて、three.jsのWebGLRendererクラスによって抽象化されています。これにより、立方体がGPUメモリ内の数値の集合に変換されます。.

皮肉なことに、three.js レンダラーの中で 3D グラフィックスを必要としないのは WebGL だけですが、3D グラフィックスには最適な選択肢です。他のレンダラーは 2D API を使って 3D を模倣しますが、WebGL は汎用的な並列コンピューティング API を使って意図的に 3D を実現します。しかし、だからといって、ライブビデオストリームの処理に WebGL のみを使用するというシナリオが排除されるわけではありません。WebGL から十分に抽象化されているため、この用途には役立ちますが、実際に使用するライブラリは全体の 3 分の 1 程度でしょう。WebGL を使ってレスポンシブな UI レイヤーを構築したり、スーパーマリオのようなプラットフォームゲームを開発したりする場合でも、three.js は優れたツールとなるでしょう。.

ライブラリの3分の1しか使用していないということは、その用途には別のツールの方が適している、あるいはthree.jsのサブセットを作成するだけで済む可能性があることを意味します。スーパーマリオと動画処理のどちらの例でも、PlaneGeometryと、おそらくマテリアルタイプさえあれば十分でしょう。.

3つの数学

3Dで特定の数学演算を実行するJavaScriptコード。JSにはデフォルトでMath.pow()がありますが、Quaternion.inverse()はありません。これらのクラスを使うことで、レンダリングを必要としないアルゴリズムを記述できます。例えば、誰が射撃しているのか、誰が大量のレイを発射しているのかを検証するゲームサーバーなどです。ただし、描画は行いません。.

3つのシーングラフ

Object3Dのサブクラスのファミリーは、ツリーデータ構造を形成し、「3D世界」とその中のオブジェクトの関係性を記述します。概念的には抽象的ですが、コードを読み解くと、具体的なレンダリングである程度表現できます。.

3つのレンダリング

汎用グラフを画面上またはバッファ(例えばサーバー側で作成)上の視覚的表現に変換するレイヤーです。この目的を達成するために、様々な技術が利用されます。.

THREE-WebGLレンダラー

ハードウェアアクセラレーションに対応し、3Dの多くの概念を理解しながらも2D(さらには一般的なコンピューティング)にも使用できる特別なレンダラーです。これらはthree.jsの主要な構成要素だと私は考えています。私は「3D」を「グラフィックス」と読み替えることが多いのですが、これはWebGLRendererにのみ当てはまります。.

Three.js はゲーム エンジンではありません。

ウェブ上で3D(またはグラフィックス)を必要とする人が全員ゲームを作っているわけではありません。ゲームエンジンは通常、3Dワールドの記述と表示以外にも多くの最適化を行います。ゲームによってニーズは異なり、リアルタイムストラテジーやファーストパーソンシューティングゲーム向けの物理演算システムやレンダリングシステムのニーズは大きく異なります。こうした状況はすべてコードの増加を意味し、製品カタログの一部として3Dモデルを作成したいだけの人にとっては、これは不必要であるだけでなく、望ましくありません。もちろん、ゲームエンジンを1つ構築し、レンダリングとエンジンブロックの構築に3つのエンジンを使うことも可能です。.

Three.js の読み込みが遅い

確かに、コアには一部のアセット用の複数のローダーがありますが、gltfやfbxなどの一般的なフォーマットはすべて独立しています。Threejsは、アセットの取得方法を気にしません。アセットを適切に解析して3Dオブジェクトを作成できれば問題ありません。Threejsにとって、gltfファイルのメッシュと手続き型球体の間に違いはありません。多くのクリエイティブな例では、立方体と球体が使用され、Three.js自体以外は何もロードされません。コアローダーは非常に汎用的で、画像やファイルを読み込み、マテリアルやテクスチャなどのThreejsオブジェクトを直接表現します。フォーマット固有のローダーは、これらの構成要素を使って構築されます。.

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

あなたも気に入るかもしれない