2

Я создаю шутер от первого лица в WebGL и в настоящее время отладки ранней версии в Chrome 31.0.1650.57WebGL: Низкая кадров в секунду и ~ 72% времени простоя

Приложение работает плохо около 7-8 кадров в секунду, и когда я Cpu профиль я получаю следующее:

enter image description here

и от этого она выглядит как центральный процессор не тратит время 72% делают ... ничего? Как получилось, requestAnimFrame дает мне этот низкий fps? Мои шейдеры действительно очень простые (в основном 1 лайнеры)

Моя игра петли по существу

function drawScene() { 
    requestAnimFrame(drawScene); 
    map.render(playerPosition); 
} 

Графика также в настоящее время очень просто. Я включил скриншот приложения, а также full .cpuprofile file.

screenshot

Может кто-нибудь объяснить, что время простоя может быть вызвано?

ОБНОВЛЕНИЕ: карта хранится в кучу «лица», где каждая грань представляет собой gl.TRIANGLE_FAN. Я не уверен, как я могу нарисовать несколько gl.TRIANGLE_FAN s (каждый с другим элементом «центр») в 1 вызов gl.drawElements.

Я попытался изменить код, чтобы один раз загрузить вершины в gpu, а затем просто загрузить индексы в массив вершин, но это заставляет gl.drawElements нарисовать 1 гигантский gl.TRIANGLE_FAN, что неверно. все gl.TRIANGLE_FAN s не используют одну и ту же «центральную» вершину.

Могу ли я каким-либо образом преобразовать gl.TRIANGLE_FAN s в gl.TRIANGLES или gl.TRIANGLE_STRIPS?

Я понимаю, что OpenGL имеет glMultiDrawElements, который делает именно то, что я wan't (давайте передадим размер каждого примитива), но не похоже, что он поддерживается в Webgl.

ответ

4

Глядя на ваш профиль, я замечаю, что вы проводите много времени в bufferData. Это говорит о том, что вы повторно загружаете данные в каждый кадр, а некоторые из остальных имен функций предполагают, что вы выполняете накладные вызовы drawArrays.

Обе эти вещи плохи для производительности. Я подозреваю, что ваше отсутствующее время идет на синхронизацию и передачу данных с помощью GPU-CPU, а не на время вычисления процессора или время вычисления процессора (последнее из них зависит от вашего профиля).

  1. Вы должны загрузить геометрию в GPU (bufferData) только один раз, а не каждый кадр (если что-то не на самом деле изменения или добавляются новые объекты в сцене, и т.д.), и

  2. вы должны попытаться свести к минимуму количество вызовов drawArrays за кадр (несколько партий из нескольких вершин, а не много партий из нескольких вершин).


Вы сказали, что ограничение в том, что ваши данные уровня состоит из отдельных вентиляторов треугольника. Вам нужно будет преобразовать эти треугольные вентиляторы в отдельные треугольники и объединить эти треугольники в один буфер. В WebGL ничего не делать, но если у вас есть вершины вентилятора 0 1 2 3 4 ..., где 0 - центральная вершина, то преобразование их в треугольники просто задает вершины (по буферу индекса или путем копирования вершин) в порядке

0 1 2 0 2 3 0 3 4 ... 

Тогда вы можете объединить много поклонников в один призыв к розыгрышу.