Блог страдающего Лиса
Lorem ipsum hello dolor sit world amet
23 фев 2023 Чт
Про то, как я хочу сделать треугольники
У меня давным-давно есть одна мысль, которая называется "трехмерный рендерер на верилоге", о котором я часто думаю и не знаю, насколько результативно. Мне хочется сделать пусть даже небольшой, но код для плис, где автоматически из буфера могли бы рисоваться трехмерные треугольники. Это крайне непростая задача, хоть и рисование обычного треугольника не так сложно, но полноценный вывод трехмерного изображения на экран потребует довольно крупных усилий.
Как все это работает? Существует несколько буферов в памяти:
По мере построчного рисования, будет рисоваться буфер из треугольников, интегрально прибавляя значения, формируя точку на текстуре и точку глубины, записывая эти данные в однострочный буфер глубины. Каждый раз после того, как будет нарисована одна линия, этот буфер очищается для новой линии.
Другими словами, на каждой линии будет отрисовываться несколько текущих рисуемых треугольников за раз. После того, как это будет сделано, из полученного буфера размером в одну строку будут скопированы и вычислены текстуры, итоговый цвет записан в видеобуфер и сам строчный буфер очищен для новой строки.
Вот такая вот сложная система.
Как все это работает? Существует несколько буферов в памяти:
- Буфер вершин (vertex), где хранятся все исходные вершины для рендерера
- Буфер индексов (indicied), там хранится номер вершины
- Текстурный буфер для треугольников
- Просматривается буфер вершин, к каждой вершине применяется матрица камеры, то есть, умножается на эту матрицу (она задана float или half-precision значениями). На самом деле для матрицы камеры вполне достаточно даже и half-precision, я думаю.
- Просматривается буфер индексов, проверяя то, где находится та или иная вершина. Если все вершины находятся впереди проецирующей плоскости, то такой треугольник добавляется в буфер очереди на рисование. Если все вершины вне пределов проецирующей плоскости, то треугольник вообще в очередь не добавляется. В случае частичного попадания за плоскость, треугольник разбивается на 2 части и добавляется в очередь как два треугольника. В очередь добавляются уже готовые вершины, не привязанные к vertex/indicies
- Происходит вычисление параметров треугольников для текстурирования и записывается в отдельный буфер. Тут очень много умножений.
- Для каждой точки вычисляется проекция. Здесь уместно использование конвейерного деления для ускорения.
- Все полученные точки треугольников сортируются пирамидальной сортировкой по возрастанию спроецированного Y. Причем сортируется только самая высокая вершина (которая имеет наименьший Y). Также, сортируются именно индексы новых точек. Это нужно для того, чтобы не перемещать большие объемы данных внутри буфера рендеринга, а только лишь индексы. Каждая вершина имеет индекс принадлежности к определенному треугольнику
- И последний этап, это рендер.
По мере построчного рисования, будет рисоваться буфер из треугольников, интегрально прибавляя значения, формируя точку на текстуре и точку глубины, записывая эти данные в однострочный буфер глубины. Каждый раз после того, как будет нарисована одна линия, этот буфер очищается для новой линии.
Другими словами, на каждой линии будет отрисовываться несколько текущих рисуемых треугольников за раз. После того, как это будет сделано, из полученного буфера размером в одну строку будут скопированы и вычислены текстуры, итоговый цвет записан в видеобуфер и сам строчный буфер очищен для новой строки.
Вот такая вот сложная система.