diff options
Diffstat (limited to 'files/ru/games/techniques/3d_on_the_web')
3 files changed, 607 insertions, 0 deletions
diff --git a/files/ru/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html b/files/ru/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html new file mode 100644 index 0000000000..7205f72e7a --- /dev/null +++ b/files/ru/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html @@ -0,0 +1,265 @@ +--- +title: Создание простой сцены с помощью Three.js +slug: Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js +tags: + - 3D + - Beginner + - Games + - Tutorial +translation_of: Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js +--- +<div>{{GamesSidebar}}</div> + +<p class="summary">В 3D сцене любой игры, даже самой простой, есть стандартные сущности, такие как поверхности, расположенные в координатной системе, камера, для того, чтобы их видеть, света и материалы, для того, чтобы они лучше выглядели, анимации, чтобы их оживить и тд.<strong> Three.js</strong>, как и любая другая 3D библиотека, предоставляет встроенные функции, которые помогут вам в реализации 3D. <span class="seoSummary">В этой статье мы покажем вам основы использования Three, включая настройку среды, структуру необходимого HTML, фундаментальные объекты Three и как создать простейшую сцену.</span></p> + +<div class="note"> +<p><strong>На заметку</strong>: Мы выбрали Three, потому что это одна из самых популярных <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> библиотек и она достаточно проста в освоении. Это не значит, что она самая лучшая, вы можете выбрать любую другую, например <a href="http://www.ambiera.com/copperlicht/index.html">CopperLicht</a>, <a href="http://www.glge.org/">GLGE</a>, <a href="https://code.google.com/p/o3d/">O3D</a> и тд.</p> +</div> + +<h2 id="Настройка_среды">Настройка среды</h2> + +<p>Чтобы начать разработку с Three.js, нужно:</p> + +<ul> + <li>Удостовериться, что вы используете современную версию браузера с поддеркой <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>, например, Firefox или Chrome.</li> + <li>Создать папку для экспериментов.</li> + <li>Сохранить копию <a href="http://threejs.org/build/three.min.js">последней версии библиотеки Three.js</a> в вашей папке.</li> + <li>Открыть <a href="http://threejs.org/docs/">документацию Three.js</a> в отдельной вкладке.</li> +</ul> + +<h2 id="HTML_структура">HTML структура</h2> + +<p>Здесь находится HTML структура, которую мы будем использовать:</p> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>MDN Games: Three.js demo</title> + <style> + body { margin: 0; padding: 0; } + canvas { width: 100%; height: 100%; } + </style> +</head> +<body> +<script src="three.min.js"></script> +<script> + var WIDTH = window.innerWidth; + var HEIGHT = window.innerHeight; + /* весь наш JavaScript код будет после этого комментария */ +</script> +</body> +</html> +</pre> + +<p>Она содержит основную информацию: {{htmlelement("title")}}, CSS, чтобы сделать <code>ширину</code> и <code>высоту</code> {{htmlelement("canvas")}} элемента равным странице. В первом элементе {{htmlelement("script")}} мы подключаем Three.js, во втором будем писать наш код, в котором уже создали 2 переменные для хранения <code>width</code> и <code>height</code>.</p> + +<p>Прежде чем продолжить, скопируйте этот код в новый файл и сохраните в вашей рабочей директории под именем <code>index.html</code>.</p> + +<h2 id="Renderer">Renderer</h2> + +<p>Renderer это инструмент для отрисовки сцены в браузере. Есть 2 вида таких инструментов: WebGL по умолчанию, другие - Canvas, SVG, CSS, и DOM. Они различаются по тому как все рендерится. Несмотря на различия в них, для пользователя все будет выглядить одинаково. Поэтому, вы можете выбрать запасной вариант на случай, если браузер пользователя не поддерживает выбранную вами технологию.</p> + +<pre class="brush: js notranslate">var renderer = new THREE.WebGLRenderer({antialias:true}); +renderer.setSize(WIDTH, HEIGHT); +renderer.setClearColor(0xDDDDDD, 1); +document.body.appendChild(renderer.domElement); +</pre> + +<p>Создаем новый WebGL renderer, устанавливаем размер так, чтобы он занимал все пространство страницы, прикрепляем DOM элемент к странице. Вы могли заметить параметр <code>antialias</code> в первой строке — если он установлен в <code>true</code>, то границы объектов сглаживаются. Метод <code>setClearColor()</code> устанавливает цвет бэкграунда (мы установили в 0xDDDDDD, светло-серый, значение по цмолчанию - черный).</p> + +<p>Добавьте этот код в ваш элемент {{htmlelement("script")}}.</p> + +<h2 id="Сцена">Сцена</h2> + +<p>Сцена (scene) это место, где все происходит. Когда создаются новые объекты, они добавляются в сцену, чтобы их можно было увидеть. В three.js роль сцены выполняет объект <code>Scene</code>. Давайте создадим его, добавив следующих код:</p> + +<pre class="brush: js notranslate">var scene = new THREE.Scene(); +</pre> + +<p>Позже, мы будем использовать метод <code>.add()</code> для добавления объектов в сцену.</p> + +<h2 id="Камера">Камера</h2> + +<p>У нас есть сцена, теперь необходимо создать камеру. С помощью следующих строк мы добавим камеру, установим ее позицию в координатной системе и направим ее на нужную нам точку, где расположено то, что мы хотим видеть:</p> + +<pre class="brush: js notranslate">var camera = new THREE.PerspectiveCamera(70, WIDTH/HEIGHT); +camera.position.z = 50; +scene.add(camera); +</pre> + +<p>Добавьте следующий код в программу.</p> + +<p>Существует несколько типов камер: кубическая (Cube), ортографическая (Orthographic), но самая простая - перспективная (Perspective). Чтобы инициализировать ее, нужно установить угол обзора и соотношение сторон: Первое нужно для указания того, как широко мы видим, последний для того, чтобы эти объекты имели правильные пропорции. Объясним поподробнее, что означают числа, что мы установили:</p> + +<ul> + <li>Мы установили поле зрения в 70, с этим можно поэкспериментировать: чем больше число, тем больше угол обзора, тем шире мы видим. Представьте обычную камеру и камеру с эффектом fish eye, Которая позволяет увидеть больше. Значение по умолчанию 50.</li> + <li>Соотношение сторон установлено в соотношение сторон окна браузера. Можно установить, например, в 16 ⁄ 9. Значение по умолчанию1.</li> + <li>Координата <code>z</code>, равная 50, это дистанция от камеры до начала координат сцены вдоль оси <code>z</code>. Мы установили такое значение, чтобы увидеть объекты в сцене. Значения <code>x</code> и <code>y</code> по умолчанию равны 0.</li> +</ul> + +<p>Стоит поэкспериментировать с этими значениями, чтобы лучше разобраться в том, как они влияют на отрисовку сцены.</p> + +<div class="note"> +<p><strong>На заметку</strong>: значения позиции (например координата z) безразмерны, устанавливайте их так, чтобы вам было удобно с ними работать.</p> +</div> + +<h2 id="Отрисовка_сцены">Отрисовка сцены</h2> + +<p>Все уже готово, но мы пока что ничего не видим. Хотя мы настроили рендерер, нам все равно нужно запустить рендеринг. Функция <code>render()</code> выполнит эту работу с небольшой помощью <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code>, которая заставляет сцену постоянно перерисовываться в каждом кадре:</p> + +<pre class="brush: js notranslate">function render() { + requestAnimationFrame(render); + renderer.render(scene, camera); +} +render(); +</pre> + +<p>На каждом новом кадре вызывается функция <code>render()</code>, а <code>renderer</code> рендерит <code>scene</code> и <code>camera</code>. Сразу после объявления функции мы в первый раз вызываем ее, чтобы запустить цикл, после чего он будет использоваться бесконечно.</p> + +<p>Еще раз, добавьте этот новый код ниже ваших предыдущих дополнений. Попробуйте сохранить файл и открыть его в браузере. Теперь вы должны увидеть серое окно. Поздравляем!</p> + +<h2 id="Geometry">Geometry</h2> + +<p>Now our scene is properly rendering, we can start adding 3D shapes. To speed up development, Three.js provides a bunch of predefined primitives, which you can use to create shapes instantly in a single line of code. There's cubes, spheres, cylinders, and more complicated shapes available. Detail like drawing required vertices and faces, for a given shape, is handled by the Three framework, so we can focus on higher level coding. Let's start, by defining the geometry for a cube shape, adding the following just above the <code>render()</code> function:</p> + +<pre class="brush: js notranslate">var boxGeometry = new THREE.BoxGeometry(10, 10, 10); +</pre> + +<p>In this case, we define a simple cube that is 10 x 10 x 10 units. The geometry itself is not enough though, we also need a material that will be used for our shape.</p> + +<h2 id="Material">Material</h2> + +<p>A material is what covers an object, the colors, or textures on its surface. In our case, we will choose a simple blue color to paint our box. There are a number of predefined materials which can be used: Basic, Phong, Lambert. Let's play with the last two later, but for now, the Basic one should be enough:</p> + +<pre class="brush: js notranslate">var basicMaterial = new THREE.MeshBasicMaterial({color: 0x0095DD}); +</pre> + +<p>Add this line below the previously added.</p> + +<p>Our material is now ready, what next?</p> + +<h2 id="Mesh">Mesh</h2> + +<p>To apply the material to a geometry, a mesh is used. This takes on a shape, and adds the specified material to every face:</p> + +<pre class="brush: js notranslate">var cube = new THREE.Mesh(boxGeometry, basicMaterial); +</pre> + +<p>Again, add this line below the one you previously added.</p> + +<h2 id="Добавление_куба_в_сцену">Добавление куба в сцену</h2> + +<p>Сейчас мы создали куб, используя 'geometry' и 'material'. Последнее, что мы долны сделать - добавить куб на сцену. Добавте в код эту строку:</p> + +<pre class="brush: js notranslate">scene.add(cube); +</pre> + +<p>Есди вы сохраните код и обновите вкладку браузера, вы увидете квадрат, а не куб, потому, что он стоит ровно напротив камеры и мы видим только одну сторону. У обьектов есть полезное свойтво - мы можем изменять их как хотим. Например, вы можете вращать его и масштабировать, сколько угодно. Чтож давайте немного повернем его, чтобы видеть больше сторон. Добавть в конец кода эту строку:</p> + +<pre class="brush: js notranslate">cube.rotation.set(0.4, 0.2, 0); +</pre> + +<p>Поздровляю, Вы создали обьект в 3D-среде! This might have proven easier than you first thought? Here's how it should look:</p> + +<p><img alt="Blue cube on a gray background rendered with Three.js." src="https://mdn.mozillademos.org/files/11849/cube.png" style="display: block; height: 400px; margin: 0px auto; width: 600px;"></p> + +<p>Весь код который мы создали:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/bwup75fa/","","350")}}</p> + +<p>Вы также можете <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/cube.html">просмотреть на GitHub</a>.</p> + +<h2 id="More_shapes_and_materials">More shapes and materials</h2> + +<p>Now we will add more shapes to the scene, and explore other shapes, materials, lighting, and more. Let's move the cube to the left, to make space for some friends. Adding the following line just below the previous one:</p> + +<pre class="brush: js notranslate">cube.position.x = -25; +</pre> + +<p>Now onto more shapes and materials. What might you input to add a torus, wrapped in the Phong material? Try adding the following lines, just below the lines defining the cube.</p> + +<pre class="brush: js notranslate">var torusGeometry = new THREE.TorusGeometry(7, 1, 6, 12); +var phongMaterial = new THREE.MeshPhongMaterial({color: 0xFF9500}); +var torus = new THREE.Mesh(torusGeometry, phongMaterial); +scene.add(torus); +</pre> + +<p>These lines will add a torus geometry; the <code>TorusGeometry()</code> method's parameters define, and the parameters are <code>radius</code>, <code>tube diameter</code>, <code>radial segment count</code>, and <code>tubular segment count</code>. The Phong material should look more glossy than the box's simple Basic material, though right now our torus will just look black.</p> + +<p>We can choose more fun predefined shapes. Let's play some more. Add the following lines, below those defining the torus:</p> + +<pre class="brush: js notranslate">var dodecahedronGeometry = new THREE.DodecahedronGeometry(7); +var lambertMaterial = new THREE.MeshLambertMaterial({color: 0xEAEFF2}); +var dodecahedron = new THREE.Mesh(dodecahedronGeometry, lambertMaterial); +dodecahedron.position.x = 25; +scene.add(dodecahedron); +</pre> + +<p>This time, we are creating a dodecahedron, a shape containing twelve flat faces. The parameter, <code>DodecahedronGeometry(),</code> defines the size of the object. We're using a Lambert material, similar to Phong, but should be less glossy. Again it's black, for now. We're moving the object to the right, so it's not in the same position as the box, or torus.</p> + +<p>As mentioned above, the new objects currently just look black. To have both, the Phong and Lambert materials properly visible, we need to introduce a source of light.</p> + +<h2 id="Lights">Lights</h2> + +<p>There are various types of light sources available in Three.js. The most basic is <code>PointLight</code>, which works like a flashlight, shining a spotlight in a defined direction. Add the following lines, below your shape definitions:</p> + +<pre class="brush: js notranslate">var light = new THREE.PointLight(0xFFFFFF); +light.position.set(-10, 15, 50); +scene.add(light); +</pre> + +<p>We define a white point of light, set its position a little away from the center of the scene, so it can light up some parts of the shapes, finally adding it to the scene. Now everything works as it should, all three shapes are visible. You should check the documentation for other types of lights, like Ambient, Directional, Hemisphere, or Spot. Experiment placing them on our scene, to see how they affect it.</p> + +<p><img alt="Shapes: blue cube, dark yellow torus and dark gray dodecahedron on a gray background rendered with Three.js." src="https://mdn.mozillademos.org/files/11851/shapes.png" style="height: 400px; width: 600px;"></p> + +<p>This looks a little boring though. In a game, something is usually happening. We might see animations and such. So let's try breathing a little life into these shapes, by animating them!</p> + +<h2 id="Анимация">Анимация</h2> + +<p>Мы можем использовать 'rotation', чтобы поменять положение куба. Также мы можем масштабировать фигуры или изменять их положение. Чтобы создать анимацию нужно внесенные изменения внести в цикл рендеринга, чтобы изменения происходили в каждом кадре.</p> + +<h3 id="Вращение">Вращение</h3> + +<p>Вращать фигуры просто. Вы просто добавляете или отнимаете значение по оси вращения. Добавте эту строкуу кода сразу после: <code>requestAnimationFrame()</code> invocation inside the <code>render</code> function:</p> + +<pre class="brush: js notranslate">cube.rotation.y += 0.01; +</pre> + +<p>This rotates the cube on every frame, by a tiny bit, so the animation looks smooth.</p> + +<h3 id="Scaling">Scaling</h3> + +<p>We can also scale an object. Applying a constant value, we would make it grow, or shrink just once. Let's make things more interesting. First, we implement a helper variable, called <code>t,</code> for counting elapsed time. Add it right before the <code>render()</code> function:</p> + +<pre class="brush: js notranslate">var t = 0; +</pre> + +<p>Now let's increase the value by a given constant value, on each frame of the animation. Add the following lines, just below the <code>requestAnimationFrame()</code> invocation:</p> + +<pre class="brush: js notranslate">t += 0.01; +torus.scale.y = Math.abs(Math.sin(t)); +</pre> + +<p>We use <code>Math.sin</code>, ending up with quite an interesting result. This scales the torus, repeating the process, as <code>sin</code> is a periodic function. We're wrapping the scale value in <code>Math.abs</code>, to pass the absolute values, greater or equal to 0. As sin is between -1 and 1, negative values might render out torus in unexpected way. In this case it looks black half the time.</p> + +<p>Now, onto movement.</p> + +<h3 id="Moving">Moving</h3> + +<p>Aside from rotation, and scaling, we can additionally move objects around the scene. Add the following, again just below our <code>requestAnimationFrame()</code> invocation:</p> + +<pre class="brush: js notranslate">dodecahedron.position.y = -7*Math.sin(t*2); +</pre> + +<p>This will move the dodecahedron up and down, by applying the <code>sin()</code> value to the y axis on each frame, and a little adjustment to make it look cooler. Try changing these values, to see how it affects the animations.</p> + +<h2 id="Conclusion">Conclusion</h2> + +<p>Here's the final code:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/rybr720u/","","350")}}</p> + +<p>You can also <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/shapes.html">see it on GitHub</a> and <a href="https://github.com/end3r/MDN-Games-3D/">fork the repository</a>, if you want to play with it locally. Now you understand the basics of Three.js, you can jump back to the parent page, <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web">3D on the Web</a>.</p> + +<p>You could also try learning raw WebGL, to gain a better understanding of what's going on underneath. See our <a href="/en-US/docs/Web/API/WebGL_API">WebGL documentation</a>.</p> diff --git a/files/ru/games/techniques/3d_on_the_web/glsl_shaders/index.html b/files/ru/games/techniques/3d_on_the_web/glsl_shaders/index.html new file mode 100644 index 0000000000..ee839e283f --- /dev/null +++ b/files/ru/games/techniques/3d_on_the_web/glsl_shaders/index.html @@ -0,0 +1,229 @@ +--- +title: GLSL Шейдеры +slug: Games/Techniques/3D_on_the_web/GLSL_Shaders +tags: + - GLSL + - OpenGL + - Shader + - three.js + - Шейдер +translation_of: Games/Techniques/3D_on_the_web/GLSL_Shaders +--- +<div>{{GamesSidebar}}</div> + +<p class="summary"><span class="seosummary">Шейдеры используют GLSL (</span><span class="ILfuVd">OpenGL Shading Language</span>)<span class="seosummary">, специальный язык программирования шейдеров от OpenGL, который во многом напоминает С (Си). GLSL выполняется напрямую графическим процессором. Существует два типа шейдеров: вершинные шейдеры и фрагментные (пиксельные) шейдеры. Вершинные шейдеры изменяют положение фигуры в системе 3D координат. Фрагментные шейдеры расчитывают цвет и другие атрибуты отображения.</span></p> + +<p>GLSL не так прост в изучении, как JavaScript. GLSL является строготипизированым и в нем часто используются операции с векторами и матрицами. It can get very complicated — very quickly. В этой статье мы создадим небольшой пример кода, который отображает куб. Чтобы ускорить разработку, мы будем использовать Three.js API.</p> + +<p>Как Вы помните из статьи о <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory">теоретических основах</a>, вертекс или вершина это точка в системе 3D кординат. Также вершины могут иметь дополнительные свойства. Система 3D координат определяет пространство, а вертексы позволяют определять формы в этом пространстве.</p> + +<h2 id="shader_types" name="shader_types">Типы шейдеров</h2> + +<p>Шейдер, по сути, это функция, которая требуется для отображения чего-либо на экране. Шейдер запускается в <a href="https://en.wikipedia.org/wiki/GPU">GPU</a> (graphics processing unit), который оптимизирован для выполнения подобных операций. Using a GPU to deal with shaders offloads some of the number crunching from the CPU. This allows the CPU to focus its processing power on other tasks, like executing code.</p> + +<h3 id="vertex_shader" name="vertex_shader">Вершинный шейдер</h3> + +<p>Vertex shaders manipulate coordinates in a 3D space and are called once per vertex. The purpose of the vertex shader is to set up the <code>gl_Position</code> variable — this is a special, global, and built-in GLSL variable. <code>gl_Position</code> is used to store the position of the current vertex.</p> + +<p>The <code>void main()</code> function is a standard way of defining the <code>gl_Position</code> variable. Everything inside <code>void main()</code> will be executed by the vertex shader. A vertex shader yields a variable containing how to project a vertex's position in 3D space onto a 2D screen.</p> + +<h3 id="fragment_shader" name="fragment_shader">Фрагментный шейдер</h3> + +<p>Fragment (or texture) shaders define RGBA (red, blue, green, alpha) colors for each pixel being processed — a single fragment shader is called once per pixel. The purpose of the fragment shader is to set up the <code>gl_FragColor</code> variable. <code>gl_FragColor</code> is a built-in GLSL variable like <code>gl_Position</code>.</p> + +<p>The calculations result in a variable containing the information about the RGBA color.</p> + +<h2 id="demo" name="demo">Демо</h2> + +<p>Let's build a simple demo to explain those shaders in action. Be sure to read <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Three.js tutorial</a> first to grasp the concept of the scene, its objects, and materials.</p> + +<div class="note"> +<p><strong>Note</strong>: Remember that you don't have to use Three.js or any other library to write your shaders — pure <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a> (Web Graphics Library) is more than enough. We've used Three.js here to make the background code a lot simpler and clearer to understand, so you can just focus on the shader code. Three.js and other 3D libraries abstract a lot of things for you — if you wanted to create such an example in raw WebGL, you'd have to write a lot of extra code to actually make it work.</p> +</div> + +<h3 id="Environment_setup" name="Environment_setup">Настройка окружения</h3> + +<p>Чтобы приступить к работе с шейдерами WebGL Вам потребуется:</p> + +<ul> + <li>Убедиться, что Вы используете современный браузер, который хорошо поддерживает <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a>, например Firefox или Chrome.</li> + <li>Создать папку, в которой будете хранить результаты ваших экспериментов.</li> + <li>Сохранить копию <a href="https://threejs.org/build/three.min.js">последней минимизированной версии библиотеки Three.js</a> в созданную папку.</li> +</ul> + +<h3 id="HTML_structure" name="HTML_structure">Структура HTML кода</h3> + +<p>Мы будем использовать следующую структуру HTML кода.</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>MDN Games: Shaders demo</title> + <style> + body { margin: 0; padding: 0; font-size: 0; } + canvas { width: 100%; height: 100%; } + </style> + <script src="three.min.js"></script> +</head> +<body> + <script id="vertexShader" type="x-shader/x-vertex"> + // vertex shader's code goes here + </script> + <script id="fragmentShader" type="x-shader/x-fragment"> + // fragment shader's code goes here + </script> + <script> + // scene setup goes here + </script> +</body> +</html> +</pre> + +<p>It contains some basic information like the document {{htmlelement("title")}}, and some CSS to set the <code>width</code> and <code>height</code> of the {{htmlelement("canvas")}} element that Three.js will insert on the page to be the full size of the viewport. The {{htmlelement("script")}} element in the {{htmlelement("head")}} includes the Three.js library in the page; we will write our code into three script tags in the {{htmlelement("body")}} tag:</p> + +<ol> + <li>The first one will contain the vertex shader.</li> + <li>The second one will contain the fragment shader.</li> + <li>The third one will contain the actual JavaScript code generating the scene.</li> +</ol> + +<p>Before reading on, copy this code to a new text file and save it in your working directory as <code>index.html</code>. We'll create a scene featuring a simple cube in this file to explain how the shaders work.</p> + +<h3 id="Исходный_код_куба">Исходный код куба</h3> + +<p>Instead of creating everything from scratch we can reuse the <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a> source code of the cube. Most of the components like the renderer, camera, and lights will stay the same, but instead of the basic material we will set the cube's color and position using shaders.</p> + +<p>Go to the <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/cube.html">cube.html file on GitHub</a>, copy all the JavaScript code from inside the second {{htmlelement("script")}} element, and paste it into the third <code><script></code> element of the current example. Save and load <code>index.html</code> in your browser — you should see a blue cube.</p> + +<h3 id="Код_вершинного_шейдера">Код вершинного шейдера</h3> + +<p>Давайте напишем простой вершинный шейдер — добавим код ниже в тело первого тега <code><script></code> :</p> + +<pre class="brush: glsl">void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x+10.0, position.y, position.z+5.0, 1.0); +} +</pre> + +<p>The resulting <code>gl_Position</code> is calculated by multiplying the model-view and the projection matrices by each vector to get the final vertex position, in each case.</p> + +<div class="note"> +<p><strong>Note</strong>: You can learn more about <em>model</em>, <em>view</em>, and <em>projection transformations</em> from the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory#Vertex_processing">vertex processing paragraph</a>, and you can also check out the links at the end of this article to learn more about it.</p> +</div> + +<p>Both <code>projectionMatrix</code> and <code>modelViewMatrix</code> are provided by Three.js and the vector is passed with the new 3D position, which results in the original cube moving 10 units along the <code>x</code> axis and 5 units along the <code>z</code> axis, translated via a shader. We can ignore the fourth parameter and leave it with the default <code>1.0</code> value; this is used to manipulate the clipping of the vertex position in the 3D space, but we don't need in our case.</p> + +<h3 id="Код_шейдера_текстуры">Код шейдера текстуры</h3> + +<p>Now we'll add the texture shader to the code — add the code below to the body's second <code><script></code> tag:</p> + +<pre class="brush: glsl">void main() { + gl_FragColor = vec4(0.0, 0.58, 0.86, 1.0); +} +</pre> + +<p>This will set an RGBA color to recreate the current light blue one — the first three float values (ranging from <code>0.0</code> to <code>1.0</code>) represent the red, green, and blue channels while the fourth one is the alpha transparency (ranging from <code>0.0</code> — fully transparent — to 1.0 — fully opaque).</p> + +<h3 id="Применение_шейдеров">Применение шейдеров</h3> + +<p>To actually apply the newly created shaders to the cube, comment out the <code>basicMaterial</code> definition first:</p> + +<pre class="brush: js">// var basicMaterial = new THREE.MeshBasicMaterial({color: 0x0095DD}); +</pre> + +<p>Далее, создаем <a href="http://threejs.org/docs/#Reference/Materials/ShaderMaterial"><code>shaderMaterial</code></a>:</p> + +<pre class="brush: js">var shaderMaterial = new THREE.ShaderMaterial( { + vertexShader: document.getElementById( 'vertexShader' ).textContent, + fragmentShader: document.getElementById( 'fragmentShader' ).textContent +}); +</pre> + +<p>This shader material takes the code from the scripts and applies it to the object the material is assigned to.</p> + +<p>Then, in the line that defines the cube we need to replace the <code>basicMaterial</code>:</p> + +<pre class="brush: js">var cube = new THREE.Mesh(boxGeometry, basicMaterial); +</pre> + +<p>...with the newly created <code>shaderMaterial</code>:</p> + +<pre class="brush: js">var cube = new THREE.Mesh(boxGeometry, shaderMaterial); +</pre> + +<p>Three.js compiles and runs the shaders attached to the mesh to which this material is given. In our case the cube will have both vertex and texture shaders applied. That's it — you've just created the simplest possible shader, congratulations! Here's what the cube should look like:</p> + +<p><img alt="Three.js blue cube demo" src="http://end3r.github.io/MDN-Games-3D/Shaders/img/cube.png" style="display: block; margin: 0px auto;"></p> + +<p>It looks exactly the same as the Three.js cube demo but the slightly different position and the same blue color are both achieved using the shader.</p> + +<h2 id="Финальный_вариант">Финальный вариант</h2> + +<h3 id="HTML">HTML</h3> + +<pre class="brush: html"><script src="https://end3r.github.io/MDN-Games-3D/Shaders/js/three.min.js"></script> +<script id="vertexShader" type="x-shader/x-vertex"> + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x+10.0, position.y, position.z+5.0, 1.0); + } +</script> +<script id="fragmentShader" type="x-shader/x-fragment"> + void main() { + gl_FragColor = vec4(0.0, 0.58, 0.86, 1.0); + } +</script> +</pre> + +<h3 id="JavaScript">JavaScript</h3> + +<pre class="brush: js"> var WIDTH = window.innerWidth; + var HEIGHT = window.innerHeight; + + var renderer = new THREE.WebGLRenderer({antialias:true}); + renderer.setSize(WIDTH, HEIGHT); + renderer.setClearColor(0xDDDDDD, 1); + document.body.appendChild(renderer.domElement); + + var scene = new THREE.Scene(); + + var camera = new THREE.PerspectiveCamera(70, WIDTH/HEIGHT); + camera.position.z = 50; + scene.add(camera); + + var boxGeometry = new THREE.BoxGeometry(10, 10, 10); + + var shaderMaterial = new THREE.ShaderMaterial( { + vertexShader: document.getElementById( 'vertexShader' ).textContent, + fragmentShader: document.getElementById( 'fragmentShader' ).textContent + }); + + var cube = new THREE.Mesh(boxGeometry, shaderMaterial); + scene.add(cube); + cube.rotation.set(0.4, 0.2, 0); + + function render() { + requestAnimationFrame(render); + renderer.render(scene, camera); + } + render();</pre> + +<h3 id="CSS">CSS</h3> + +<pre class="brush: css">body { margin: 0; padding: 0; font-size: 0; } +canvas { width: 100%; height: 100%; } +</pre> + +<h3 id="Результат">Результат</h3> + +<p>{{ EmbedLiveSample('Final_code', '100%', '400', '', 'Games/Techniques/3D_on_the_web/GLSL_Shaders') }}</p> + +<h2 id="Заключение">Заключение</h2> + +<p>This article has taught the very basics of shaders. Our example doesn't do much but there are many more cool things you can do with shaders — check out some really cool ones on <a href="http://shadertoy.com/">ShaderToy</a> for inspiration and to learn from their sources.</p> + +<h2 id="Смотри_также">Смотри также</h2> + +<ul> + <li><a href="http://learningwebgl.com/blog/?page_id=1217">Изучение WebGL</a> — for general WebGL knowledge</li> + <li><a href="http://webglfundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html">WebGL шейдеры и GLSL основы</a> — for GLSL specific information</li> +</ul> diff --git a/files/ru/games/techniques/3d_on_the_web/index.html b/files/ru/games/techniques/3d_on_the_web/index.html new file mode 100644 index 0000000000..3944c617c6 --- /dev/null +++ b/files/ru/games/techniques/3d_on_the_web/index.html @@ -0,0 +1,113 @@ +--- +title: 3D games on the Web +slug: Games/Techniques/3D_on_the_web +tags: + - Games + - Graphics + - NeedsContent + - NeedsExample + - NeedsTranslation + - TopicStub + - WebGL + - WebVR + - three.js +translation_of: Games/Techniques/3D_on_the_web +--- +<div>{{GamesSidebar}}</div><p class="summary">For rich gaming experiences on the Web the weapon of choice is WebGL, which is rendered on HTML {{htmlelement("canvas")}}. WebGL is basically an OpenGL ES 2.0 for the Web — it's a JavaScript API providing tools to build rich interactive animations and of course also games. You can generate and render dynamic 3D graphics with JavaScript that is hardware accelerated.</p> + +<h2 id="Documentation_and_browser_support">Documentation and browser support</h2> + +<p>The <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> project documentation and specification is maintained by the <a href="https://www.khronos.org/">Khronos Group</a>, not the W3C as with most of the Web APIs. Support on modern browsers is very good, even on mobile, so you don't have to worry about that too much. The main browsers are all supporting WebGL and all you need to focus on is optimizing the performance on the devices you use.</p> + +<p>There's an ongoing effort on releasing WebGL 2.0 (based on OpenGL ES 3.0) in the near future, which will bring many improvements and will help developers build games for the modern Web using current, powerful hardware.</p> + +<h2 id="Explaining_basic_3D_theory">Explaining basic 3D theory</h2> + +<p>The basics of 3D theory centers around shapes represented in a 3D space, with a coordinate system being used to calculate their positions. See our <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory">Explaining basic 3D theory</a> article for all the information you need.</p> + +<h2 id="Advanced_concepts">Advanced concepts</h2> + +<p>You can do a lot more with WebGL. There are some advanced concepts which you should dive into and learn more about — like shaders, collision detection, or the latest hot topic — virtual reality on the web.</p> + +<h3 id="Shaders">Shaders</h3> + +<p>It's worth mentioning shaders, which are a separate story on their own. Shaders use GLSL, a special OpenGL Shading Language with syntax similar to C that is executed directly by the graphics pipeline. They can be split into Vertex Shaders and Fragment Shaders (or Pixel Shaders) — the former transforms shape positions to real 3D drawing coordinates, while the latter computes rendering colors and other attributes. You should definitely check out <a href="/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders">GLSL Shaders</a> article to learn more about them.</p> + +<h3 id="Collision_Detection">Collision Detection</h3> + +<p>It's hard to imagine a game without the collision detection — we always need to work out when something is hitting something else. We have information available for your to learn from:</p> + +<ul> + <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D collision detection</a></li> +</ul> + +<h3 id="WebVR">WebVR</h3> + +<p>The concept of virtual reality is not new, but it's storming onto the web thanks to hardware advancements such as the <a href="https://www.oculus.com/en-us/rift/">Oculus Rift</a>, and the (currently experimental) <a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a> for capturing information form VR hardware and making it available for use in JavaScript applications. For more, read <a href="/en-US/docs/Games/Techniques/3D_on_the_web/WebVR">WebVR — Virtual Reality for the Web</a>.</p> + +<p>There's also the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a> article showing you how easy it is to build 3D environments for virtual reality using the <a href="http://aframe.io/">A-Frame</a> framework.</p> + +<h2 id="The_rise_of_libraries_and_frameworks">The rise of libraries and frameworks</h2> + +<p>Coding raw WebGL is fairly complex, but you'll want to get to grips with it in the long run, as your projects get more advanced (see our <a href="/en-US/docs/Web/API/WebGL_API">WebGL documentation</a> to get started.) For real world projects you'll probably also make use of a framework to speed up development and help you manage the project you're working on. Using a framework for 3D games also helps optimize the performance as a lot is taken care of by the tools you use, so you can focus on building the game itself.</p> + +<p>The most popular JavaScript 3D library is <a href="http://threejs.org/">Three.js</a>, a multi-purpose tool that makes common 3D techniques simpler to implement. There are other popular game development libraries and frameworks worth checking too; <a href="https://aframe.io">A-Frame</a>, <a href="https://playcanvas.com/">PlayCanvas</a> and <a href="http://www.babylonjs.com/">Babylon.js</a> are among the most recognizable ones with rich documentation, online editors and active communities.</p> + +<h3 id="Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</h3> + +<p>A-Frame is a web framework for building 3D and VR experiences. Under the hood, it is a three.js framework with a declarative entity-component pattern, meaning we can build scenes with just HTML. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a> subpage for the step-by-step process of creating the demo.</p> + +<h3 id="Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</h3> + +<p><span class="seosummary">Babylon.js is one of the most popular 3D game engines used by developers. As with any other 3D library it provides built-in functions to help you implement common 3D functionality more quickly. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a> subpage for the basics of using Babylon.js, including setting up a development environment, structuring the necessary HTML, and writing the JavaScript code.</span></p> + +<h3 id="Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</h3> + +<p>PlayCanvas is a popular 3D WebGL game engine open sourced on GitHub, with an editor available online and good documentation. See the <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a> subpage for high level details, and further articles showing how to create demos using the PlayCanvas library, and the online editor.</p> + +<h3 id="Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</h3> + +<p>Three.js, as any other library, gives you a huge advantage: instead of writing hundreds of lines of WebGL code to build anything interesting you can use built-in helper functions to do it a lot easier and faster. See the <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a> subpage for the step-by-step process of creating the demo.</p> + +<h3 id="Other_tools">Other tools</h3> + +<p>Both <a href="http://unity3d.com/">Unity</a> and <a href="https://www.unrealengine.com/">Unreal</a> can export your game to <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> with <a href="/en-US/docs/Games/Tools/asm.js">asm.js</a>, so you're free to use their tools and techniques to build games that will be exported to the web.</p> + +<p><img alt="" src="http://end3r.github.io/MDN-Games-3D/A-Frame/img/shapes.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<h2 id="Where_to_go_next">Where to go next</h2> + +<p>With this article we just scratched the surface of what's possible with currently available technologies. You can build immersive, beautiful and fast 3D games on the Web using WebGL, and the libraries and frameworks build on top of it.</p> + +<h3 id="Source_code">Source code</h3> + +<p>You can find all the source code for this series <a href="http://end3r.github.io/MDN-Games-3D/">demos on GitHub</a>.</p> + +<h3 id="APIs">APIs</h3> + +<ul> + <li><a href="/en-US/docs/Web/API/Canvas_API">Canvas API</a></li> + <li><a href="/en-US/docs/Web/API/WebGL_API">WebGL API</a></li> + <li><a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a></li> +</ul> + +<h3 id="Frameworks">Frameworks</h3> + +<ul> + <li><a href="http://threejs.org/">Three.js</a></li> + <li><a href="https://github.com/WhitestormJS/whs.js">Whitestorm.js</a> (based on Three.js)</li> + <li><a href="https://playcanvas.com/">PlayCanvas</a></li> + <li><a href="http://www.babylonjs.com/">Babylon.js</a></li> + <li><a href="http://aframe.io/">A-Frame</a></li> +</ul> + +<h3 id="Tutorials">Tutorials</h3> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Whitestorm.js">Building up a basic demo with Whitestorm.js</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a></li> +</ul> |
