|
@@ -0,0 +1,546 @@
|
|
|
+Title: Three.js のプリミティブ
|
|
|
+Description: three.js プリミティブの旅。
|
|
|
+TOC: プリミティブ
|
|
|
+
|
|
|
+This article is one in a series of articles about three.js.
|
|
|
+The first article was [about fundamentals](threejs-fundamentals.html).
|
|
|
+If you haven't read that yet you might want to start there.
|
|
|
+この記事はthree.jsについてのシリーズ記事の一つです。
|
|
|
+最初の記事は[about fundamentals](threejs-fundamentals.html)です。
|
|
|
+もしまだ読まれていない場合は、そちらを先に始めるのが良いでしょう。
|
|
|
+
|
|
|
+Three.js has a large number of primitives. Primitives
|
|
|
+are generally 3D shapes that are generated at runtime
|
|
|
+with a bunch of parameters.
|
|
|
+Three.jsは多くのプリミティブがあります。
|
|
|
+プリミティブは、一般的に実行時にパラメータ群を指定して生成される、3D形状のことです。
|
|
|
+
|
|
|
+
|
|
|
+It's common to use primitives for things like a sphere
|
|
|
+for a globe or a bunch of boxes to draw a 3D graph. It's
|
|
|
+especially common to use primitives to experiment
|
|
|
+and get started with 3D. For the majority of 3D apps
|
|
|
+it's more common to have an artist make 3D models
|
|
|
+in a 3D modeling program like [Blender](https://blender.org)
|
|
|
+or [Maya](https://www.autodesk.com/products/maya/) or [Cinema 4D](https://www.maxon.net/en-us/products/cinema-4d/). Later in this series we'll
|
|
|
+cover making and loading data from several 3D modeling
|
|
|
+programs. For now let's go over some of the available
|
|
|
+primitives.
|
|
|
+地球儀の球体や、3Dグラフを描くための箱の集まりのようなものに、プリミティブを使うのは一般的です。
|
|
|
+実験したり3Dを始めたりするために、プリミティブを使うことは、とても普通です。
|
|
|
+3Dアプリケーションの多くは、3Dモデルを[Blender](https://blender.org)や
|
|
|
+[Maya](https://www.autodesk.com/products/maya/)や
|
|
|
+[Cinema 4D](https://www.maxon.net/en-us/products/cinema-4d/)といった
|
|
|
+3Dモデリングプログラムでを使って、アーティストに作ってもらう方が一般的です。
|
|
|
+このシリーズの後半では、いくつかの3Dモデリングプログラムからデータを作って
|
|
|
+読み込む方法にも言及するつもりです。
|
|
|
+では、利用できるプリミティブについて説明しましょう。
|
|
|
+
|
|
|
+
|
|
|
+Many of the primitives below have defaults for some or all of their
|
|
|
+parameters so you can use more or less depending on your needs.
|
|
|
+以下のプリミティブの多くは、一部または全てのパラメーターのデフォルト値があり、
|
|
|
+必要に応じて、多かれ少なかれ使うことができるでしょう。
|
|
|
+
|
|
|
+
|
|
|
+<div id="Diagram-BoxBufferGeometry" data-primitive="BoxBufferGeometry">立方体</div>
|
|
|
+<div id="Diagram-CircleBufferGeometry" data-primitive="CircleBufferGeometry">2次元の円</div>
|
|
|
+<div id="Diagram-ConeBufferGeometry" data-primitive="ConeBufferGeometry">A Cone円錐</div>
|
|
|
+<div id="Diagram-CylinderBufferGeometry" data-primitive="CylinderBufferGeometry">A Cylinder円筒</div>
|
|
|
+<div id="Diagram-DodecahedronBufferGeometry" data-primitive="DodecahedronBufferGeometry">A dodecahedron (12 sides)十二面体(12面)</div>
|
|
|
+<div id="Diagram-ExtrudeBufferGeometry" data-primitive="ExtrudeBufferGeometry">An extruded 2d shape with optional bevelling.
|
|
|
+Here we are extruding a heart shape. Note this is the basis
|
|
|
+for <code>TextBufferGeometry</code> and <code>TextGeometry</code> respectively.
|
|
|
+ベベルのオプション付きの、押し出された2次元形状。
|
|
|
+これは<code>TextBufferGeometry</code>と<code>TextGeometry</code>のそれぞれの基礎になることに注意してください。</div>
|
|
|
+<div id="Diagram-IcosahedronBufferGeometry" data-primitive="IcosahedronBufferGeometry">An icosahedron (20 sides)二十面体(20面)</div>
|
|
|
+<div id="Diagram-LatheBufferGeometry" data-primitive="LatheBufferGeometry">A shape generated by spinning a line. Examples would be: lamps, bowling pins, candles, candle holders, wine glasses, drinking glasses, etc... You provide the 2d silhouette as series of points and then tell three.js how many subdivisions to make as it spins the silhouette around an axis.ある軸の周りを回転してできた形状。例としてはこんなところでしょうか:ランプやボーリングのピン、ろうそく、ろうそく立て、ワイングラス、ドリンクグラス、などなど...。点の連続として2次元の輪郭を与え、その輪郭を軸の周りで回転させる際に、どのくらい細かくするかthree.jsに指示することができます。</div>
|
|
|
+<div id="Diagram-OctahedronBufferGeometry" data-primitive="OctahedronBufferGeometry">An Octahedron (8 sides)八面体(8面)</div>
|
|
|
+<div id="Diagram-ParametricBufferGeometry" data-primitive="ParametricBufferGeometry">A surface generated by providing a function that takes a 2D point from a grid and returns the corresponding 3d point.グリッドから2次元の点を取得し、対応する3次元の点を返す関数を作ることでできた表面。</div>
|
|
|
+<div id="Diagram-PlaneBufferGeometry" data-primitive="PlaneBufferGeometry">A 2D plane 2次元の四角形</div>
|
|
|
+<div id="Diagram-PolyhedronBufferGeometry" data-primitive="PolyhedronBufferGeometry">Takes a set of triangles centered around a point and projects them onto a sphereある点の周りに三角形の集まりを集めて球にする</div>
|
|
|
+<div id="Diagram-RingBufferGeometry" data-primitive="RingBufferGeometry">A 2D disc with a hole in the center 真ん中に穴のあいた円盤</div>
|
|
|
+<div id="Diagram-ShapeBufferGeometry" data-primitive="ShapeBufferGeometry">A 2D outline that gets triangulated 三角形分割された2次元の輪郭</div>
|
|
|
+<div id="Diagram-SphereBufferGeometry" data-primitive="SphereBufferGeometry">A sphere 球</div>
|
|
|
+<div id="Diagram-TetrahedronBufferGeometry" data-primitive="TetrahedronBufferGeometry">A tetrahedron (4 sides) 四面体(4面)</div>
|
|
|
+<div id="Diagram-TextBufferGeometry" data-primitive="TextBufferGeometry">3D text generated from a 3D font and a string 3Dフォントと文字による3Dテキスト</div>
|
|
|
+<div id="Diagram-TorusBufferGeometry" data-primitive="TorusBufferGeometry">A torus (donut) 円環(ドーナツ)</div>
|
|
|
+<div id="Diagram-TorusKnotBufferGeometry" data-primitive="TorusKnotBufferGeometry">A torus knot 円環(結び目)</div>
|
|
|
+<div id="Diagram-TubeBufferGeometry" data-primitive="TubeBufferGeometry">A circle traced down a path 経路をなぞった円</div>
|
|
|
+<div id="Diagram-EdgesGeometry" data-primitive="EdgesGeometry">A helper object that takes another geometry as input and generates edges only if the angle between faces is greater than some threshold. For example if you look at the box at the top it shows a line going through each face showing every triangle that makes the box. Using an <code>EdgesGeometry</code> instead the middle lines are removed. Adjust the thresholdAngle below and you'll see the edges below that threshold disappear.異なるジオメトリを入力として、その面同士の角度が閾値以上なら角を作り出した補助オブジェクト。例えば、記事の最初の方で紹介した立方体を見てみると、それぞれの面に、立方体を作っている全ての三角形の線が表示されています。<code>EdgesGeometry</code>を代わりに使うことで、面内の線はす全て除去されます。下記のthresholdAngleを調整してみてください。閾値以下の角が消えて見えるでしょう。</div>
|
|
|
+<div id="Diagram-WireframeGeometry" data-primitive="WireframeGeometry">Generates geometry that contains one line segment (2 points) per edge in the given geometry. Without this you'd often be missing edges or get extra edges since WebGL generally requires 2 points per line segment. For example if all you had was a single triangle there would only be 3 points. If you tried to draw it using a material with <code>wireframe: true</code> you would only get a single line. Passing that triangle geometry to a <code>WireframeGeometry</code> will generate a new geometry that has 3 lines segments using 6 points..
|
|
|
+1つの角ごとに1つの線分(2点)を持つジオメトリを生成する。WebGLは線分を作るのに2点が必要なので、この機能がないと、しばしば角を忘れたり、余分な角を作ってしまうでしょう。例えば、たった3点しかない1つの三角形あるとします。<code>wireframe: true</code>のマテリアルを使ってそれを描こうとした場合、1本の線分しか得られません。<code>WireframeGeometry</code>にその三角形のジオメトリを渡すと、6点からなる3つの線分を持った新しいジオメトリを生成します。</div>
|
|
|
+
|
|
|
+You might notice of most of them come in pairs of `Geometry`
|
|
|
+or `BufferGeometry`. The difference between the 2 types is effectively flexibility
|
|
|
+vs performance.
|
|
|
+ほとんどのプリミティブは`Geometry`か`BufferGeometry`の2つがあることに気づいたかもしれません。
|
|
|
+この2つの違いは、効果的な柔軟性とパフォーマンスです。
|
|
|
+
|
|
|
+`BufferGeometry` based primitives are the performance oriented
|
|
|
+types. The vertices for the geometry are generated directly
|
|
|
+into an efficient typed array format ready to be uploaded to the GPU
|
|
|
+for rendering. This means they are faster to start up
|
|
|
+and take less memory but if you want to modify their
|
|
|
+data they take what is often considered more complex
|
|
|
+programming to manipulate.
|
|
|
+`BufferGeometry`に基づいた基本形状はパフォーマンス志向の種類です。
|
|
|
+形状の頂点は、レンダリングのためGPUにアップロードするのに適した配列形式に、直接生成されます。
|
|
|
+これは、起動が速く省メモリであることを意味しますが、データの修正により複雑なプログラミングが必要になることが多いです。
|
|
|
+
|
|
|
+`Geometry` based primitives are the more flexible, easier to manipulate
|
|
|
+type. They are built from JavaScript based classes like `Vector3` for
|
|
|
+3D points, `Face3` for triangles.
|
|
|
+They take quite a bit of memory and before they can be rendered three.js will need to
|
|
|
+convert them to something similar to the corresponding `BufferGeometry` representation.
|
|
|
+`Geometry`に基づいた基本形状はより柔軟で、操作しやすい種類です。
|
|
|
+これらは、3次元の点のための`Vector3`、三角形のための`Face3`のようなJavaScriptに基づくクラスからできています。結構メモリを必要としますし、three.jsにレンダリングされる前に、対応する`BufferGeometry`表現の類似物に変換する必要があります。
|
|
|
+
|
|
|
+If you know you are not going to manipulate a primitive or
|
|
|
+if you're comfortable doing the math to manipulate their
|
|
|
+internals then it's best to go with the `BufferGeometry`
|
|
|
+based primitives. If on the other hand you want to change
|
|
|
+a few things before rendering you might find the `Geometry`
|
|
|
+based primitives easier to deal with.
|
|
|
+プリミティブを操作しないことが分かっているか、計算をして内部を操作することに抵抗がないなら、
|
|
|
+`BufferGeometry`に基づいたプリミティブを使うのがベストです。
|
|
|
+一方で、レンダリング前に少なからず変更を入れたいなら、`Geometry`に基づいたプリミティブを使うと、
|
|
|
+より簡単に扱うことができます。
|
|
|
+
|
|
|
+As an simple example a `BufferGeometry`
|
|
|
+can not have new vertices easily added. The number of vertices used is
|
|
|
+decided at creation time, storage is created, and then data for vertices
|
|
|
+are filled in. Whereas for `Geometry` you can add vertices as you go.
|
|
|
+単純な例だと、`BufferGeometry`は新しい頂点群を簡単に追加できません。
|
|
|
+使う頂点の数は作成時に宣言され、記憶領域が確保され、頂点群に関するデータが書き込まれます。
|
|
|
+一方、`Geometry`は、あなたがしたいように頂点群を追加できます。
|
|
|
+
|
|
|
+We'll go over creating custom geometry in [another article](threejs-custom-geometry.html). For now
|
|
|
+let's make an example creating each type of primitive. We'll start
|
|
|
+with the [examples from the previous article](threejs-responsive.html).
|
|
|
+[another article](threejs-custom-geometry.html)にカスタムジオメトリの作成について説明します。
|
|
|
+今は、それぞれの種類のプリミティブを作成する例を作ってみましょう。
|
|
|
+[examples from the previous article](threejs-responsive.html)から始めます。
|
|
|
+
|
|
|
+Near the top let's set a background color
|
|
|
+最初の方で、背景色を指定しましょう。
|
|
|
+
|
|
|
+```js
|
|
|
+const scene = new THREE.Scene();
|
|
|
++scene.background = new THREE.Color(0xAAAAAA);
|
|
|
+```
|
|
|
+
|
|
|
+This tells three.js to clear to lightish gray.
|
|
|
+これでthree.jsに、透明からライトグレーに変えるように伝えます。
|
|
|
+
|
|
|
+The camera needs to change position so that we can see all the
|
|
|
+objects.
|
|
|
+全てのオブジェクトを見られるよう、カメラも位置を変える必要があります。
|
|
|
+
|
|
|
+```js
|
|
|
+-const fov = 75;
|
|
|
++const fov = 40;
|
|
|
+const aspect = 2; // the canvas default
|
|
|
+const near = 0.1;
|
|
|
+-const far = 5;
|
|
|
++const far = 1000;
|
|
|
+const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
|
|
|
+-camera.position.z = 2;
|
|
|
++camera.position.z = 120;
|
|
|
+```
|
|
|
+
|
|
|
+Let's add a function, `addObject`, that takes an x, y position and an `Object3D` and adds
|
|
|
+the object to the scene.
|
|
|
+`addObject`関数を加えましょう。これはx座標とy座標と`Object3D`を取り、sceneにオブジェクトを追加します。
|
|
|
+
|
|
|
+```js
|
|
|
+const objects = [];
|
|
|
+const spread = 15;
|
|
|
+
|
|
|
+function addObject(x, y, obj) {
|
|
|
+ obj.position.x = x * spread;
|
|
|
+ obj.position.y = y * spread;
|
|
|
+
|
|
|
+ scene.add(obj);
|
|
|
+ objects.push(obj);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+Let's also make a function to create a random colored material.
|
|
|
+We'll use a feature of `Color` that lets you set a color
|
|
|
+based on hue, saturation, and luminance.
|
|
|
+ランダムに色付けされたマテリアルを作る関数も作成してみましょう。
|
|
|
+色相、彩度、輝度に基づいて色を設定できる、`Color`の機能を使ってみます。
|
|
|
+
|
|
|
+`hue` goes from 0 to 1 around the color wheel with
|
|
|
+red at 0, green at .33 and blue at .66. `saturation`
|
|
|
+goes from 0 to 1 with 0 having no color and 1 being
|
|
|
+most saturated. `luminance` goes from 0 to 1
|
|
|
+with 0 being black, 1 being white and 0.5 being
|
|
|
+the maximum amount of color. In other words
|
|
|
+as `luminance` goes from 0.0 to 0.5 the color
|
|
|
+will go from black to `hue`. From 0.5 to 1.0
|
|
|
+the color will go from `hue` to white.
|
|
|
+`hue`は色相環を0から1まで変化します。赤は0、緑は.33、青は.66です。
|
|
|
+`saturation`は0から1まで変化します。0 は無色で、1は最も彩度の高いです。
|
|
|
+`luminance`は0から1まで変化します。0は黒、1は白、0.5が色の最大量になります。
|
|
|
+言い換えると、`luminance`が0.0から0.5に変化するにつれて、色は黒から`hue`に
|
|
|
+変わります。0.5から1.0までは`hue`から白に変化します。
|
|
|
+
|
|
|
+```js
|
|
|
+function createMaterial() {
|
|
|
+ const material = new THREE.MeshPhongMaterial({
|
|
|
+ side: THREE.DoubleSide,
|
|
|
+ });
|
|
|
+
|
|
|
+ const hue = Math.random();
|
|
|
+ const saturation = 1;
|
|
|
+ const luminance = .5;
|
|
|
+ material.color.setHSL(hue, saturation, luminance);
|
|
|
+
|
|
|
+ return material;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+We also passed `side: THREE.DoubleSide` to the material.
|
|
|
+This tells three to draw both sides of the triangles
|
|
|
+that make up a shape. For a solid shape like a sphere
|
|
|
+or a cube there's usually no reason to draw the
|
|
|
+back sides of triangles as they all face inside the
|
|
|
+shape. In our case though we are drawing a few things
|
|
|
+like the `PlaneBufferGeometry` and the `ShapeBufferGeometry`
|
|
|
+which are 2 dimensional and so have no inside. Without
|
|
|
+setting `side: THREE.DoubleSide` they would disappear
|
|
|
+when looking at their back sides.
|
|
|
+私たちは`side: THREE.DoubleSide`もマテリアルに渡しました。
|
|
|
+これはthreeに形状を作るときに三角形の両面を描くように指示します。
|
|
|
+球体や立方体のような立体形状には、形状の内側を向いている裏側を描く
|
|
|
+理由がないのです。
|
|
|
+しかしこの例では、2次元で裏側が存在しない`PlaneBufferGeometry`や`ShapeBufferGeometry`のような
|
|
|
+ものを描こうとしています。
|
|
|
+`side: THREE.DoubleSide`を設定しないと、裏側を見たときに消滅してしまうでしょう。
|
|
|
+
|
|
|
+I should note that it's faster to draw when **not** setting
|
|
|
+`side: THREE.DoubleSide` so ideally we'd set it only on
|
|
|
+the materials that really need it but in this case we
|
|
|
+are not drawing too much so there isn't much reason to
|
|
|
+worry about it.
|
|
|
+`side: THREE.DoubleSide`に**not**が設定された方が、描画が速くなるため、
|
|
|
+理想的には本当に必要な時だけ設定するのが良いことを注記しておきます。
|
|
|
+しかし、この例だと、そんなにたくさん描画しないので、心配ありません。
|
|
|
+
|
|
|
+Let's make a function, `addSolidGeometry`, that
|
|
|
+we pass a geometry and it creates a random colored
|
|
|
+material via `createMaterial` and adds it to the scene
|
|
|
+via `addObject`.
|
|
|
+ジオメトリを渡すと`createMaterial`によってランダムに色が付いたマテリアルを作り、
|
|
|
+`addObject`によってシーンに追加する`addSolidGeometry`関数を作りましょう。
|
|
|
+
|
|
|
+```js
|
|
|
+function addSolidGeometry(x, y, geometry) {
|
|
|
+ const mesh = new THREE.Mesh(geometry, createMaterial());
|
|
|
+ addObject(x, y, mesh);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+Now we can use this for the majority of the primitives we create.
|
|
|
+For example creating a box
|
|
|
+さて、私たちの作るプリミティブの大多数に、この関数が使用できます。
|
|
|
+例えば、立方体を作ってみます。
|
|
|
+
|
|
|
+```js
|
|
|
+{
|
|
|
+ const width = 8;
|
|
|
+ const height = 8;
|
|
|
+ const depth = 8;
|
|
|
+ addSolidGeometry(-2, -2, new THREE.BoxBufferGeometry(width, height, depth));
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+If you look in the code below you'll see a similar section for each type of geometry.
|
|
|
+下記のコードを覗いてみると、それぞれの種類のジオメトリに対して、同じようなセクションがあります。
|
|
|
+
|
|
|
+Here's the result:
|
|
|
+結果はこのようになります:
|
|
|
+
|
|
|
+{{{example url="../threejs-primitives.html" }}}
|
|
|
+
|
|
|
+There are a couple of notable exceptions to the pattern above.
|
|
|
+The biggest is probably the `TextBufferGeometry`. It needs to load
|
|
|
+3D font data before it can generate a mesh for the text.
|
|
|
+That data loads asynchronously so we need to wait for it
|
|
|
+to load before trying to create the geometry. By promisifiying
|
|
|
+font loading we can make it mush easier.
|
|
|
+We create a `FontLoader` and then a function `loadFont` that returns
|
|
|
+a promise that on resolve will give us the font. We then create
|
|
|
+an `async` function called `doit` and load the font using `await`.
|
|
|
+And finally create the geometry and call `addObject` to add it the scene.
|
|
|
+上記のパターンには、2つの特筆すべき例外があります。
|
|
|
+最大のものは、おそらく`TextBufferGeometry`です。テキストのためのメッシュを作る前に、
|
|
|
+3Dフォントデータを読み込む必要があります。フォントの読み込みにpromiseを使えば、
|
|
|
+もっと速くすることができます。
|
|
|
+`FontLoader`を作ると、promiseを返す`loadFont`関数は解決時にフォントを提供してくれるでしょう。
|
|
|
+次に、`doit` と呼ばれる`async`関数を作り、`await`を使ってフォントを読み込みます。
|
|
|
+最後に、ジオメトリを作り、`addObject`を呼んでシーンに追加します。
|
|
|
+
|
|
|
+```js
|
|
|
+{
|
|
|
+ const loader = new THREE.FontLoader();
|
|
|
+ // promisify font loading
|
|
|
+ function loadFont(url) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ loader.load(url, resolve, undefined, reject);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ async function doit() {
|
|
|
+ const font = await loadFont('resources/threejs/fonts/helvetiker_regular.typeface.json'); /* threejsfundamentals: url */
|
|
|
+ const geometry = new THREE.TextBufferGeometry('three.js', {
|
|
|
+ font: font,
|
|
|
+ size: 3.0,
|
|
|
+ height: .2,
|
|
|
+ curveSegments: 12,
|
|
|
+ bevelEnabled: true,
|
|
|
+ bevelThickness: 0.15,
|
|
|
+ bevelSize: .3,
|
|
|
+ bevelSegments: 5,
|
|
|
+ });
|
|
|
+ const mesh = new THREE.Mesh(geometry, createMaterial());
|
|
|
+ geometry.computeBoundingBox();
|
|
|
+ geometry.boundingBox.getCenter(mesh.position).multiplyScalar(-1);
|
|
|
+
|
|
|
+ const parent = new THREE.Object3D();
|
|
|
+ parent.add(mesh);
|
|
|
+
|
|
|
+ addObject(-1, -1, parent);
|
|
|
+ }
|
|
|
+ doit();
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+There's one other difference. We want to spin the text around its
|
|
|
+center but by default three.js creates the text such that its center of rotation
|
|
|
+is on the left edge. To work around this we can ask three.js to compute the bounding
|
|
|
+box of the geometry. We can then call the `getCenter` method
|
|
|
+of the bounding box and pass it our mesh's position object.
|
|
|
+`getCenter` copies the center of the box into the position.
|
|
|
+It also returns the position object so we can call `multiplyScalar(-1)`
|
|
|
+to position the entire object such that its center of rotation
|
|
|
+is at the center of the object.
|
|
|
+もう一つ違いがあります。私たちはテキストをそれ自身の中心の周りで回転させたかったのですが、
|
|
|
+three.jsはデフォルトではテキストを左端を中心に回転するように作成します。
|
|
|
+これを回避するため、three.jsにジオメトリのバウンディングボックスの計算をさせることができます。
|
|
|
+そこで、バウンディングボックスの`getCenter`メソッドを呼んで、それをメッシュの位置オブジェクトに
|
|
|
+渡すことができます。
|
|
|
+`getCenter`が箱の中心をその位置にコピーします。位置オブジェクトも返すので、
|
|
|
+`multiplyScalar(-1)`を呼んでオブジェクト全体を置くことができます。
|
|
|
+結果、回転の中心は物体の中心になります。
|
|
|
+
|
|
|
+If we then just called `addSolidGeometry` like with previous
|
|
|
+examples it would set the position again which is
|
|
|
+no good. So, in this case we create an `Object3D` which
|
|
|
+is the standard node for the three.js scene graph. `Mesh`
|
|
|
+is inherited from `Object3D` as well. We'll cover [how the scene graph
|
|
|
+works in another article](threejs-scenegraph.html).
|
|
|
+For now it's enough to know that
|
|
|
+like DOM nodes, children are drawn relative to their parent.
|
|
|
+By making an `Object3D` and making our mesh a child of that
|
|
|
+we can position the `Object3D` wherever we want and still
|
|
|
+keep the center offset we set earlier.
|
|
|
+これだと、もし先の例のように`addSolidGeometry`を呼ぶと、
|
|
|
+再び位置が設定されてしまいますが、それはよくありません。
|
|
|
+そのため、この例では、three.jsのシーングラフでは標準的なノードである
|
|
|
+`Object3D`を作ります。`Mesh`は同様に`Object3D`を継承しています。
|
|
|
+[別の記事でどのようにシーングラフが働くか](threejs-scenegraph.html)扱います。
|
|
|
+とりあえず、DOMノードのように、子ノードは親ノードと関連して描かれるというように、
|
|
|
+知っていれば十分です。
|
|
|
+`Object3D`を作成し、メッシュをその子にすることで、どこにでも`Object3D`に配置し、
|
|
|
+先ほど設定した中心のオフセットを維持したままにできます。
|
|
|
+
|
|
|
+If we didn't do this the text would spin off center.
|
|
|
+こうしないと、テキストが中央からずれて回ってしまいます。
|
|
|
+
|
|
|
+{{{example url="../threejs-primitives-text.html" }}}
|
|
|
+
|
|
|
+Notice the one on the left is not spinning around its center
|
|
|
+whereas the one on the right is.
|
|
|
+左側のものは自身の中心の周りを回転していませんが、右側のものはそうなっていることに
|
|
|
+気づいてください。
|
|
|
+
|
|
|
+The other exceptions are the 2 line based examples for `EdgesGeometry`
|
|
|
+and `WireframeGeometry`. Instead of calling `addSolidGeometry` they call
|
|
|
+`addLineGeometry` which looks like this
|
|
|
+もう一つの例外は、`EdgesGeometry`と`WireframeGeometry`の、2つの直線に基づいた例です。
|
|
|
+`addSolidGeometry`を呼ぶ代わりに、このように`addLineGeometry`を呼んでいます。
|
|
|
+
|
|
|
+```js
|
|
|
+function addLineGeometry(x, y, geometry) {
|
|
|
+ const material = new THREE.LineBasicMaterial({color: 0x000000});
|
|
|
+ const mesh = new THREE.LineSegments(geometry, material);
|
|
|
+ addObject(x, y, mesh);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+It creates a black `LineBasicMaterial` and then creates a `LineSegments`
|
|
|
+object which is a wrapper for `Mesh` that helps three know you're rendering
|
|
|
+line segments (2 points per segment).
|
|
|
+黒色の`LineBasicMaterial`を作り、次に`LineSegments`オブジェクトを作成します。
|
|
|
+これは`Mesh`のラッパーで、あなたが線分(線分あたり2点)をレンダリングしようとしていることを
|
|
|
+threeが知る補助をします。
|
|
|
+
|
|
|
+Each of the primitives has several parameters you can pass on creation
|
|
|
+and it's best to [look in the documentation](https://threejs.org/docs/) for all of them rather than
|
|
|
+repeat them here. You can also click the links above next to each shape
|
|
|
+to take you directly to the docs for that shape.
|
|
|
+プリミティブのそれぞれは、作成する際に渡すことができる複数のパラメーターを持っていて、
|
|
|
+ここで繰り返すよりも[このドキュメントを覗いてもらう](https://threejs.org/docs/)ことが一番良いです。
|
|
|
+また、各形状の横にある上記のリンクをクリックすると、その形状のドキュメントに直接案内されます。
|
|
|
+
|
|
|
+There is one other pair of classes that doesn't really fit the patterns above. Those are
|
|
|
+the `PointsMaterial` and the `Points` class. `Points` is like `LineSegments` above in that it takes a
|
|
|
+a `Geometry` or `BufferGeometry` but draws points at each vertex instead of lines.
|
|
|
+To use it you also need to pass it a `PointsMaterial` which
|
|
|
+take a [`size`](PointsMaterial.size) for how large to make the points.
|
|
|
+
|
|
|
+上記のパターンに全然はまらない1組のクラスがほかにあります。
|
|
|
+それは`PointsMaterial`と`Points`クラスです。`Points`は`LineSegments`に似ていて、
|
|
|
+`Geometry`か`BufferGeometry`を引数に取ります。しかし、線の代わりに各頂点の点を描画します。
|
|
|
+使うためには、`PointsMaterial`も渡す必要があります。
|
|
|
+これは、点をどれくらい大きくするか決めるため[`size`](PointsMaterial.size) を取ります。
|
|
|
+
|
|
|
+```js
|
|
|
+const radius = 7;
|
|
|
+const widthSegments = 12;
|
|
|
+const heightSegments = 8;
|
|
|
+const geometry = new THREE.SphereBufferGeometry(radius, widthSegments, heightSegments);
|
|
|
+const material = new THREE.PointsMaterial({
|
|
|
+ color: 'red',
|
|
|
+ size: 0.2, // in world units
|
|
|
+});
|
|
|
+const points = new THREE.Points(geometry, material);
|
|
|
+scene.add(points);
|
|
|
+```
|
|
|
+
|
|
|
+<div class="spread">
|
|
|
+<div data-diagram="Points"></div>
|
|
|
+</div>
|
|
|
+
|
|
|
+You can turn off [`sizeAttenuation`](PointsMaterial.sizeAttenuation) by setting it to false if you want the points to
|
|
|
+be the same size regardless of their distance from the camera.
|
|
|
+カメラからの距離に関わらず店の大きさを同じにしたいのであれば、
|
|
|
+ [`sizeAttenuation`](PointsMaterial.sizeAttenuation) をfalseにすることで、止めることができます。
|
|
|
+
|
|
|
+```js
|
|
|
+const material = new THREE.PointsMaterial({
|
|
|
+ color: 'red',
|
|
|
++ sizeAttenuation: false,
|
|
|
++ size: 3, // in pixels
|
|
|
+- size: 0.2, // in world units
|
|
|
+});
|
|
|
+...
|
|
|
+```
|
|
|
+
|
|
|
+<div class="spread">
|
|
|
+<div data-diagram="PointsUniformSize"></div>
|
|
|
+</div>
|
|
|
+
|
|
|
+One other thing that's important to cover is that almost all shapes
|
|
|
+have various settings for how much to subdivide them. A good example
|
|
|
+might be the sphere geometries. Spheres take parameters for
|
|
|
+how many divisions to make around and how many top to bottom. For example
|
|
|
+説明が必要なもう一つの大切なことは、ほとんど全部の形状が、
|
|
|
+どのくらい小分けにするか決める、様々な設定を持っていることです。
|
|
|
+球体のジオメトリが良い例かもしれません。
|
|
|
+球体は周囲と上下にどのくらい分割するかのパラメータがあります。
|
|
|
+例えば、
|
|
|
+
|
|
|
+<div class="spread">
|
|
|
+<div data-diagram="SphereBufferGeometryLow"></div>
|
|
|
+<div data-diagram="SphereBufferGeometryMedium"></div>
|
|
|
+<div data-diagram="SphereBufferGeometryHigh"></div>
|
|
|
+</div>
|
|
|
+
|
|
|
+The first sphere has 5 segments around and 3 high which is 15 segments
|
|
|
+or 30 triangles. The second sphere has 24 segments by 10. That's 240 segments
|
|
|
+or 480 triangles. The last one has 50 by 50 which is 2500 segments or 5000 triangles.
|
|
|
+最初の球体は、周囲に5セグメント、高さ3なので、15セグメントまたは30個の三角形です。。
|
|
|
+二つ目の球体は、周囲に24セグメント、高さが10です。240セグメントか480個の三角形です。
|
|
|
+最後の球体は、周囲に50セグメント、高さが50で、2500セグメントか5000個の三角形です。
|
|
|
+
|
|
|
+It's up to you to decide how many subdivisions you need. It might
|
|
|
+look like you need a high number of segments but remove the lines
|
|
|
+and the flat shading and we get this
|
|
|
+どのくらい分割が必要かは、あなたが決めることです。
|
|
|
+多くのセグメントが必要なように見えるかもしれませんが、線を除去して、
|
|
|
+影をならすことで、このようになります。
|
|
|
+
|
|
|
+<div class="spread">
|
|
|
+<div data-diagram="SphereBufferGeometryLowSmooth"></div>
|
|
|
+<div data-diagram="SphereBufferGeometryMediumSmooth"></div>
|
|
|
+<div data-diagram="SphereBufferGeometryHighSmooth"></div>
|
|
|
+</div>
|
|
|
+
|
|
|
+It's now not so clear that the one on the right with 5000 triangles
|
|
|
+is entirely better than the one in the middle with only 480.
|
|
|
+If you're only drawing a few spheres, like say a single globe for
|
|
|
+a map of the earth, then a single 10000 triangle sphere is not a bad
|
|
|
+choice. If on the other hand you're trying to draw 1000 spheres
|
|
|
+then 1000 spheres times 10000 triangles each is 10 million triangles.
|
|
|
+To animate smoothly you need the browser to draw at 60 frames per
|
|
|
+second so you'd be asking the browser to draw 600 million triangles
|
|
|
+per second. That's a lot of computing.
|
|
|
+5000個の三角形による右側の球体の方が、たった480の真ん中の球体よりも
|
|
|
+全くもって良いかは、明らかではありません。
|
|
|
+地球の地図として一個の地球儀というように、もし、いくつかの球体を描くだけなら、
|
|
|
+10000個の三角形の球体でも悪い選択ではありません。
|
|
|
+一方で、1000個の球体を書こうとしているなら、1000個の球体におのおの10000個の三角形が
|
|
|
+かかり、一千万個の三角形になります。
|
|
|
+滑らかに動かすにはブラウザが一秒間に60フレーム描画する必要があるため、
|
|
|
+ブラウザは1秒間に6億個の三角形を描画する必要があります。
|
|
|
+それは計算が多すぎます。
|
|
|
+
|
|
|
+Sometimes it's easy to choose. For example you can also choose
|
|
|
+to subdivide a plane.
|
|
|
+選ぶのが簡単な時もあります。例えば、平面の細分化を選ぶこともできます。
|
|
|
+
|
|
|
+<div class="spread">
|
|
|
+<div data-diagram="PlaneBufferGeometryLow"></div>
|
|
|
+<div data-diagram="PlaneBufferGeometryHigh"></div>
|
|
|
+</div>
|
|
|
+
|
|
|
+The plane on the left is 2 triangles. The plane on the right
|
|
|
+is 200 triangles. Unlike the sphere there is really no trade off in quality for most
|
|
|
+use cases of a plane. You'd most likely only subdivide a plane
|
|
|
+if you expected to want to modify or warp it in some way. A box
|
|
|
+is similar.
|
|
|
+左側の四角形は2つの三角形から成ります。右側の四角形は200個の三角形から成ります。
|
|
|
+球体の時と異なり、四角形の場合だと、質的なトレードオフは全くありません。
|
|
|
+いくつかの用途で、大抵の場合、四角形を改造したり歪めたりしたいと思っている時に、
|
|
|
+四角形を細分化するだけで良いでしょう。
|
|
|
+立方体も同様です。
|
|
|
+
|
|
|
+So, choose whatever is appropriate for your situation. The less
|
|
|
+subdivisions you choose the more likely things will run smoothly and the less
|
|
|
+memory they'll take. You'll have to decide for yourself what the correct
|
|
|
+tradeoff is for your particular situation.
|
|
|
+あなたの状況にふさわしいものを選びましょう。
|
|
|
+選んだ細分化が少ないほど、より滑らかに動いて、省メモリになることでしょう。
|
|
|
+あなたの特定の状況にふさわしい、正しいトレードオフは何か、決めなければいけません。
|
|
|
+
|
|
|
+If none of the shapes above fit your use case you can load
|
|
|
+geometry for example from a [.obj file](threejs-load-obj.html)
|
|
|
+or a [.gltf file](threejs-load-gltf.html).
|
|
|
+You can also create your own [custom Geometry](threejs-custom-geometry.html)
|
|
|
+or [custom BufferGeometry](threejs-custom-buffergeometry.html).
|
|
|
+あなたの用途に適した形状がないなら、例えば、[.obj file](threejs-load-obj.html)
|
|
|
+や[.gltf file](threejs-load-gltf.html)からジオメトリを読み込むことができます。
|
|
|
+[カスタムジオメトリ](threejs-custom-geometry.html)
|
|
|
+や[カスタムBufferGeometry](threejs-custom-buffergeometry.html)を作ることもできます。
|
|
|
+
|
|
|
+Next up let's go over [how three's scene graph works and how
|
|
|
+to use it](threejs-scenegraph.html).
|
|
|
+次は、[threeのシーングラフの動き方と使い方](threejs-scenegraph.html)を説明します。
|
|
|
+
|
|
|
+<link rel="stylesheet" href="../resources/threejs-primitives.css">
|
|
|
+<script type="module" src="../resources/threejs-primitives.js"></script>
|
|
|
+
|