|
@@ -2,23 +2,28 @@ Title: Three.js Custom Geometry
|
|
|
Description: Как сделать свою собственную геометрию.
|
|
|
TOC: Custom Geometry
|
|
|
|
|
|
-В предыдущей статье рассказывалось о различных встроенных примитивах, включенных в THREE.js. В этой статье мы рассмотрим создание нашей собственной геометрии.
|
|
|
+В [предыдущей статье](threejs-primitives.html) рассказывалось о различных встроенных примитивах, включенных в THREE.js. В этой статье мы рассмотрим создание нашей собственной геометрии.
|
|
|
|
|
|
-Просто для ясности, если вы серьезно относитесь к созданию 3D-контента, наиболее распространенный способ - использовать пакет 3D-моделирования, такой как Blender, Maya, 3D Studio Max, Cinema4D и т. Д. Вы создадите модель, а затем экспортируете в gLTF или .obj и загрузите их. Какой бы вариант вы ни выбрали, рассчитывайте потратить 2 или 3 недели на изучение соответствующих учебных пособий, поскольку все они имеют полезную кривую обучения.
|
|
|
+Просто для ясности, если вы серьезно относитесь к созданию 3D-контента, наиболее распространенный способ - использовать пакет 3D-моделирования, такой как [Blender](https://blender.org),
|
|
|
+[Maya](https://www.autodesk.com/products/maya/overview),
|
|
|
+[3D Studio Max](https://www.autodesk.com/products/3ds-max/overview),
|
|
|
+[Cinema4D](https://www.maxon.net/en-us/) и т. д.
|
|
|
+Вы создадите модель, а затем экспортируете в [gLTF](threejs-load-gltf.html) или [.obj](threejs-load-obj.html) и загрузите их.
|
|
|
+Какой бы вариант вы ни выбрали, рассчитывайте потратить 2 или 3 недели на изучение соответствующих учебных пособий, поскольку все они имеют полезную кривую обучения.
|
|
|
|
|
|
Тем не менее, бывают случаи, когда мы можем захотеть сгенерировать нашу собственную трехмерную геометрию в коде вместо использования пакета моделирования.
|
|
|
|
|
|
-Сначала давайте просто сделаем куб. Хотя Three.js уже предоставляет нам BoxGeometry и BoxBufferGeometry, куб легко понять, поэтому давайте начнем с него.
|
|
|
+Сначала давайте просто сделаем куб. Хотя Three.js уже предоставляет нам `BoxGeometry` и `BoxBufferGeometry`, куб легко понять, поэтому давайте начнем с него.
|
|
|
|
|
|
-Есть два способа сделать пользовательскую геометрию в THREE.js. Один с классом Geometry, другой - BufferGeometry. У каждого есть свои преимущества. Геометрия, возможно, проще в использовании, но медленнее и использует больше памяти. Для нескольких тысяч треугольников это отличный выбор, но для десятков тысяч треугольников может быть лучше использовать BufferGeometry.
|
|
|
+Есть два способа сделать пользовательскую геометрию в THREE.js. Один с классом `Geometry`, другой - `BufferGeometry`. У каждого есть свои преимущества. `Geometry`, возможно, проще в использовании, но медленнее и использует больше памяти. Для нескольких тысяч треугольников это отличный выбор, но для десятков тысяч треугольников может быть лучше использовать `BufferGeometry`.
|
|
|
|
|
|
-BufferGeometry, возможно, сложнее в использовании, но использует меньше памяти и работает быстрее. Если вы хотите сгенерировать более 10000 треугольников, подумайте об использовании BufferGeometry.
|
|
|
+`BufferGeometry`, возможно, сложнее в использовании, но использует меньше памяти и работает быстрее. Если вы хотите сгенерировать более 10000 треугольников, подумайте об использовании `BufferGeometry`.
|
|
|
|
|
|
-Заметьте, когда я говорю, что Geometry медленнее, я имею в виду, что она медленнее запускается и медленнее изменяется, но рисовать она не медленнее, поэтому, если вы не планируете изменять свою геометрию, тогда, пока она не слишком велика, будет только немного больше. задержка для вашей программы, чтобы начать использовать Geometry против BufferGeometry. Мы изучим оба способа. Пока что давайте использовать геометрию, так как легче понять IMO.
|
|
|
+Заметьте, когда я говорю, что `Geometry` медленнее, я имею в виду, что она медленнее запускается и медленнее изменяется, но рисовать она не медленнее, поэтому, если вы не планируете изменять свою геометрию, тогда, пока она не слишком велика, будет только немного больше. задержка для вашей программы, чтобы начать использовать `Geometry` против `BufferGeometry`. Мы изучим оба способа. Пока что давайте использовать геометрию, так как легче понять IMO.
|
|
|
|
|
|
-Сначала давайте сделаем куб с Geometry. Начнем с примера из статьи об отзывчивости.
|
|
|
+Сначала давайте сделаем куб с `Geometry`. Начнем с примера из [статьи об отзывчивости](threejs-responsive.html).
|
|
|
|
|
|
-Давайте удалим код, который использует BoxGeometry, и заменим ее на Geometry.
|
|
|
+Давайте удалим код, который использует `BoxGeometry`, и заменим ее на `Geometry`.
|
|
|
|
|
|
```js
|
|
|
-const boxWidth = 1;
|
|
@@ -51,7 +56,7 @@ const geometry = new THREE.Geometry();
|
|
|
Затем нам нужно сделать треугольники, по 2 на каждую грань куба
|
|
|
<div class="threejs_center"><img src="resources/cube-triangles.svg" style="width: 500px"></div>
|
|
|
|
|
|
-Мы делаем это, создавая объекты Face3 и определяя индексы 3 вершин, которые составляют эту грань.
|
|
|
+Мы делаем это, создавая объекты `Face3` и определяя индексы 3 вершин, которые составляют эту грань.
|
|
|
|
|
|
Порядок, в котором мы указываем вершины, важен. Чтобы указывать на внешнюю сторону куба, они должны быть указаны в направлении против часовой стрелки, когда этот треугольник направлен на камеру.
|
|
|
|
|
@@ -84,7 +89,7 @@ geometry.faces.push(
|
|
|
|
|
|
Несколько других мелких изменений в оригинальном коде, и он должен работать.
|
|
|
|
|
|
-Эти кубики в два раза больше, чем BoxGeometry, которую мы использовали раньше, поэтому давайте немного переместим камеру назад
|
|
|
+Эти кубики в два раза больше, чем `BoxGeometry`, которую мы использовали раньше, поэтому давайте немного переместим камеру назад
|
|
|
|
|
|
```js
|
|
|
const fov = 75;
|
|
@@ -109,7 +114,7 @@ const cubes = [
|
|
|
];
|
|
|
```
|
|
|
|
|
|
-И последнее, что мы еще не добавили нормалей, поэтому мы не можем включить освещение. Давайте изменим материал на то, что не нуждается в освещении.
|
|
|
+И последнее, что мы еще не добавили это нормалей, поэтому мы не можем включить освещение. Давайте изменим материал на то, что не нуждается в освещении.
|
|
|
|
|
|
```js
|
|
|
function makeInstance(geometry, color, x) {
|
|
@@ -125,7 +130,7 @@ function makeInstance(geometry, color, x) {
|
|
|
и мы получаем кубики, которые мы сделали сами.
|
|
|
{{{example url="../threejs-custom-geometry-cube.html" }}}
|
|
|
|
|
|
-Мы можем указать цвет для каждой грани, установив свойство color каждой стороны.
|
|
|
+Мы можем указать цвет для каждой грани, установив свойство `color` каждой стороны.
|
|
|
|
|
|
```js
|
|
|
geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
|
|
@@ -136,7 +141,7 @@ geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
|
|
|
geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
|
|
|
```
|
|
|
|
|
|
-обратите внимание, что мы должны рассказать материал, который мы хотим использовать FaceColors
|
|
|
+обратите внимание, что мы должны рассказать материал, который мы хотим использовать `FaceColors`
|
|
|
|
|
|
```js
|
|
|
-const material = new THREE.MeshBasicMaterial({color});
|
|
@@ -145,7 +150,7 @@ geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta')
|
|
|
|
|
|
{{{example url="../threejs-custom-geometry-cube-face-colors.html" }}}
|
|
|
|
|
|
-Вместо этого мы можем установить цвет каждой отдельной вершины, установив для свойства vertexColors массив из 3 цветов для 3 вершин.
|
|
|
+Вместо этого мы можем установить цвет каждой отдельной вершины, установив для свойства `vertexColors` массив из 3 цветов для 3 вершин.
|
|
|
|
|
|
```js
|
|
|
geometry.faces.forEach((face, ndx) => {
|
|
@@ -165,7 +170,7 @@ geometry.faces.forEach((face, ndx) => {
|
|
|
|
|
|
{{{example url="../threejs-custom-geometry-cube-vertex-colors.html" }}}
|
|
|
|
|
|
-Чтобы использовать освещение, нам нужны нормали. Нормали - это векторы, которые определяют направление. Так же, как цвета, мы можем указать нормаль для грани, установив свойство normal для каждой стороны с помощью
|
|
|
+Чтобы использовать освещение, нам нужны нормали. Нормали - это векторы, которые определяют направление. Так же, как цвета, мы можем указать нормаль для грани, установив свойство `normal` для каждой стороны с помощью
|
|
|
|
|
|
|
|
|
|
|
@@ -173,7 +178,7 @@ geometry.faces.forEach((face, ndx) => {
|
|
|
face.normal = new THREE.Vector3(...)
|
|
|
```
|
|
|
|
|
|
-или мы можем указать нормаль для каждой вершины, установив для свойства vertexNormals что-то вроде
|
|
|
+или мы можем указать нормаль для каждой вершины, установив для свойства `vertexNormals` что-то вроде
|
|
|
|
|
|
```js
|
|
|
face.vertexNormals = [
|
|
@@ -185,13 +190,13 @@ face.vertexNormals = [
|
|
|
|
|
|
но часто гораздо проще просто попросить THREE.js вычислить для нас нормали на основе указанных позиций.
|
|
|
|
|
|
-Для нормалей грани мы бы назвали Geometry.computeFaceNormals как в
|
|
|
+Для нормалей грани мы бы назвали `Geometry.computeFaceNormals` как в
|
|
|
|
|
|
```js
|
|
|
geometry.computeFaceNormals();
|
|
|
```
|
|
|
|
|
|
-Удаление цвета вершин и изменение материала обратно на MeshPhongMaterial
|
|
|
+Удаление цвета вершин и изменение материала обратно на `MeshPhongMaterial`
|
|
|
```js
|
|
|
-const material = new THREE.MeshBasicMaterial({vertexColors: THREE.VertexColors});
|
|
|
+const material = new THREE.MeshPhongMaterial({color});
|
|
@@ -200,18 +205,18 @@ geometry.computeFaceNormals();
|
|
|
и теперь наши кубики будут освещены.
|
|
|
{{{example url="../threejs-custom-geometry-cube-face-normals.html" }}}
|
|
|
|
|
|
-Использование нормалей сторон всегда даст нам граненый взгляд. Мы можем использовать нормали вершин для более гладкого вида, вызывая Geometry.computeVertexNormals
|
|
|
+Использование нормалей сторон всегда даст нам граненый взгляд. Мы можем использовать нормали вершин для более гладкого вида, вызывая `Geometry.computeVertexNormals`
|
|
|
|
|
|
```js
|
|
|
-geometry.computeFaceNormals();
|
|
|
+geometry.computeVertexNormals();
|
|
|
```
|
|
|
|
|
|
-К сожалению, куб не является хорошим кандидатом для нормалей вершин, поскольку это означает, что каждая вершина получает свою нормаль от нормалей всех граней, которые она разделяет.
|
|
|
+К сожалению, куб не является хорошим выбором для нормалей вершин, поскольку это означает, что каждая вершина получает свою нормаль от нормалей всех граней, которые она разделяет.
|
|
|
|
|
|
{{{example url="../threejs-custom-geometry-cube-vertex-normals.html" }}}
|
|
|
|
|
|
-Добавление текстурных координат, иногда называемых UV, выполняется через массив слоев параллельных массивов в массив faces , который устанавливается через Geometry.faceVertexUvs. Для нашего куба мы могли бы сделать что-то вроде
|
|
|
+Добавление текстурных координат, иногда называемых UV, выполняется через массив слоев параллельных массивов в массив `faces` , который устанавливается через `Geometry.faceVertexUvs`. Для нашего куба мы могли бы сделать что-то вроде
|
|
|
|
|
|
```js
|
|
|
geometry.faceVertexUvs[0].push(
|
|
@@ -236,7 +241,7 @@ geometry.faceVertexUvs[0].push(
|
|
|
);
|
|
|
```
|
|
|
|
|
|
-Важно отметить, что faceVertexUvs - это массив слоев. Каждый слой представляет собой другой набор координат UV. По умолчанию есть один слой координат UV, слой 0, поэтому мы просто добавляем наши UV в этот слой.
|
|
|
+Важно отметить, что `faceVertexUvs` - это массив слоев. Каждый слой представляет собой другой набор координат UV. По умолчанию есть один слой координат UV, слой 0, поэтому мы просто добавляем наши UV в этот слой.
|
|
|
|
|
|
Давайте добавим текстуру к нашему материалу и переключимся обратно, чтобы вычислить нормали стороны
|
|
|
|
|
@@ -265,7 +270,7 @@ function makeInstance(geometry, color, x) {
|
|
|
|
|
|
<div class="threejs_center"><img src="../resources/images/heightmap-96x64.png" style="width: 512px; image-rendering: pixelated;"></div>
|
|
|
|
|
|
-Мы загрузим это и затем сгенерируем из него сетку карты высот. Мы можем использовать ImageLoader для загрузки изображения.
|
|
|
+Мы загрузим это и затем сгенерируем из него сетку карты высот. Мы можем использовать `ImageLoader` для загрузки изображения.
|
|
|
|
|
|
```js
|
|
|
const imgLoader = new THREE.ImageLoader();
|
|
@@ -377,7 +382,7 @@ for (let z = 0; z < cellsDeep; ++z) {
|
|
|
```
|
|
|
|
|
|
Несколько небольших изменений, чтобы было удобнее просматривать.
|
|
|
-включить OrbitControls
|
|
|
+включим `OrbitControls`
|
|
|
|
|
|
* include the `OrbitControls`
|
|
|
|
|
@@ -420,8 +425,8 @@ const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
|
|
|
и мы удалили код, связанный с вращением кубов.
|
|
|
{{{example url="../threejs-custom-geometry-heightmap.html" }}}
|
|
|
|
|
|
-Я надеюсь, что это была полезная инструкция для создания вашей собственной геометрии с использованием Geometry.
|
|
|
-В другой статье мы рассмотрим BufferGeometry.
|
|
|
+Я надеюсь, что это была полезная инструкция для создания вашей собственной геометрии с использованием `Geometry`.
|
|
|
+В другой статье мы рассмотрим `BufferGeometry`.
|
|
|
|
|
|
-In [another article](threejs-custom-buffergeometry.html) we'll go over `BufferGeometry`.
|
|
|
+В [другой статье](threejs-custom-buffergeometry.html) мы рассмотрим `BufferGeometry`.
|
|
|
|