|
@@ -5,15 +5,15 @@ A [previous article](threejs-primitives.html) gave a tour of
|
|
the various built in primitives included in THREE.js. In this
|
|
the various built in primitives included in THREE.js. In this
|
|
article we'll cover making our own geometry.
|
|
article we'll cover making our own geometry.
|
|
|
|
|
|
-Just to be clear, if you are serious about making 3D content
|
|
|
|
|
|
+Just to be clear, if you are serious about making 3D content,
|
|
the most common way is to use a 3D modeling package like
|
|
the most common way is to use a 3D modeling package like
|
|
-[blender](https://blender.org),
|
|
|
|
|
|
+[Blender](https://blender.org),
|
|
[Maya](https://www.autodesk.com/products/maya/overview),
|
|
[Maya](https://www.autodesk.com/products/maya/overview),
|
|
[3D Studio Max](https://www.autodesk.com/products/3ds-max/overview),
|
|
[3D Studio Max](https://www.autodesk.com/products/3ds-max/overview),
|
|
[Cinema4D](https://www.maxon.net/en-us/), etc...
|
|
[Cinema4D](https://www.maxon.net/en-us/), etc...
|
|
You'd build a model and then export to [gLTF](threejs-load-gltf.html)
|
|
You'd build a model and then export to [gLTF](threejs-load-gltf.html)
|
|
or [.obj](threejs-load-obj.html) and load them up.
|
|
or [.obj](threejs-load-obj.html) and load them up.
|
|
-Which ever one you choose expect to spend 2 or 3 weeks going through
|
|
|
|
|
|
+Whichever one you choose, expect to spend 2 or 3 weeks going through
|
|
their respective tutorials as all of them have a learning curve
|
|
their respective tutorials as all of them have a learning curve
|
|
to be useful.
|
|
to be useful.
|
|
|
|
|
|
@@ -24,7 +24,7 @@ First let's just make a cube. Even though three.js already
|
|
provides us with `BoxGeometry` and `BoxBufferGeometry` a
|
|
provides us with `BoxGeometry` and `BoxBufferGeometry` a
|
|
cube is easy to understand so let's start there.
|
|
cube is easy to understand so let's start there.
|
|
|
|
|
|
-There are 2 ways to make custom geometry in THREE.js one
|
|
|
|
|
|
+There are 2 ways to make custom geometry in THREE.js. One
|
|
is with the `Geometry` class, the other is `BufferGeometry`.
|
|
is with the `Geometry` class, the other is `BufferGeometry`.
|
|
Each has their advantages. `Geometry` is arguably easier to
|
|
Each has their advantages. `Geometry` is arguably easier to
|
|
use but slower and uses more memory. For few 1000s triangles
|
|
use but slower and uses more memory. For few 1000s triangles
|
|
@@ -38,7 +38,7 @@ consider using `BufferGeometry`.
|
|
|
|
|
|
Note when I say `Geometry` is slower I mean it is slower to
|
|
Note when I say `Geometry` is slower I mean it is slower to
|
|
start and slower to modify but it is not slower to draw so
|
|
start and slower to modify but it is not slower to draw so
|
|
-if you're not planning on modifying your geometry then
|
|
|
|
|
|
+if you're not planning on modifying your geometry then
|
|
as long as it's not too large there will only be slightly more
|
|
as long as it's not too large there will only be slightly more
|
|
delay for your program to start using `Geometry` vs using
|
|
delay for your program to start using `Geometry` vs using
|
|
`BufferGeometry`. We'll go over both eventually. For now
|
|
`BufferGeometry`. We'll go over both eventually. For now
|
|
@@ -211,10 +211,10 @@ and we need to tell the material to use vertex colors
|
|
|
|
|
|
To use lighting we need normals. Normals are vectors that specify direction.
|
|
To use lighting we need normals. Normals are vectors that specify direction.
|
|
Just like the colors we can specify a normal for the face by setting the `normal`
|
|
Just like the colors we can specify a normal for the face by setting the `normal`
|
|
-property on each face with
|
|
|
|
|
|
+property on each face with
|
|
|
|
|
|
```js
|
|
```js
|
|
-face.normal = new THREE.Vector3(...)`
|
|
|
|
|
|
+face.normal = new THREE.Vector3(...)
|
|
```
|
|
```
|
|
|
|
|
|
or we can specify a normal for each vertex by setting the `vertexNormals`
|
|
or we can specify a normal for each vertex by setting the `vertexNormals`
|
|
@@ -256,13 +256,13 @@ vertex normals for a smoother look by calling `Geometry.computeVertexNormals`
|
|
+geometry.computeVertexNormals();
|
|
+geometry.computeVertexNormals();
|
|
```
|
|
```
|
|
|
|
|
|
-Unfortunately a cube is not a good candidate for vertex normals since it
|
|
|
|
|
|
+Unfortunately a cube is not a good candidate for vertex normals since it
|
|
means each vertex gets its normal from the
|
|
means each vertex gets its normal from the
|
|
-normals of all the faces it shares.
|
|
|
|
|
|
+normals of all the faces it shares.
|
|
|
|
|
|
{{{example url="../threejs-custom-geometry-cube-vertex-normals.html" }}}
|
|
{{{example url="../threejs-custom-geometry-cube-vertex-normals.html" }}}
|
|
|
|
|
|
-Adding texture coordinates, sometimes called UVs, is done via an array of
|
|
|
|
|
|
+Adding texture coordinates, sometimes called UVs, is done via an array of
|
|
layers of parallel arrays to the `faces` array which is set via `Geometry.faceVertexUvs`.
|
|
layers of parallel arrays to the `faces` array which is set via `Geometry.faceVertexUvs`.
|
|
For our cube we could do something like
|
|
For our cube we could do something like
|
|
|
|
|
|
@@ -315,7 +315,7 @@ function makeInstance(geometry, color, x) {
|
|
|
|
|
|
{{{example url="../threejs-custom-geometry-cube-texcoords.html" }}}
|
|
{{{example url="../threejs-custom-geometry-cube-texcoords.html" }}}
|
|
|
|
|
|
-Putting that all together lets make a simple heightmap based
|
|
|
|
|
|
+Putting that all together, let's make a simple heightmap based
|
|
terrain mesh.
|
|
terrain mesh.
|
|
|
|
|
|
A heightmap based terrain is where you have a 2D array of heights
|
|
A heightmap based terrain is where you have a 2D array of heights
|
|
@@ -325,7 +325,7 @@ It's 64x64 pixels
|
|
|
|
|
|
<div class="threejs_center"><img src="../resources/images/heightmap-64x64.png" style="width: 512px; image-rendering: pixelated;"></div>
|
|
<div class="threejs_center"><img src="../resources/images/heightmap-64x64.png" style="width: 512px; image-rendering: pixelated;"></div>
|
|
|
|
|
|
-We'll load that and then generate a heightmap mesh from it.
|
|
|
|
|
|
+We'll load that and then generate a heightmap mesh from it.
|
|
We can use the `ImageLoader` to load the image.
|
|
We can use the `ImageLoader` to load the image.
|
|
|
|
|
|
```js
|
|
```js
|
|
@@ -353,7 +353,7 @@ from the image
|
|
|
|
|
|
For each cell we'll generate 5 vertices. One for each corner of the cell
|
|
For each cell we'll generate 5 vertices. One for each corner of the cell
|
|
and one at the center point of the cell with the average height of the 4
|
|
and one at the center point of the cell with the average height of the 4
|
|
-corner heights.
|
|
|
|
|
|
+corner heights.
|
|
|
|
|
|
```js
|
|
```js
|
|
const cellsAcross = width - 1;
|
|
const cellsAcross = width - 1;
|
|
@@ -401,13 +401,13 @@ We'll then make 4 triangles from those 5 vertices
|
|
```js
|
|
```js
|
|
// create 4 triangles
|
|
// create 4 triangles
|
|
geometry.faces.push(
|
|
geometry.faces.push(
|
|
- new THREE.Face3(ndx , ndx + 4, ndx + 1),
|
|
|
|
|
|
+ new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
|
|
new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
|
|
new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
|
|
new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
|
|
new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
|
|
new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
|
|
new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
|
|
);
|
|
);
|
|
|
|
|
|
- // add the texture coordinates for each vertex of each face.
|
|
|
|
|
|
+ // add the texture coordinates for each vertex of each face
|
|
const u0 = x / cellsAcross;
|
|
const u0 = x / cellsAcross;
|
|
const v0 = z / cellsAcross;
|
|
const v0 = z / cellsAcross;
|
|
const u1 = (x + 1) / cellsDeep;
|
|
const u1 = (x + 1) / cellsDeep;
|
|
@@ -490,4 +490,4 @@ and we deleted the code related to spinning the cubes.
|
|
I hope that was a useful instruction to making your own
|
|
I hope that was a useful instruction to making your own
|
|
geometry using `Geometry`.
|
|
geometry using `Geometry`.
|
|
|
|
|
|
-In [another article](threejs-custom-buffergeometry.html) we'll go over `BufferGeometry`.
|
|
|
|
|
|
+In [another article](threejs-custom-buffergeometry.html) we'll go over `BufferGeometry`.
|