Графика временно рисуется через glDrawArrays() без индексов. Число объектов на экране стало большим, пришло время задуматься о производительности.
Я думал, что основная проблема - большие заливаемые площади (филлрейт), но нет, при вписывании координат (0;0;0) в вершинный шейдер фреймрейт повысился несильно. Очевидно, проблема в большом количестве вершин.
Вершины у меня имеют по 20 float-координат (5 х vec4). Временно убрал один вектор, стало 16 флоатов. Фреймрейт не поднялся ни на кадр. Это что же, количество занимаемой вершинами памяти тоже неважно, причем ни насколько? Прежде чем начать заниматься индексами и всем остальным хотелось бы выяснить, на что сейчас вообще тратится фреймрейт.
GPU Intel HD4000. Вся геометрия в нескольких крупных VBO, вызовов glDrawArrays() немного, порядка 20-24 вызовов за кадр.
Роман Шувалов
что происходит в вершинном шейдере? как ты переключаешь стейты(текстуры, юниформы, шейдеры, буферы)? сколько мс уходит на кадр?
Роман Шувалов
Для начала неплохо было бы узнать на CPU или на GPU ботлнек.
Что говорит intel gpa? Ну или на худой конец GPUView?
Suslik
> что происходит в вершинном шейдере?
В данный момент ничего, glPosition = vec4(0.0, 0.0, 0.0, 1.0);
> как ты переключаешь стейты(текстуры, юниформы, шейдеры, буферы)?
Эээ через glTexture2D, glUniform и всё прочее. Буфер через VAO, glBindVertexArray. Но этих вызовов ничтожно мало, буквально 20 вызовов за кадр.
> сколько мс уходит на кадр?
В данный момент на почти пустом экране 32 fps, 30 мс на кадр.
И да, я тут решил посчитать число вершин... 2 миллиона вершин :)
MrShoor
> Для начала неплохо было бы узнать на CPU или на GPU ботлнек.
При малом количестве вершин всё в порядке. Данные хранятся на GPU. Значит CPU ни при чём.
> Что говорит intel gpa? Ну или на худой конец GPUView?
Я забыл сказать, что у меня тут линукс. С инструментарием по анализу производительности GPU не знаком, т.к. как-то не было нужды до сегодняшнего дня.
Роман Шувалов
> И да, я тут решил посчитать число вершин... 2 миллиона вершин :)
Солидное число. Кажется пришло время добавить фрустум куллинг. :)
> Данные хранятся на GPU. Значит CPU ни при чём.
> Я забыл сказать, что у меня тут линукс.
Я как то однажды напарывался на то, что дефолтные драйвера винды делали для DX10 инстансинг софтварно. Т.е. буквально эмулировали его, что приводило к жутким тормозами на стороне CPU, хотя рисовалось там всего несколько десятков тысяч вершин. Так что я бы все равно проверял этот момент. С другой стороны я совершенно не знаю как профайлить графику на чем то отличном от винды.
Роман Шувалов
> Эээ через glTexture2D, glUniform и всё прочее. Буфер через VAO, glBindVertexArray. Но этих вызовов ничтожно мало, буквально 20 вызовов за кадр.
учти, что смена стейтов — вовсе не бесплатное удовольствие, и если их менять направо-налево, то баттлнек вполне может перекочевать в них. например, смена vao, смена текстур и шейдеров — одни из самих дорогих вызовов сами по себе вне зависимости от типа данных, которые они, собственно, меняют. то есть забайндить vao с 2 миллионами трайэнглов занимает столько же времени, сколько забайндить vao с 2 трайэнглами.
> В данный момент на почти пустом экране 32 fps, 30 мс на кадр.
судя по всему, в дело ещё вмешивается всеми любимый интелловский чип, который иногда работает медленнее, чем можно представить в самых смелых фантазиях.
> И да, я тут решил посчитать число вершин... 2 миллиона вершин :)
нутыпонил. просто таскание 2e+6 вершин между шейдерами вполне может занимать 30мс на интелловском поделии. ещё на всякий случай спрошу — ты уверен, что случайно не заливаешь эти 2 ляма вершин на видюху каждый кадр?
MrShoor
> Солидное число. Кажется пришло время добавить фрустум куллинг. :)
Это само собой, еще я отсортирую треугольники по направлению нормали и буду отсекать обратные стороны статичных объектов.
> инстансинг софтварно
Инстансинга нет и скорее всего не будет. Но я учту, что такое случается.
Suslik
> смена текстур и шейдеров — одни из самих дорогих вызовов сами по себе вне зависимости от типа данных
Т.е. имеет смысл один раз накидать все текстуры в текстурные юниты, а в шейдеры вписать индекс юнита, чем всё подряд биндить в GL_TEXTURE0, так? Я и так это подозревал, просто не думал, что это настолько важно.
> просто таскание 2e+6 вершин между шейдерами вполне может занимать 30мс на интелловском поделии.
Хотел спросить "какое таскание", как вспомнил, что отрисовки-то две - в карту теней и во вьюпорт пользователя. И в каждой отрисовке свой шейдер.
Кстати, если вместо 2 млн вершин будет 2 млн индексов при, скажем, 1 млн вершин, ситуация улучшится?
В общем суть понятна, если бы я сразу посчитал вершины то и тему бы не создавал. А на Интеле хочу завести, чтоб быть уверенным, что на любом другом GPU всё будет в порядке. Ну и это единственное что есть у меня в распоряжении.
Роман Шувалов
> Т.е. имеет смысл один раз накидать все текстуры в текстурные юниты, а в шейдеры
> вписать индекс юнита, чем всё подряд биндить в GL_TEXTURE0, так? Я и так это
> подозревал, просто не думал, что это настолько важно.
это может помочь, если производительность упрётся в переключение стейтов. но она может упереться во что-то другое и тогда визуальной разницы не будет. оба случая бывают.
Роман Шувалов
> Хотел спросить "какое таскание"
в смысле сделать что угодно с 2 миллионами чего угодно за кадр на интелловской видюхе — это уже попахивает временем порядка миллисекунд, лол.
Роман Шувалов
> Кстати, если вместо 2 млн вершин будет 2 млн индексов при, скажем, 1 млн
> вершин, ситуация улучшится?
Улучшится, и тут тоже все вилами по воде писано. Если вершинный шейдер легкий - то улучшится незначительно. Если вершинный шейдер экстремально тяжелый - то улучшения должны быть заметны. При количестве инструкций в вершинном шейдере стремящемся к бесконечности - производительность увеличится в 2 раза, если обрабатывать 1 млн с индексами вместо 2 без индексов.
Роман Шувалов
> Это само собой, еще я отсортирую треугольники по направлению нормали и буду
> отсекать обратные стороны статичных объектов.
Если ты каждый кадр собрался сортировать отдельные треугольники - то лучше даже не пробуй. Тормозить будет люто. Если сортировать - то только целиком объектами или пачками по много треугольников.
А вообще с сортировкой лучше заморачиваться в самую последнюю очередь, когда ты точно знаешь, что упирается в филлрейт например.
Поидее в твоем случае фрустум куллинг порвет все. Мне когда-то давно давно дали проект: сделать примитивные гоночки. Ну я сделал, а потом заказчик прислал трассу, одним мешем в 10М вершин. Все конечно же стало колом (в единицы FPS). Сложил я этот меш в октри, врубил фрустум куллинг и все сразу заиграло на 100+ FPS.
Роман Шувалов
Сколько раз вызывается glDrawArrays() за один кадр?
Vitorio
> Сколько раз вызывается glDrawArrays() за один кадр?
Написано же в нульпосте.
MrShoor
Спасибо. Не увидел%)
MrShoor
> Если ты каждый кадр собрался сортировать отдельные треугольники - то лучше даже не пробуй.
Нее, 1 раз во время загрузки.
А фрустумом так просто всё решить не удастся - перед носом у игрока может быть очень много объектов. Тут уже спасёт только туман и снижение ЛОДа на заднем плане, что сделать будет непросто, т.к. геометрия генерированная. Потом покажу. Анонс проекта уже в этом месяце.
Роман Шувалов
> Графика временно рисуется через glDrawArrays() без индексов.
что-то пошло не так
> > Если ты каждый кадр собрался сортировать отдельные треугольники - то лучше
> > даже не пробуй.
> Нее, 1 раз во время загрузки
ну не так пошло, не так :)
Тема в архиве.