Комментарии 14
Для меня эти дела ещё сложноваты, но я рискну.
Мой ответ
Чтобы не были видны грани и рёбра, ведь мы имитируем многогранником криволинейный объект.
Если быть более точным: чтобы при небольших поворотах модели или источника света освещение вело себя так, как будто освещено нечто криволинейное, а не вскрывало прямолинейные рёбра и плоские грани.
Если быть более точным: чтобы при небольших поворотах модели или источника света освещение вело себя так, как будто освещено нечто криволинейное, а не вскрывало прямолинейные рёбра и плоские грани.
Для отрисовки каждого пикселя растеризатор нам даёт барицентрические координаты пикселя (альфа, бета, гамма). Это означает, что текущий пиксель имеет пространственные координаты p = альфа p0 + бета p1 + гамма p2. Мы интерполируем текстурные координаты ровно так же, затем интерполируем и вектор нормали:Если я правильно понимаю, то линейно интерполировать текстурные координаты и нормали после проецирования (а раз речь идет о растеризаторе, то получается после) можно только в случае ортогональной проекции. Правильно?
В случае с перспективной проекцией, там будут искажения. Я когда-то очень давно писал свой софтовый рендер и уперся в эту проблему. Несколько дней дебажил, думал что проблема в коде, а оказалась — в математике.
Забавно то, что на моем Asus A686 (Windows Mobile 5.0) по какой-то причине растеризатор как раз не учитывал перспективные искажения, получались точно такие же забавные артефакты.
Есть еще один интересный момент, про который забыли сказать — само хранение и представление нормалей.
Дефакто подразумевается, что они приходят в RGB текстуре, где каждая компонента меняется в -127:127.
На самом деле это не так. Из-за того, что данные хранятся в нормализованном виде, часть значений не может быть использована.
Есть другой подход – "Octahedron normal vector encoding" – представление нормали как луча пересекающего октаеэдрон, или пирамиду. В том числе конечный 2д вектор представляется как 2д вектор, и чуть более "линеен".
Сам про это читал в документах valve, но сейчас не могу найти документ :(
Но в статье https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/ есть пара ссылочек на докумены с тервером…
PS: Картинка для привлечения внимания:
Дефакто подразумевается, что они приходят в RGB текстуре, где каждая компонента меняется в -127:127.
На самом деле это не так. Из-за того, что данные хранятся в нормализованном виде, часть значений не может быть использована.
Есть другой подход – "Octahedron normal vector encoding" – представление нормали как луча пересекающего октаеэдрон, или пирамиду. В том числе конечный 2д вектор представляется как 2д вектор, и чуть более "линеен".
Сам про это читал в документах valve, но сейчас не могу найти документ :(
Но в статье https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/ есть пара ссылочек на докумены с тервером…
PS: Картинка для привлечения внимания:
Признаться честно, я не то, что забыл, я никогда и не знал про другие способы хранения. Спасибо! Буду читать на досуге.
UPD: http://media.steampowered.com/apps/valve/2015/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf, 48 слайд, но лучше смотреть с начала.
Раздел по мультисемплингу будет?
Поправьте меня, если я не прав, но ведь первая normal-map задана скорее в object space, а не в world space. Чтобы трансформировать её в world space, нужно умножить на транспонированную обратную model-матрицу.
P.S. А репер — устоявщаяся терминология? Википедия говорит Поверхность.
P.S. А репер — устоявщаяся терминология? Википедия говорит Поверхность.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Краткий курс компьютерной графики: задание карт нормалей в касательном пространстве