Проблемы производительности WebGL с сеткой вершин>65k на MacBook Pro

Следующая модель имеет хорошую производительность на нескольких бюджетных машинах:

http://examples.x3dom.org/example/x3dom_sofaGirl.html

Однако на MacBook Pro с Nvidia GT 650m частота кадров очень низкая. Я думал, что это потому, что MacBook не имеет OES_element_index_uint расширение, но расширение появляется, если я делаю:

document.createElement("canvas").getContext("experimental-webgl").getSupportedExtensions();

Реструктуризация сетки ниже 65К решает проблему. Есть ли способ добиться хорошей производительности без реструктуризации?

Я установил приложение (gfxCardStatus), которое отключило GT 650m и принудительно использовало только встроенную графику. Теперь все работает отлично. Это ошибка драйвера?

Я нашел еще одну 3d-сцену, которая работает на выделенном графическом процессоре быстрее, чем на встроенном:

http://examples.x3dom.org/binaryGeo/oilrig_demo/index.html

Я думаю, это потому, что он состоит из множества маленьких ячеек. Также, когда я запускаю эту сцену, я слышу, как вентилятор GPU раскручивается Это не было со сценой GirlGirl.

1 ответ

Во-первых, WebGL не ограничивается 65 тыс. Вершин на вызов. gl.drawElements имеет ограничение в 64 КБ, хотя есть расширения, которые удаляют это ограничение. gl.drawArrays не имеет такого ограничения, хотя.

Я не знаю, почему это медленно, но глядя на фрейм в WebGL Inspector X3DOM использует gl.drawArrays

x3dom не ограничивается 65k

Я вырыл немного больше. Я попытался использовать Web Tracing Framework, а также профилировщик Chrome. Это показало много времени, проведенного в gl.readPixels,

профилировщик, показывающий readpixels

Чтобы увидеть, была ли это проблема, я открыл консоль JavaScript и заменил gl.readPixels с такой операцией

В консоли JavaScript:

// find the canvas
c = document.getElementsByTagName("canvas")[0]

// get the webgl context for that canvas
gl = c.getContext("webgl")

// replace readPixels with a no-op
gl.readPixels = function(x, y, w, h, f, t, b) { 
  var s = w * h * 4; 
  for (var ii = 0; ii < s; ++ii) {
    b[ii] = 0;
  }
};

Что убрано readPixels от появления в профилировщике

но образец не работал быстрее.

Далее я попробовал взлом drawArrays рисовать меньше.

В консоли JavaScript:

// save off the original drawArrays so we can call it
window.origDrawArrays = gl.drawArrays.bind(gl)

// patch in our own that draws less
gl.drawArrays = function(t, o, c) { window.origDrawArrays(t, o, 50000); }

Что вы знаете, теперь он работает очень быстро. Хм. Может быть, это ошибка драйвера. Его просили нарисовать 1070706 вершин, но вряд ли это большое количество для NVidia GT 650m


Итак, я не знаю почему, но мне хотелось изучить этот вопрос. Я написал собственное приложение для отображения тех же данных. Он работает со скоростью 60 кадров в секунду легко. Я проверил интегрированную графику в WebGL, как сказал OP. Также 60fps легко. NVidia 650GT находится на скорости около 1 кадра в секунду.

Я также проверил Safari и Firefox. Они тоже бегают медленно. Общее дело там - УГОЛ. Все они используют ANGLE для переписывания шейдеров. Возможно, есть проблема, так как тот же шейдер работал нормально на моем родном тесте. Конечно, тест Native не выполняет те же функции, что и WebGL, но он не только рисует 1M polys.

Поэтому я подал ошибку: https://code.google.com/p/chromium/issues/detail?id=437150

Другие вопросы по тегам