はじめに
私はテストの一部で Three.js を使用しましたが、ブラウザで 3D を開始する際の煩雑な作業を抽象化できる優れたライブラリです。カメラ、オブジェクト、ライト、マテリアルなどを作成できます。レンダラを選択することもできます。つまり、HTML 5 のキャンバス、WebGL、SVG のいずれを使用してシーンを描画するかを決定できます。オープンソースであるため、プロジェクトに参加することもできます。ただし、ここではエンジンとして遊んで学んだことを中心に、基本的な部分について説明します。
Three.js は優れたライブラリですが、苦労することもあるかもしれません。通常、サンプル、リバース エンジニアリング、(私の場合は間違いなく)特定の機能の探索にかなりの時間を費やす必要があります。また、必要に応じて GitHub で質問することも必要です。ご不明な点がございましたら、Mr. doob と AlteredQualia が非常に役立つと思います。
1. 基本情報
3D に関する基本的な知識と、JavaScript に関する十分な知識があることを前提としています。そうでない場合は、少し学習してから試してみることをおすすめします。混乱する可能性があるためです。
3D 世界には、次のようなものがいくつかあります。ここでは、作成プロセスについて説明します。
- シーン
- レンダラ
- カメラ
- 1 ~ 2 つのオブジェクト(マテリアルあり)
もちろん、クールなことができるので、ぜひブラウザで 3D を試してみてください。
2. サポート
ブラウザでのサポートについて、簡単に説明します。私の経験では、Google の Chrome ブラウザは、サポートされているレンダラと基盤となる JavaScript エンジンの速度の点で、最も適したブラウザです。Chrome は Canvas、WebGL、SVG をサポートしており、非常に高速です。バージョン 4 の登場により、Firefox がそれに続いています。JavaScript エンジンは Chrome よりも少し遅いようですが、レンダリング技術のサポートは優れています。Opera と Safari は WebGL のサポートを追加する予定ですが、現在のバージョンではキャンバスのみがサポートされています。Internet Explorer(バージョン 9 以降)はキャンバス レンダリングのみをサポートしています。Microsoft が WebGL 機能を追加する予定については、何も聞いていません。
3. シーンを設定する
ここでは、すべてのレンダリング技術をサポートするブラウザを選択し、キャンバスまたは WebGL でレンダリングすることを前提としています。これらは標準的な選択肢です。Canvas は WebGL よりも広くサポートされていますが、WebGL はグラフィック カードの GPU で実行されます。つまり、CPU はレンダリング以外の他のタスク(実行しようとしている物理やユーザー操作など)に集中できます。
選択したレンダラに関係なく、JavaScript はパフォーマンスを重視して最適化する必要があります。3D はブラウザにとって軽量なタスクではありません(可能であるだけでも素晴らしいことです)。コードのボトルネックを見つけて、可能であれば削除してください。
では、ダウンロードして HTML ファイルに three.js を含めたと仮定して、シーンの設定方法を説明します。この場合、次のように指定します。
// set the scene size
var WIDTH = 400,
HEIGHT = 300;
// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');
// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
VIEW_ANGLE,
ASPECT,
NEAR,
FAR );
var scene = new THREE.Scene();
// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
// attach the render-supplied DOM element
$container.append(renderer.domElement);
難しい作業ではありません。
4. メッシュを作成する
シーン、カメラ、レンダラ(サンプルコードでは WebGL を選択しました)はありますが、実際に描画するものはありません。Three.js には、いくつかの標準ファイル形式の読み込みがサポートされています。これは、Blender、Maya、Cinema4D などのモデルを出力する場合に便利です。簡単にするために(結局のところ、まずは始めることです!)プリミティブについて説明します。プリミティブは、球、平面、立方体、円柱など、比較的基本的なジオメトリ メッシュです。Three.js では、次のようなプリミティブを簡単に作成できます。
// set up the sphere vars
var radius = 50, segments = 16, rings = 16;
// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),
sphereMaterial);
// add the sphere to the scene
scene.add(sphere);
問題ありませんが、球体の素材はどうすればよいですか?コードでは変数 sphereMaterial を使用していますが、まだ定義していません。まず、素材についてもう少し詳しく説明する必要があります。
5. 材質
これは間違いなく、Three.js で最も便利な機能の 1 つです。メッシュに適用できる一般的な(非常に便利な)マテリアルがいくつか用意されています。
- 「基本」 - 「ライトなし」でレンダリングすることを意味します。
- ランバート
- Phong
他にも多くの機能がありますが、簡潔にするため、ご自身で見つけてください。特に WebGL の場合、これらの資料は非常に役立ちます。その理由は、これは、WebGL ではレンダリングされるすべてのものにシェーダーを記述する必要があるためです。シェーダーは、それ自体が大きなトピックですが、簡単に言うと、GLSL(OpenGL シェーダー言語)で記述され、GPU に外観を指示します。つまり、照明や反射などの数学を模倣する必要があります。すぐに複雑な作業になる可能性があります。Three.js では、不要な場合はこの処理を行う必要はありません。この処理は抽象化されます。シェーダーを記述する場合は、MeshShaderMaterial でも記述できるため、柔軟な設定が可能です。
ただし、今はラバート マテリアルを球に適用しましょう。
// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});
なお、マテリアルを作成するときに、色以外にも、スムージング マップや環境マップなど、指定できるプロパティがあります。マテリアルに設定できるさまざまなプロパティ、およびエンジンが提供するオブジェクトについては、Wiki ページをご覧ください。また、最近 threejs.org が立ち上がり、API をより魅力的に表示できるようになりました。
6. 照明!
この時点でシーンをレンダリングすると、赤い円が表示されます。Lambert マテリアルが適用されていても、シーンに光がないため、デフォルトでは、フラット カラーリングと同じように、完全なアンビエント ライトにフォールバックします。簡単な光源を追加して、この問題を解決しましょう。
// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
7. レンダリング
これで、レンダリングする準備がすべて整いました。実際には、次のようにする必要があります。
// draw!
renderer.render(scene, camera);
ただし、レンダリングは複数回行う必要があるため、ループする場合は requestAnimationFrame を使用する必要があります。これは、ブラウザでアニメーションを処理する最もスマートな方法です。まだ完全にサポートされていないため、Paul Irish のシムを確認することを強くおすすめします。
8. 一般的なオブジェクト プロパティ
Three.js のコードをよく見ると、多くのオブジェクトが Object3D から「継承」されていることがわかります。これは、位置、回転、スケール情報など、非常に便利なプロパティを含むベース オブジェクトです。特に、Sphere は Object3D から継承するメッシュであり、独自のプロパティ(ジオメトリとマテリアル)を追加します。なぜこれらのことを言っているのでしょうか?何もしない球体を画面に表示するだけということはまずありません。これらのプロパティは、メッシュとマテリアルの基盤となる詳細をその場で操作できるため、検討する価値があります。
// sphere geometry
sphere.geometry
// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array
// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same
9. Dirty Little Secrets
Three.js の注意点として、メッシュの頂点などを変更しても、レンダリング ループでは何も変化しない点があります。その理由は、これは、Three.js が最適化の一環としてメッシュのデータをキャッシュに保存するためです。実際に必要なのは、何かが変更されたことを Three.js に通知して、必要なものを再計算できるようにすることです。手順は次のとおりです。
// changes to the vertices
sphere.geometry.__dirtyVertices = true;
// changes to the normals
sphere.geometry.__dirtyNormals = true;
他にも方法はありますが、私が見つけたのはこの 2 つが最も便利です。当然ながら、不要な計算を避けるため、変更された項目のみにフラグを立ててください。
まとめ
Three.js の簡単な紹介がお役に立てば幸いです。実際に手を動かして試してみるのが一番です。ぜひおすすめします。ブラウザでネイティブに実行される 3D は非常に楽しいものです。Three.js などのエンジンを使用すると、多くの問題を回避して、本当にクールなものを作成できます。少しでもお役に立てるよう、このラボの記事でソースコードをラップしましたので、参照用としてご利用ください。気に入っていただけたら、Twitter で教えてください。いつでもコメントをお待ちしています。