Browse Source

[ru] Add translation for threejs-fundamentals

questions:
 (?) the top down diagram -> с диаграммой сверху вниз
 (?) root of a form of scene graph -> корень формы графа сцены
 (?) render -> отрисовка
 (?) Mesh -> полигональная сетка
 (?) Box -> прямоугольный параллелепипед
 (?) Frustum -> усеченная пирамида
 (?) fundamentals && basic -> основы
NikitaIT 6 years ago
parent
commit
dba75569cb
2 changed files with 343 additions and 20 deletions
  1. 323 0
      threejs/lessons/ru/threejs-fundamentals.md
  2. 20 20
      threejs/lessons/ru/toc.html

+ 323 - 0
threejs/lessons/ru/threejs-fundamentals.md

@@ -0,0 +1,323 @@
+Title: Основы Three.js
+Description: Твой первый урок по Three.js начинаетсся с основ
+
+Это первая статья в серии статей о three.js.
+[Three.js](http://threejs.org) это 3D-библиотека, которая максимально 
+упрощает создание 3D-контента на веб-странице.
+
+Three.js часто путают с WebGL, поскольку чаще всего, 
+но не всегда, three.js использует WebGL для рисования 3D.
+[WebGL - это очень низкоуровневое api, рисующее только точки, линии и треугольники](https://webglfundamentals.org). 
+Чтобы сделать что-нибудь полезное с WebGL, как правило, требуется немало кода, 
+и именно здесь приходит Three.js. Он обрабатывает такие вещи, как сцены, 
+источники света, тени, материалы, текстуры, 3D-математику, все, 
+что вам нужно было бы написать самостоятельно, если бы вы использовали WebGL напрямую.
+
+В этих руководствах предполагается, что вы уже знаете JavaScript, 
+и по большей части они будут использовать стандарт ES6+. [Смотрите здесь 
+краткий список вещей, которые вы, как ожидается, уже знаете](threejs-prerequisites.html). 
+Большинство браузеров, которые поддерживают three.js, 
+обновляются автоматически, поэтому большинство пользователей 
+должны иметь возможность запускать этот код. Если вы хотите, 
+чтобы этот код запускался в действительно старых браузерах, 
+посмотрите на транспайлер, такой как [Babel](http://babel.io).
+Конечно, пользователи, использующие действительно старые браузеры, 
+вероятно, имеют машины, которые не могут запускать three.js.
+
+При изучении большинства языков программирования первое, что делают люди, 
+это заставляют компьютер напечатать `"Hello World!"`. Для 3D одна из самых 
+распространенных задач - создать 3D-куб, так что давайте начнем с `"Hello Cube!"`
+
+Первое, что нам нужно, это тэг `<canvas>`:
+
+```
+<body>
+  <canvas id="c"></canvas>
+</body>
+```
+
+Three.js будет рисовать на этом холсте, так что нам нужно найти 
+его и передать three.js.
+
+```
+<script>
+'use strict';
+
+/* global THREE */
+
+function main() {
+  const canvas = document.querySelector('#c');
+  const renderer = new THREE.WebGLRenderer({canvas: canvas});
+  ...
+</script>
+```
+
+Обратите внимание, что здесь есть некоторые не явные детали. 
+Если вы не передадите холст в three.js, библиотека создаст его за вас, 
+но затем нужно будет добавить его в DOM. Место добавления 
+может меняться в зависимости от вашего варианта использования, 
+и вам придется изменить свой код, поэтому я считаю, что передача canvas 
+в three.js выглядит немного более гибкой. Я могу поместить холст где угодно, 
+и код найдет его там, как если бы у меня был код для вставки холста в документ, 
+и мне, вероятно, пришлось бы изменить этот код, если бы изменился мой вариант 
+использования.
+
+Когда канвас найден, мы создаем `WebGLRenderer`. Renderer - это то, что отвечает 
+за фактическое получение всех предоставленных вами данных и их отрисовку 
+на холст. В прошлом были другие рендеры, такие как `CSSRenderer`, 
+`CanvasRenderer`, а в будущем могут быть
+`WebGL2Renderer` или `WebGPURenderer`. На данный момент есть `WebGLRenderer`, 
+который использует WebGL для рисования 3D на холсте.
+
+Далее нам нужна камера.
+
+```
+const fov = 75;
+const aspect = 2;  // значение для canvas по умолчанию
+const near = 0.1;
+const far = 5;
+const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+```
+
+`fov` сокращение от `field of view`, [поле зрения](https://en.wikipedia.org/wiki/Field_of_view). В этом случае 75 градусов в 
+вертикальном измерении. Обратите внимание, что большинство углов в Three.js 
+указаны в радианах, но по какой-то причине перспективная камера принимает градусы.
+
+`aspect` это [соотношение сторон холста](https://ru.wikipedia.org/wiki/Соотношение_сторон_экрана) (англ. aspect ratio). Мы рассмотрим детали 
+в другой статье, но по умолчанию холст имеет размер 300x150 пикселей, 
+значит соотношение сторон 300/150 или 2.
+
+`near` и `far` представляют пространство перед камерой, которое будет отображаться. 
+Все, что находится до или после этого диапазона, будет обрезано (не нарисовано).
+
+Эти 4 параметра определяют [усеченную пирамиду](https://ru.wikipedia.org/wiki/Усечённая_пирамида) *"frustum"*. *Frustum* это 
+название 3D фигуры, напоминающей пирамиду с отсеченной верхушкой. Другими словами, 
+думайте о слове "frustum" как о трехмерной фигуре,
+такой как сфера, куб и призма.
+
+<img src="../resources/frustum-3d.svg" width="500" class="threejs_center"/>
+
+Высота ближней и дальней плоскостей определяется полем зрения (field of view). 
+Ширина обеих плоскостей определяется полем зрения и соотношением сторон (aspect).
+
+Все, что находится внутри определенного усеченного контура, будет нарисовано. 
+Снаружи ничего не будет.
+
+По умолчанию камера смотрит вниз по оси -Z и вверх по оси +Y. Мы поместим наш куб 
+в начало координат (origin), поэтому нам нужно немного отодвинуть камеру назад, 
+чтобы что-то увидеть.
+
+```
+camera.position.z = 2;
+```
+
+Вот как мы её направили.
+
+<img src="../resources/scene-down.svg" width="500" class="threejs_center"/>
+
+На диаграмме выше мы видим, что наша камера находится в `z = 2`. И смотрит вниз по оси -Z. 
+Усеченная пирамида начинается с 0.1 единицы спереди камеры и до 5 единиц перед камерой.
+ Our canvas is twice as wide
+as it is tall so across view the field of view will be much wider than
+our specified 75 degrees which is the vertical field of view.
+Поскольку на этой диаграмме мы смотрим вниз, поле зрения (fov) зависит от отношения 
+сторон (aspect). Так как ширина холста в 2 раза больще высоты, при просмотре поле обзора 
+будет намного шире, чем указанные нами 75 градусов, которые являются вертикальным 
+полем зрения.
+
+Далее создадим `Scene`. `Scene` в three.js корень формы графа сцены. 
+Все, что вы хотите нарисовать необходимо добавить на сцену. Мы рассмотрим подробнее, 
+[как работают сцены, в следующей статье](threejs-scenegraph.html).
+
+```
+const scene = new THREE.Scene();
+```
+
+Далее мы создаем `BoxGeometry` который содержит данные для [прямоугольного параллелепипеда](https://ru.wikipedia.org/wiki/Прямоугольный_параллелепипед). 
+Почти все, что мы хотим отобразить в Three.js, нуждается в геометрии, 
+которая определяет вершины нашего трехмерного объекта.
+
+```
+const boxWidth = 1;
+const boxHeight = 1;
+const boxDepth = 1;
+const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
+```
+
+Затем мы создаем основной материал и устанавливаем его цвет. 
+Цвета могут быть определены с использованием 6-значных шестнадцатеричных 
+значений цвета, как в CSS.
+
+```
+const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
+```
+
+Затем мы создаем [полигональную сетку](https://ru.wikipedia.org/wiki/Полигональная_сетка) 
+`Mesh`. `Mesh` в three.js представляет комбинацию 
+формы объекта `Geometry` и `Material` (как нарисовать объект, 
+блестящий или плоский, какой цвет, какую текстуру(ры) применить и т.д.)
+а также положение, ориентацию, и масштаб этого объекта в сцене.
+
+```
+const cube = new THREE.Mesh(geometry, material);
+```
+
+И, наконец, мы добавляем `Mesh` на сцену
+
+```
+scene.add(cube);
+```
+
+Затем мы можем отрендерить сцену, вызвав функцию `render` рендерера 
+передав ей сцену и камеру.
+
+```
+renderer.render(scene, camera);
+```
+
+Вот рабочий пример
+
+{{{example url="../threejs-fundamentals.html" }}}
+
+Трудно сказать, что это 3D-куб, так как мы видим его непосредственно по оси 
+-Z, а сам куб выровнен по этой оси, поэтому мы видим только одну грань.
+
+Давайте оживим его, и, надеюсь, это прояснит, что он рисуется в 3D. Для его 
+анимации мы будем отрисовывать внутри цикла отрисовки, используя
+[`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
+
+Вот наш цикл
+
+```
+function render(time) {
+  time *= 0.001;  // конвертировать время в секунды
+
+  cube.rotation.x = time;
+  cube.rotation.y = time;
+
+  renderer.render(scene, camera);
+
+  requestAnimationFrame(render);
+}
+requestAnimationFrame(render);
+```
+
+`requestAnimationFrame` это запрос к браузеру, что вы хотите что-то анимировать.
+Вы передаете ему функцию для вызова. В нашем случае эта функция `render`. 
+Браузер вызовет вашу функцию, и если вы обновите что-либо, связанное с 
+отображением страницы, браузер выполнит перерисовку страницы. 
+В нашем случае мы вызываем `renderer.render`, которая нарисует нашу сцену.
+
+`requestAnimationFrame` передает время с момента загрузки страницы в нашу функцию. 
+Это время приходит в миллисекундах. Я считаю, что работать с секундами намного проще, 
+поэтому здесь мы конвертируем время в секунды.
+
+Затем мы устанавливаем вращение куба по X и Y на текущее время. Эти повороты в 
+[радианах](https://ru.wikipedia.org/wiki/Радиан). В круге 2 пи радиана, 
+поэтому наш куб должен повернуться вокруг каждой оси примерно за 6.28
+секунд.
+
+Затем мы отрисовываем сцену и запрашиваем еще один кадр анимации, 
+чтобы продолжить наш цикл.
+
+Вне цикла мы вызываем `requestAnimationFrame` один раз, чтобы запустить цикл.
+
+{{{example url="../threejs-fundamentals-with-animation.html" }}}
+
+Это немного лучше, но все еще трудно увидеть 3d. Что может помочь, так это 
+добавить немного освещения, поэтому давайте добавим источник света. 
+В Three.js есть много разных источников света, о которых мы поговорим в 
+следующей статье. А пока давайте создадим направленный свет.
+
+```
+{
+  const color = 0xFFFFFF;
+  const intensity = 1;
+  const light = new THREE.DirectionalLight(color, intensity);
+  light.position.set(-1, 2, 4);
+  scene.add(light);
+}
+```
+
+Направленные источники имеет положение и цель. Оба по умолчанию равны 0, 0, 0. В нашем
+случае мы устанавливаем положение источника света на -1, 2, 4 чтобы оно было немного слева, 
+сверху и позади нашей камеры. Цель по-прежнему 0, 0, 0, поэтому они будут светить 
+в направлении начала координат.
+
+Нам также нужно изменить материал. `MeshBasicMaterial` не воспреимчив к свету. 
+Давайте изменим его на `MeshPhongMaterial`, который отражает свет.
+
+```
+-const material = new THREE.MeshBasicMaterial({color: 0x44aa88});  // greenish blue
++const material = new THREE.MeshPhongMaterial({color: 0x44aa88});  // greenish blue
+```
+
+И вот оно работает.
+
+{{{example url="../threejs-fundamentals-with-light.html" }}}
+
+Теперь должно быть довольно четко видно 3D.
+
+Просто для удовольствия добавим еще 2 кубика.
+
+Мы будем использовать одну и ту же геометрию для каждого куба, но 
+создадим другой материал, чтобы каждый куб мог иметь свой цвет.
+
+Сначала мы сделаем функцию, которая создает новый материал с указанным цветом. 
+Затем создает mesh, используя указанную геометрию, добавляет ее к сцене и 
+устанавливает ей позицию X.
+
+```
+function makeInstance(geometry, color, x) {
+  const material = new THREE.MeshPhongMaterial({color});
+
+  const cube = new THREE.Mesh(geometry, material);
+  scene.add(cube);
+
+  cube.position.x = x;
+
+  return cube;
+}
+```
+
+Затем мы будем вызывать его 3 раза с 3 разными цветами и позициями X, 
+сохраняя экземпляры `Mesh` в массив.
+
+```
+const cubes = [
+  makeInstance(geometry, 0x44aa88,  0),
+  makeInstance(geometry, 0x8844aa, -2),
+  makeInstance(geometry, 0xaa8844,  2),
+];
+```
+
+Наконец, мы закрутим все 3 куба в нашей функции отрисовки. 
+Мы рассчитываем немного разные коэффициенты вращения для каждого.
+
+```
+function render(time) {
+  time *= 0.001;  // конвертировать время в секунды
+  
+  cubes.forEach((cube, ndx) => {
+    const speed = 1 + ndx * .1;
+    const rot = time * speed;
+    cube.rotation.x = rot;
+    cube.rotation.y = rot;
+  });
+
+  ...
+```
+
+и вот оно.
+
+{{{example url="../threejs-fundamentals-3-cubes.html" }}}
+
+Если вы сравните его с диаграммой сверху вниз, вы увидите, что она соответствует 
+нашим ожиданиям. С кубами в X = -2 и X = +2 они частично находятся вне нашей 
+усеченной пирамиды. Они также несколько искривлены, так как 
+поле зрения на холсте очень велико.
+
+Я надеюсь, что это короткое вступление поможет вам начать изучение. 
+[Далее мы рассмотрим, как сделать отзывчивый дизайн, чтобы код можно было применять 
+к различным ситуациям](threejs-responsive.html).
+

+ 20 - 20
threejs/lessons/ru/toc.html

@@ -1,39 +1,39 @@
 <ul>
   <li>Основы</li>
   <ul>
-    <li><a href="/threejs/lessons/threejs-fundamentals.html">Базовые принципы</a></li>
-    <li><a href="/threejs/lessons/threejs-responsive.html">Адаптивный дизайн</a></li>
-    <li><a href="/threejs/lessons/threejs-prerequisites.html">Предварительные условия</a></li>
-    <li><a href="/threejs/lessons/threejs-setup.html">Настройка</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-fundamentals.html">Базовые принципы</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-responsive.html">Адаптивный дизайн</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-prerequisites.html">Предварительные условия</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-setup.html">Настройка</a></li>
   </ul>
   <li>Решения</li>
   <ul>
-    <li><a href="/threejs/lessons/threejs-load-obj.html">Загрузить файл .OBJ</a></li>
-    <li><a href="/threejs/lessons/threejs-load-gltf.html">Загрузить файл .GLTF</a></li>
-    <li><a href="/threejs/lessons/threejs-multiple-scenes.html"> Несколько холстов, несколько сцен</a></li>
-    <li><a href="/threejs/lessons/threejs-picking.html">Выбор объектов с помощью мыши</a></li>
-    <li><a href="/threejs/lessons/threejs-post-processing.html">Постобработка</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-load-obj.html">Загрузить файл .OBJ</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-load-gltf.html">Загрузить файл .GLTF</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-multiple-scenes.html"> Несколько холстов, несколько сцен</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-picking.html">Выбор объектов с помощью мыши</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-post-processing.html">Постобработка</a></li>
   </ul>
   <li>Советы</li>
   <ul>
-    <li><a href="/threejs/lessons/threejs-debugging-javascript.html">Отладка JavaScript</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-debugging-javascript.html">Отладка JavaScript</a></li>
   </ul>
   <li>Основы</li>
   <ul>
-    <li><a href="/threejs/lessons/threejs-primitives.html">Примитивы</a></li>
-    <li><a href="/threejs/lessons/threejs-scenegraph.html">Граф сцены</a></li>
-    <li><a href="/threejs/lessons/threejs-materials.html">Материалы</a></li>
-    <li><a href="/threejs/lessons/threejs-textures.html">Текстуры</a></li>
-    <li><a href="/threejs/lessons/threejs-lights.html">Свет</a></li>
-    <li><a href="/threejs/lessons/threejs-cameras.html">Камера</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-primitives.html">Примитивы</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-scenegraph.html">Граф сцены</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-materials.html">Материалы</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-textures.html">Текстуры</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-lights.html">Свет</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-cameras.html">Камера</a></li>
     <li><a href="#"><del>Мотор!</del></a></li>
-    <li><a href="/threejs/lessons/threejs-shadows.html">Тени</a></li>
-    <li><a href="/threejs/lessons/threejs-fog.html">Туман</a></li>
-    <li><a href="/threejs/lessons/threejs-rendertargets.html">Цели рендеринга</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-shadows.html">Тени</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-fog.html">Туман</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-rendertargets.html">Цели рендеринга</a></li>
   </ul>
   <li>Ссылки</li>
   <ul>
-    <li><a href="/threejs/lessons/threejs-material-table.html">Таблица материалов</a></li>
+    <li><a href="/threejs/lessons/ru/threejs-material-table.html">Таблица материалов</a></li>
   </ul>
 </ul>
 <ul>