Компьютерная графика

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Компьютерная графика » Программирование графики и GPU » Ламерский вопрос по шейдерам


Ламерский вопрос по шейдерам

Сообщений 1 страница 8 из 8

1

Пишу на досуге движок (без претензий на шедевр). В числе прочего склепал скелетную анимацию классического формата: кости приводятся по интерполированным ключам в желаемую позу, затем по положению костей в соответствии с их весами в вершине ошкуривается меш (вычисляется позиция вершины относительно каждой кости как единственной, а затем взвешенная сумма даёт итоговую позицию). Полученные позиции вершин пишутся в вершинный буфер (массив float*).  После этого в соответствии с индексным буфером (массив unsigned int*) осуществляю рендер:

    glEnableClientState (GL_VERTEX_ARRAY);
    glEnableClientState (GL_NORMAL_ARRAY );
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);

    glBindTexture ( GL_TEXTURE_2D, m_uTextureID );
    glVertexPointer (3,GL_FLOAT,0,m_pfVertexBuffer);
    glTexCoordPointer(2,GL_FLOAT,0,m_pfTexCoordBuffer);
    glNormalPointer(3,GL_FLOAT,m_pfNormalBuffer);
   
    glDrawElements(GL_TRIANGLES, m_uiNumFaces*3, GL_UNSIGNED_SHORT, m_pusIndexBuffer);

    glDisableClientState (GL_VERTEX_ARRAY);
    glDisableClientState (GL_NORMAL_ARRAY );
    glDisableClientState (GL_TEXTURE_COORD_ARRAY);

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

   И вот вопрос. Вершинный шейдер, как известно, обсчитывает одну вершину. Но сами-то вершины поступают в соответствии с их индексами в треугольниках, которых уже больше чем вершин раза в полтора. А в каждом треугольнике их, как известно, три. :)
    То есть вырисовывается нехорошая перспектива обрабатывать каждую вершину по несколько раз, что, разумеется, неправильно.
Не использовать же GPU тоже неправильно. А потому спрашиваю у мудрого сихана и опытных сэмпаев: а что мне, собственно, делать?
Кидать на вывод вершинный буфер без индексного не получается: тогда грани формируются из вершин в произвольном порядке и получается кракозябр. Буду очень рад пояснению. Заранее прошу прощения за глубинное ламерство. :)

0

2

А если попробовать NV_transform_feedback или рендеринг в вершинный буфер - все делается на GPU, причем просто изменяется содержимое буфера с кординатами вершин

0

3

Steps3D написал(а):

рендеринг в вершинный буфер

Если я правильно понимаю, то заводится текстура. Шейдер для каждой вершины рассчитывает окончательные параметры (координаты нормаль и т.п.) и пишет их в эту текстуру. Далее содержимое текстуры (которая на самом деле хранилище вершинных данных) рендерится в соответствии с индексами вершин в треугольниках.
Так?

0

4

На самом деле просто содержимое текстуры копируется в вершинный буфер, который рендерится
При этом все действия происходят на GPU

0

5

Приношу извинения за ламерство. :)
Изначально ведь содержимое текстуры должно быть заполнено (на каждом шаге цикла анимации). Как я могу понимать, заполняется оно параметрами вершин одновременно с их расчётом. Т.е. в памяти компа лежат исходные данные вершин и текущие (только что полученные) данные костей. И то, и другое отправляется в шейдер (к примеру, в силу того что костей на вершину у меня не более 4-х, я набор преобразований кости решил отсылать как две матрицы 4х4 - в одной лежат кватернионы, в другой - вектора смещения; веса костей в вершине отправляются как вектор). Шейдер-1 их обсчитывает и текущие характеристики вершины кладёт в текстуру (возможно, сразу в несколько мест в соответствии с индексами вершин в треугольниках).  Далее, видимо, шейдер-2 должен скопировать полученные т.о. данные для всех вершин меша в вершинный буфер.
   Вопрос такой: шейдер-1 это, судя по всему, вершинный шейдер. А шейдер-2?
Ещё раз приношу извинения за ламерство: я явно пока ещё не всё понимаю в процессе, которым стремлюсь управлять. :)

0

6

1. при рендеринге в вершинный буфер практически все делает фрагментный шейдер - т.е. каждый элемент текстуры рассчитывается именно фрагментным шейдером. Т.е. тут можно иметь просто две текстуры - одну для предыдущего кадра, одну для текущего - через рендеринг в тектуру вычисляются данные для текущего кадра (и записываются в текстуру), потом содержимое эжтой текстуры копируется в вершинный буфер.
Т.ек. всю работуц по анимацции делает фрагментный шейдер на этапе рендеринга в текстуру - посмтрите у меня на сайте статью

2. Второй вариант - NV_transfoirm_feedback (EXT_transform_feedback) - тут никаких текстур нет, все считает именно вершинный шейдер - есть два вершинных буфера - для предыдущего каждроа и для текущего. Далее делается рендлеринг в режиме transform_feedback - тогда когда вершины будут обработамы вершинным шейденром никакого рендеринга не будут, а вершины запишутся в другой вершинный буфер.
В результате любого из этих подходов Вы один раз считате вершины и записываете их во второй вершинный буфер. После чего оснвоной рендер просто использует уже готовые вершины

0

7

Как я понял, эти расширения поддерживаются только картами nVidia. А хотелось бы сделать нечто более общее и попроще. :)
Попробую сформулировать вопрос иначе:
Есть изменяющийся во времени меш. Хочется рассчитывать текущее положение каждой вершины на GPU. А также хочется при рендере указывать системе порядок расположения вершин в треугольниках через GL_TRIANGLES. Как это сделать максимально простым и общеупотребимым способом?
  Ещё раз приношу извинения за ламерство. :)

0

8

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

0


Вы здесь » Компьютерная графика » Программирование графики и GPU » Ламерский вопрос по шейдерам


создать форум