CumingSoon
Местный стендапер
- 1,634
- 12
- 270
Q: Что такое VBO?
A: VBO – это технология, позволяющая выгрузить данные в видеоустройство для повышения скорости отрисовки.
ОЗУ, ГПУ и ЦПУ - все имеют про три буквы в сокращении, все оканчиваются на «у» (на самом деле, ГП, ЦП и ОЗУ)...
Данные между ними передаются относительно медленно, словно каждый из них находится на разных материках. Процессор имеет кэш, доступ к которому является достаточно быстрым; видеокарта имеет видеопамять, доступ к которой будет побыстрее, чем к ОЗУ. Данные, нужные для отрисовки, лежат же в ОЗУ: например, треугольник с 3 вершинами, каждая из которых может иметь 3 локальные координаты, 2 UV-координаты. Для того чтобы не гонять все эти данные из ОЗУ в процессор, а оттуда на ГП, была разработана технология VBO. Она позволяет сразу выгрузить данные в видеопамять, а графический процессор будет использовать их для отрисовки уже оттуда.
Также, VBO представляет из себя массив ака буфер данных, находящийся в видеопамяти.
Q: Что такое VAO?
А: Всё очень просто, это массив, содержащий буферы с данными(те самые VBO), а также последовательность индексов(о них позже).
Допустим, рисуется параллелограмм(выше картинка). Поскольку ОГЛ рисует треугольниками, то наш параллелограмм распадается на 2 треугольника. Каждая из 4 вершин может иметь: позицию(3 координаты), UV-координаты(2 координаты). Значит, VAO будет следующим(тут вершины повторяются, поскольку мы описываем треугольники, а каждому из них нужно указать три вершины в опр. порядке):
-VAO
--Pos0
--UV0
--Pos1
--UV1
--Pos2
--UV2
//второй треугольник
--Pos2
--UV2
--Pos1
--UV1
--Pos3
--UV3
Итого, 6 * (3 + 2) = 30 чисел.
Вместо того, чтобы загружать каждый раз данные о вершине, мы загрузим разово все вершины и последовательность, в которой эти вершины будут рисоваться(индексы). Тогда VAO примет вид:
-VAO
--Pos0
--UV0
--Pos1
--UV1
--Pos2
--UV2
--Pos3
--UV3
--indices[0, 1, 2, 2, 3, 1]
Итого, 4 * (3 + 2) + 6 = 26 чисел. Экономия в 4 числа.
- Всего?!
Да, всего. Но мы ведь рисуем лишь два треугольника, а какова будет экономия, если нарисовать 2-3к треугольников?
Q: Хорошо, *не* понятно, но что такое шейдер, зачем он?
A: Шейдер - это программа для ГП, которая обрабатывает какие-то данные на ГП, лол. Вершинный шейдер - вершины, геометрический - наборы вершин, фрагментарный - пиксели. Ещё есть тесселяционный, но с ним я не работал, уж простите. Пишутся шредоры эти на С-подобном языке - GLSL.
Итак, расскажу чуть подробнее про каждый тип шейдеров.
==Вершинный==
Обычно принимает локальную координату вершины, которую с помощью диковинных трансформаций переводит в NDC(normalized device coordinates).
==Фрагментарный==
Ну тут всё просто - нужно выдать цвет пикселя. Можно использовать текстуру, откуда по UV-координатам легко достаётся цвет пикселя; можно просто указать цвет (от 0 до 1).
==Геометрический==
Принимаете набор вершин, а дальше что хотите - то и делайте. Можете раздвинуть вершины, можете добавить/убрать имеющиеся. Например, 1 входную вершину можно превратить в куб. Точка->куб. Тут уж ваша фантазия. 'Nuff said.
Q: Каких-то диковинных трансформаций?
А: Трансформации переводят позицию из одного простраства в другое с помощью матриц. Происходит это по следующей схеме: local space -> world(global) space -> view(camera) space -> clip space -> NDC space.
Local Space: локальное пространство фигуры. Думаю, всё понятно, да?
World(global) Space: мировое пространство фигуры. Тут тоже всё ясно, так?
View(camera) Space: пространство в камере. В мире компьютерной графике вращается не камера, а вершины фигур, смещаются также вершины. Камеры нет, это всё ложь.
Clip Space: если вы используете перспективную проекцию, то более далёкие фигуры будут меньше, чем ближние; параллельные прямые начинают сходится. Но можно задать ортогональную проекцию. Тогда все фигуры будут одинаковых размеров, будто б не удалены; параллельные не сходятся. О построении матриц проекции:
http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html
http://www.songho.ca/opengl/gl_projectionmatrix.html
Кстати, в первых трёх трансформациях используется 3-хмерный вектор. А вот в последней трансформации требуется 4-хмерный вектор, поскольку после преобразования в clip space координаты должны стать единичными, т.е. находится в NDCS(normalized device coordinates space). А происходит это путём деления xyz на w. Намечается вопрос: "А как тогда подобрать w координаты, чтобы перевести этот вектор в clip space?". Обычно ставится w = 1, если это точка. И w = 0 если вектор(потому что при делении на 0 всё обращается в бесконечность, а вектор в данном контексте представляет направление. Направление же не имеет конечной точки, ведь так?). А ещё в clip space верно следующее уравнение -w <= x, y, z <= w. Если какая-то из 3-х координат не соответствует неравенству, то она находится вне проекции(вне frustum, если перспективная; вне параллелепипеда, если это ортогональная).
Q: А что с кодом?
А: Ничего, мне лень его писать, ведь его не очень мало. Тем более, он запросто находится в гугле. Можете найти тут: https://github.com/r4v3n6101/Raven-API *пиар*.
Напоследок, в этом маленьком туториале, скажу, что:
1) В шредорах матрицы column-major, т.е. matrix.get(0, 1) выдаст вам число из первого столбца, второго ряда вместо ожидаемого числа из первого ряда, второго столбца. Легко переводится в row-major. Просто транспонируйте матрицу(поменяйте колонки и ряды местами). В некоторых функциях ОГЛ даже есть такой параметр, transpose.
2) В пространстве NDC левая тройка координат. Так что если использовали правую в пространстве камеры и глобальном пространстве, то вам придётся развернуть ось Z.
Вопросы, предложения, помидоры принимаются.
A: VBO – это технология, позволяющая выгрузить данные в видеоустройство для повышения скорости отрисовки.
ОЗУ, ГПУ и ЦПУ - все имеют про три буквы в сокращении, все оканчиваются на «у» (на самом деле, ГП, ЦП и ОЗУ)...
Данные между ними передаются относительно медленно, словно каждый из них находится на разных материках. Процессор имеет кэш, доступ к которому является достаточно быстрым; видеокарта имеет видеопамять, доступ к которой будет побыстрее, чем к ОЗУ. Данные, нужные для отрисовки, лежат же в ОЗУ: например, треугольник с 3 вершинами, каждая из которых может иметь 3 локальные координаты, 2 UV-координаты. Для того чтобы не гонять все эти данные из ОЗУ в процессор, а оттуда на ГП, была разработана технология VBO. Она позволяет сразу выгрузить данные в видеопамять, а графический процессор будет использовать их для отрисовки уже оттуда.
Также, VBO представляет из себя массив ака буфер данных, находящийся в видеопамяти.
Q: Что такое VAO?
А: Всё очень просто, это массив, содержащий буферы с данными(те самые VBO), а также последовательность индексов(о них позже).
Допустим, рисуется параллелограмм(выше картинка). Поскольку ОГЛ рисует треугольниками, то наш параллелограмм распадается на 2 треугольника. Каждая из 4 вершин может иметь: позицию(3 координаты), UV-координаты(2 координаты). Значит, VAO будет следующим(тут вершины повторяются, поскольку мы описываем треугольники, а каждому из них нужно указать три вершины в опр. порядке):
-VAO
--Pos0
--UV0
--Pos1
--UV1
--Pos2
--UV2
//второй треугольник
--Pos2
--UV2
--Pos1
--UV1
--Pos3
--UV3
Итого, 6 * (3 + 2) = 30 чисел.
Вместо того, чтобы загружать каждый раз данные о вершине, мы загрузим разово все вершины и последовательность, в которой эти вершины будут рисоваться(индексы). Тогда VAO примет вид:
-VAO
--Pos0
--UV0
--Pos1
--UV1
--Pos2
--UV2
--Pos3
--UV3
--indices[0, 1, 2, 2, 3, 1]
Итого, 4 * (3 + 2) + 6 = 26 чисел. Экономия в 4 числа.
- Всего?!
Да, всего. Но мы ведь рисуем лишь два треугольника, а какова будет экономия, если нарисовать 2-3к треугольников?
Q: Хорошо, *не* понятно, но что такое шейдер, зачем он?
A: Шейдер - это программа для ГП, которая обрабатывает какие-то данные на ГП, лол. Вершинный шейдер - вершины, геометрический - наборы вершин, фрагментарный - пиксели. Ещё есть тесселяционный, но с ним я не работал, уж простите. Пишутся шредоры эти на С-подобном языке - GLSL.
Итак, расскажу чуть подробнее про каждый тип шейдеров.
==Вершинный==
Обычно принимает локальную координату вершины, которую с помощью диковинных трансформаций переводит в NDC(normalized device coordinates).
==Фрагментарный==
Ну тут всё просто - нужно выдать цвет пикселя. Можно использовать текстуру, откуда по UV-координатам легко достаётся цвет пикселя; можно просто указать цвет (от 0 до 1).
==Геометрический==
Принимаете набор вершин, а дальше что хотите - то и делайте. Можете раздвинуть вершины, можете добавить/убрать имеющиеся. Например, 1 входную вершину можно превратить в куб. Точка->куб. Тут уж ваша фантазия. 'Nuff said.
Q: Каких-то диковинных трансформаций?
А: Трансформации переводят позицию из одного простраства в другое с помощью матриц. Происходит это по следующей схеме: local space -> world(global) space -> view(camera) space -> clip space -> NDC space.
Local Space: локальное пространство фигуры. Думаю, всё понятно, да?
World(global) Space: мировое пространство фигуры. Тут тоже всё ясно, так?
View(camera) Space: пространство в камере. В мире компьютерной графике вращается не камера, а вершины фигур, смещаются также вершины. Камеры нет, это всё ложь.
Clip Space: если вы используете перспективную проекцию, то более далёкие фигуры будут меньше, чем ближние; параллельные прямые начинают сходится. Но можно задать ортогональную проекцию. Тогда все фигуры будут одинаковых размеров, будто б не удалены; параллельные не сходятся. О построении матриц проекции:
http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html
http://www.songho.ca/opengl/gl_projectionmatrix.html
Кстати, в первых трёх трансформациях используется 3-хмерный вектор. А вот в последней трансформации требуется 4-хмерный вектор, поскольку после преобразования в clip space координаты должны стать единичными, т.е. находится в NDCS(normalized device coordinates space). А происходит это путём деления xyz на w. Намечается вопрос: "А как тогда подобрать w координаты, чтобы перевести этот вектор в clip space?". Обычно ставится w = 1, если это точка. И w = 0 если вектор(потому что при делении на 0 всё обращается в бесконечность, а вектор в данном контексте представляет направление. Направление же не имеет конечной точки, ведь так?). А ещё в clip space верно следующее уравнение -w <= x, y, z <= w. Если какая-то из 3-х координат не соответствует неравенству, то она находится вне проекции(вне frustum, если перспективная; вне параллелепипеда, если это ортогональная).
Q: А что с кодом?
А: Ничего, мне лень его писать, ведь его не очень мало. Тем более, он запросто находится в гугле. Можете найти тут: https://github.com/r4v3n6101/Raven-API *пиар*.
Напоследок, в этом маленьком туториале, скажу, что:
1) В шредорах матрицы column-major, т.е. matrix.get(0, 1) выдаст вам число из первого столбца, второго ряда вместо ожидаемого числа из первого ряда, второго столбца. Легко переводится в row-major. Просто транспонируйте матрицу(поменяйте колонки и ряды местами). В некоторых функциях ОГЛ даже есть такой параметр, transpose.
2) В пространстве NDC левая тройка координат. Так что если использовали правую в пространстве камеры и глобальном пространстве, то вам придётся развернуть ось Z.
Вопросы, предложения, помидоры принимаются.