Краткий курс компьютерной графики, аддендум: лечим по фотографии

в 16:09, , рубрики: game development, ненормальное программирование, отладка, Программирование, Работа с анимацией и 3D-графикой

Год назад я опубликовал цикл статей, имевший целью популяризацию графического программирования. Много воды утекло с тех пор, появилась англоязычная версия цикла, прошедшая некоторую полировку по сравнению с оригинальным. За этот год мне написало несколько сотен человек, причём многие просили помочь отладить их код.

Я предлагаю вам поиграть в игру: я даю только картинку, на которой видна проблема, попробуйте понять, в каком месте кода нужно искать баг, что именно сломано. Я в эту игру играю ежедневно, досконально смотреть сотни версий рендера у меня нет никакой возможности, поэтому я, как заправский экстрасенс, лечу по фотографии. Зачастую успешно.

Абсолютно все картинки сгенерированы не мной, я лишь собрал самые типичные баги. Настоящая людская боль перед вашими глазами, ко мне, понятно, обращаются (особенно по почте) только после того, как не могут сами найти баг в разумное время.

Вот первый баг для затравки, слева битый рендер, справа то, что ожидалось:

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 1

Скрытый текст
Наипервейший хинт: очень круглая форма. Сразу намекает на то, что вместо массива вершин человек загрузил массив нормальных векторов, точнее, перепутал строки «v x y z» и «vn x y z» из .obj файла

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 2

Скрытый текст
Треугольники плохо стыкуются друг с другом. В wavefront .obj файлах индексы массивов начинаются с единицы, а не с нуля, человек забыл отнять единицу после прочтения файл модели.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 3

Скрытый текст
Обратите внимание, что все треугольники на их геометрическом месте, а проблемные места текстуры образуют полные кольца вокруг одной вершины, что намекает на то, что периодически одна вершина битая. Так и есть, был плавающий баг в прочтении текстурных индексов.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 4

Скрытый текст
На картинке тонировка Гуро, заполнение треугольника явно сделано при помощи сканирующей линии, когда вершины сортируются по их игрек-координате, а затем горизонтальными линиями заметается треугольник. Порядок вершин изменился, а вот цвет вершин поменять местами забыли. Очень частый баг.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 5

Скрытый текст
На картинке битый z-буфер. Практически то же самое, что и предыдущий баг, только забыли поменять z-координату вершин при сортировке.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 6

Скрытый текст
И опять тот же самый баг, но чуть-чуть в другом месте: при заметании треугольника он для удобства делится на две части, каждая горизонтальная линия рисуется слева направо. Меняя местами вершины линии, забыли про текстурные координаты.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 7

Скрытый текст
Ошибки округления, игрек сканирующей линии явно вычисляется интерполяцией, вместо того, чтобы по нему непосредственно сделать заметающий цикл.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 8

Скрытый текст
Опять ошибки округления, экранные вершины треугольника не были округлены перед растеризацией.

Тут полезно знать, что человек пытался сделать блестящую поверхность (specular map):

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 9

Скрытый текст
Неважно что в степени ноль даёт единицу...

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 10

Скрытый текст
Растеризация треугольника явно сделана через барицентрические координаты, и их неплохо бы сдвинуть по кругу при вычислении текстурных координат.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 11

Скрытый текст
Текстуру явно нужно перевернуть по вертикали

Ха, эта картинка очень похожа на предыдущую, но баг совсем другой (почему?)

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 12

Скрытый текст
Вместо текстурных координат человек просто использовал xy текущего пикселя для поиска цвета в текстуре...

Здесь и далее картинки до и после отладки:

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 13

Скрытый текст
Направление света было использовано для отсечения задних граней. А надо было бы направление взгляда...

Попытка применить карту нормалей:

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 14

Скрытый текст
Ну что, цвет, живущий в RGB [0,255]^3 был сконвертирован в XYZ, живущий в [0,2]^3, а не в [-1,1]^3.

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 15

Скрытый текст
При плоской тонировке (flat shading) вектор света и/или вектор нормали не был нормализован, в итоге попытка отрисовать цвета со значением более 255, переполнение unsigned char

Краткий курс компьютерной графики, аддендум: лечим по фотографии - 16

Скрытый текст
Явно опять переполнение, но на сей раз отрицательные значения. Человек забыл, что скалярное произведение бывает отрицательным. Картинка справа — это fabs(интенсивности), предыдущая картинка могла бы быть получена, если бы вместо fabs мы использовали обычный clamp

Have fun!

Автор: haqreu

Источник

Поделиться новостью

* - обязательные к заполнению поля