Skip to content

Commit ba76e37

Browse files
vicimpagreggman
authored andcommitted
Complete translation into Russian
1 parent 3d571bc commit ba76e37

32 files changed

+8252
-627
lines changed

webgl/lessons/ru/webgl-2d-matrices.md

Lines changed: 515 additions & 3 deletions
Large diffs are not rendered by default.

webgl/lessons/ru/webgl-drawing-without-data.md

Lines changed: 357 additions & 1 deletion
Large diffs are not rendered by default.

webgl/lessons/ru/webgl-fundamentals.md

Lines changed: 416 additions & 1 deletion
Large diffs are not rendered by default.

webgl/lessons/ru/webgl-gpgpu.md

Lines changed: 1006 additions & 5 deletions
Large diffs are not rendered by default.

webgl/lessons/ru/webgl-how-it-works.md

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,197 @@ v_color, который мы объявили.
197197

198198
// ищем, куда должны идти данные вершин.
199199
var positionLocation = gl.getAttribLocation(program, "a_position");
200-
+ var colorLocation = gl.getAttribLocation(program, "a_color");
200+
+ var colorLocation = gl.getAttribLocation(program, "a_color");
201+
...
202+
+ // Создаем буфер для цветов.
203+
+ var buffer = gl.createBuffer();
204+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
205+
+
206+
+ // Устанавливаем цвета.
207+
+ setColors(gl);
208+
209+
// настраиваем атрибуты
210+
...
211+
+ // говорим атрибуту цвета, как извлекать данные из текущего ARRAY_BUFFER
212+
+ gl.enableVertexAttribArray(colorLocation);
213+
+ var size = 4;
214+
+ var type = gl.FLOAT;
215+
+ var normalize = false;
216+
+ var stride = 0;
217+
+ var offset = 0;
218+
+ gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset);
219+
220+
...
221+
222+
+// Заполняем буфер цветами для 2 треугольников
223+
+// которые составляют прямоугольник.
224+
+function setColors(gl) {
225+
+ // Выбираем 2 случайных цвета.
226+
+ var r1 = Math.random();
227+
+ var b1 = Math.random();
228+
+ var g1 = Math.random();
229+
+
230+
+ var r2 = Math.random();
231+
+ var b2 = Math.random();
232+
+ var g2 = Math.random();
233+
+
234+
+ gl.bufferData(
235+
+ gl.ARRAY_BUFFER,
236+
+ new Float32Array(
237+
+ [ r1, b1, g1, 1,
238+
+ r1, b1, g1, 1,
239+
+ r1, b1, g1, 1,
240+
+ r2, b2, g2, 1,
241+
+ r2, b2, g2, 1,
242+
+ r2, b2, g2, 1]),
243+
+ gl.STATIC_DRAW);
244+
+}
245+
246+
И вот результат.
247+
248+
{{{example url="../webgl-2d-rectangle-with-2-colors.html" }}}
249+
250+
Обратите внимание, что у нас есть 2 треугольника сплошного цвета. Тем не менее, мы передаем значения
251+
в *varying*, поэтому они варьируются или интерполируются по
252+
треугольнику. Просто мы использовали тот же цвет на каждой из 3 вершин
253+
каждого треугольника. Если мы сделаем каждый цвет разным, мы увидим
254+
интерполяцию.
255+
256+
// Заполняем буфер цветами для 2 треугольников
257+
// которые составляют прямоугольник.
258+
function setColors(gl) {
259+
// Делаем каждую вершину разным цветом.
260+
gl.bufferData(
261+
gl.ARRAY_BUFFER,
262+
new Float32Array(
263+
* [ Math.random(), Math.random(), Math.random(), 1,
264+
* Math.random(), Math.random(), Math.random(), 1,
265+
* Math.random(), Math.random(), Math.random(), 1,
266+
* Math.random(), Math.random(), Math.random(), 1,
267+
* Math.random(), Math.random(), Math.random(), 1,
268+
* Math.random(), Math.random(), Math.random(), 1]),
269+
gl.STATIC_DRAW);
270+
}
271+
272+
И теперь мы видим интерполированный *varying*.
273+
274+
{{{example url="../webgl-2d-rectangle-with-random-colors.html" }}}
275+
276+
Не очень захватывающе, я полагаю, но это демонстрирует использование более чем одного
277+
атрибута и передачу данных от вершинного шейдера к фрагментному шейдеру. Если
278+
вы посмотрите на [примеры обработки изображений](webgl-image-processing.html),
279+
вы увидите, что они также используют дополнительный атрибут для передачи координат текстуры.
280+
281+
## Что делают эти команды буфера и атрибута?
282+
283+
Буферы - это способ получения данных вершин и других данных на вершину на
284+
GPU. `gl.createBuffer` создает буфер.
285+
`gl.bindBuffer` устанавливает этот буфер как буфер для работы.
286+
`gl.bufferData` копирует данные в текущий буфер.
287+
288+
Как только данные находятся в буфере, нам нужно сказать WebGL, как извлекать данные из
289+
него и предоставлять их атрибутам вершинного шейдера.
290+
291+
Для этого сначала мы спрашиваем WebGL, какие локации он назначил
292+
атрибутам. Например, в коде выше у нас есть
293+
294+
// ищем, куда должны идти данные вершин.
295+
var positionLocation = gl.getAttribLocation(program, "a_position");
296+
var colorLocation = gl.getAttribLocation(program, "a_color");
297+
298+
Как только мы знаем локацию атрибута, мы выдаем 2 команды.
299+
300+
gl.enableVertexAttribArray(location);
301+
302+
Эта команда говорит WebGL, что мы хотим предоставить данные из буфера.
303+
304+
gl.vertexAttribPointer(
305+
location,
306+
numComponents,
307+
typeOfData,
308+
normalizeFlag,
309+
strideToNextPieceOfData,
310+
offsetIntoBuffer);
311+
312+
И эта команда говорит WebGL получать данные из буфера, который был последним
313+
привязан с gl.bindBuffer, сколько компонентов на вершину (1 - 4), какой
314+
тип данных (`BYTE`, `FLOAT`, `INT`, `UNSIGNED_SHORT`, и т.д.), шаг
315+
который означает, сколько байт пропустить, чтобы получить от одного куска данных к
316+
следующему куску данных, и смещение для того, как далеко в буфере находятся наши данные.
317+
318+
Количество компонентов всегда от 1 до 4.
319+
320+
Если вы используете 1 буфер на тип данных, то и шаг, и смещение могут
321+
всегда быть 0. 0 для шага означает "использовать шаг, который соответствует типу и
322+
размеру". 0 для смещения означает начать с начала буфера. Установка
323+
их в значения, отличные от 0, более сложна, и хотя это может иметь некоторые
324+
преимущества с точки зрения производительности, это не стоит усложнения, если только
325+
вы не пытаетесь довести WebGL до его абсолютных пределов.
326+
327+
Я надеюсь, что это проясняет буферы и атрибуты.
328+
329+
Вы можете взглянуть на эту
330+
[интерактивную диаграмму состояния](/webgl/lessons/resources/webgl-state-diagram.html)
331+
для другого способа понимания того, как работает WebGL.
332+
333+
Далее давайте пройдемся по [шейдерам и GLSL](webgl-shaders-and-glsl.html).
334+
335+
<div class="webgl_bottombar"><h3>Для чего нужен normalizeFlag в vertexAttribPointer?</h3>
336+
<p>
337+
Флаг нормализации предназначен для всех не-плавающих типов. Если вы передаете
338+
false, то значения будут интерпретироваться как тип, которым они являются. BYTE идет
339+
от -128 до 127, UNSIGNED_BYTE идет от 0 до 255, SHORT идет от -32768 до 32767 и т.д...
340+
</p>
341+
<p>
342+
Если вы устанавливаете флаг нормализации в true, то значения BYTE (-128 до 127)
343+
представляют значения -1.0 до +1.0, UNSIGNED_BYTE (0 до 255) становятся 0.0 до +1.0.
344+
Нормализованный SHORT также идет от -1.0 до +1.0, просто у него больше разрешения, чем у BYTE.
345+
</p>
346+
<p>
347+
Самое распространенное использование нормализованных данных - для цветов. Большую часть времени цвета
348+
идут только от 0.0 до 1.0. Использование полного float для каждого красного, зеленого, синего и альфа
349+
использовало бы 16 байт на вершину на цвет. Если у вас сложная геометрия, это
350+
может сложиться в много байт. Вместо этого вы могли бы конвертировать ваши цвета в UNSIGNED_BYTE,
351+
где 0 представляет 0.0, а 255 представляет 1.0. Теперь вам понадобилось бы только 4 байта на цвет
352+
на вершину, экономия 75%.
353+
</p>
354+
<p>Давайте изменим наш код, чтобы делать это. Когда мы говорим WebGL, как извлекать наши цвета, мы бы использовали</p>
355+
<pre class="prettyprint showlinemods">
356+
var size = 4;
357+
* var type = gl.UNSIGNED_BYTE;
358+
* var normalize = true;
359+
var stride = 0;
360+
var offset = 0;
361+
gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset);
362+
</pre>
363+
<p>И когда мы заполняем наш буфер цветами, мы бы использовали</p>
364+
<pre class="prettyprint showlinemods">
365+
// Заполняем буфер цветами для 2 треугольников
366+
// которые составляют прямоугольник.
367+
function setColors(gl) {
368+
// Выбираем 2 случайных цвета.
369+
var r1 = Math.random() * 256; // 0 до 255.99999
370+
var b1 = Math.random() * 256; // эти значения
371+
var g1 = Math.random() * 256; // будут обрезаны
372+
var r2 = Math.random() * 256; // когда сохранены в
373+
var b2 = Math.random() * 256; // Uint8Array
374+
var g2 = Math.random() * 256;
375+
376+
gl.bufferData(
377+
gl.ARRAY_BUFFER,
378+
new Uint8Array( // Uint8Array
379+
[ r1, b1, g1, 255,
380+
r1, b1, g1, 255,
381+
r1, b1, g1, 255,
382+
r2, b2, g2, 255,
383+
r2, b2, g2, 255,
384+
r2, b2, g2, 255]),
385+
gl.STATIC_DRAW);
386+
}
387+
</pre>
388+
<p>
389+
Вот этот пример.
390+
</p>
391+
392+
{{{example url="../webgl-2d-rectangle-with-2-byte-colors.html" }}}
393+
</div>

webgl/lessons/ru/webgl-image-processing-continued.md

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,4 +195,83 @@ TOC: Продвинутая обработка изображений
195195
var count = 6;
196196
gl.drawArrays(primitiveType, offset, count);
197197
}
198-
```
198+
```
199+
200+
Вот рабочая версия с немного более гибким UI. Отметьте эффекты,
201+
чтобы включить их. Перетаскивайте эффекты, чтобы изменить порядок их применения.
202+
203+
{{{example url="../webgl-2d-image-processing.html" }}}
204+
205+
Некоторые вещи, которые я должен объяснить.
206+
207+
Вызов `gl.bindFramebuffer` с `null` говорит WebGL, что вы хотите рендерить
208+
на canvas вместо одного из ваших framebuffer'ов.
209+
210+
Также framebuffer'ы могут работать или не работать в зависимости от того, какие привязки
211+
вы на них помещаете. Есть список того, какие типы и комбинации привязок
212+
должны всегда работать. Используемая здесь, одна текстура `RGBA`/`UNSIGNED_BYTE`,
213+
назначенная точке привязки `COLOR_ATTACHMENT0`, должна всегда работать.
214+
Более экзотические форматы текстур и/или комбинации привязок могут не работать.
215+
В этом случае вы должны привязать framebuffer и затем вызвать
216+
`gl.checkFramebufferStatus` и посмотреть, возвращает ли он `gl.FRAMEBUFFER_COMPLETE`.
217+
Если да, то все в порядке. Если нет, вам нужно будет сказать пользователю использовать
218+
что-то другое. К счастью, WebGL2 поддерживает многие форматы и комбинации.
219+
220+
WebGL должен преобразовывать из [clip space](webgl-fundamentals.html) обратно в пиксели.
221+
Он делает это на основе настроек `gl.viewport`. Поскольку framebuffer'ы,
222+
в которые мы рендерим, имеют другой размер, чем canvas, нам нужно установить
223+
viewport соответствующим образом в зависимости от того, рендерим ли мы в текстуру или canvas.
224+
225+
Наконец, в [оригинальном примере](webgl-fundamentals.html) мы переворачивали координату Y
226+
при рендеринге, потому что WebGL отображает canvas с 0,0 в левом нижнем углу
227+
вместо более традиционного для 2D левого верхнего угла. Это не нужно
228+
при рендеринге в framebuffer. Поскольку framebuffer никогда не отображается,
229+
какая часть является верхом и низом, не имеет значения. Все, что имеет значение,
230+
это то, что пиксель 0,0 в framebuffer соответствует 0,0 в наших вычислениях.
231+
Чтобы справиться с этим, я сделал возможным установить, переворачивать или нет, добавив
232+
еще один uniform вход в вызов шейдера `u_flipY`.
233+
234+
```
235+
...
236+
+uniform float u_flipY;
237+
...
238+
239+
void main() {
240+
...
241+
+ gl_Position = vec4(clipSpace * vec2(1, u_flipY), 0, 1);
242+
...
243+
}
244+
```
245+
246+
И затем мы можем установить это при рендеринге с помощью
247+
248+
```
249+
...
250+
+ var flipYLocation = gl.getUniformLocation(program, "u_flipY");
251+
252+
...
253+
254+
+ // не переворачиваем
255+
+ gl.uniform1f(flipYLocation, 1);
256+
257+
...
258+
259+
+ // переворачиваем
260+
+ gl.uniform1f(flipYLocation, -1);
261+
```
262+
263+
Я сохранил этот пример простым, используя одну GLSL программу, которая может достичь
264+
множественных эффектов. Если бы вы хотели делать полноценную обработку изображений, вам, вероятно,
265+
понадобилось бы много GLSL программ. Программа для настройки оттенка, насыщенности и яркости.
266+
Другая для яркости и контрастности. Одна для инвертирования, другая для настройки
267+
уровней и т.д. Вам нужно будет изменить код для переключения GLSL программ и обновления
268+
параметров для этой конкретной программы. Я рассматривал написание этого примера,
269+
но это упражнение лучше оставить читателю, потому что множественные GLSL программы, каждая
270+
со своими потребностями в параметрах, вероятно, означает серьезный рефакторинг, чтобы все
271+
не превратилось в большую путаницу спагетти-кода.
272+
273+
Я надеюсь, что этот и предыдущие примеры сделали WebGL немного более
274+
доступным, и я надеюсь, что начало с 2D помогает сделать WebGL немного легче для
275+
понимания. Если я найду время, я попробую написать [еще несколько статей](webgl-2d-translation.html)
276+
о том, как делать 3D, а также больше деталей о [том, что WebGL действительно делает под капотом](webgl-how-it-works.html).
277+
Для следующего шага рассмотрите изучение [как использовать 2 или более текстур](webgl-2-textures.html).

0 commit comments

Comments
 (0)