webgl2 - Объяснение для gl.TEXTURE0 n

Подмечаю в отладчике номер gl.TEXTURE0 ....31 . 0 + 31 = 32 32 объекта для текстур, но у меня есть только одна текстура.

Я нашел на сайте разработчиков Mozilla: "GL предоставляет 32 регистра текстур; первый из них - gl.TEXTURE0".

Когда я связываю следующий (второй текс), я использовал:

  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, textures[0]);
  gl.activeTexture(gl.TEXTURE1);
  gl.bindTexture(gl.TEXTURE_2D, textures[1]);

or :

  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, textures[0]);
  gl.activeTexture(gl.TEXTURE33);
  gl.bindTexture(gl.TEXTURE_2D, textures[1]);

person Nikola Lukic    schedule 28.03.2017    source источник


Ответы (1)


Если на сайте Mozilla написано

"GL предоставляет 32 текстурных регистра.

сайт неправильный

WebGL и WebGL2 имеют столько блоков текстуры, сколько поддерживает драйвер/графический процессор. Однако и WebGL1, и WebGL2 имеют минимальное количество. WebGL1 — 8 (8 текстур фрагментных шейдеров и 0 текстур вершинных шейдеров), WebGL2 — 32 (16 текстур фрагментных шейдеров и 16 текстур вершинных шейдеров).

Итак, лучше всего начать с единицы 0 и работать вверх. Если вам нужно использовать более 8 в WebGL1 или более 32 в WebGL2, вы должны узнать, сколько из них доступно, и либо сообщить пользователю, что он не может использовать ваш сайт, либо вернуться к более простому методу, который работает в пределах минимума.

Что касается более высоких чисел, гораздо проще просто использовать

var unit = ???;
gl.activeTexture(gl.TEXTURE0 + unit);
...

Потому что это соответствует тому, что вам нужно для настройки униформы сэмплера.

// bind a texture to texture unit 7
var unit = 7;
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, someTexture);

// and tell some sampler uniform to use texture unit 7
gl.uniform1i(someSamplerUniformLocation, unit);

Если вы не используете больше минимума, то вам не о чем спрашивать. Если вы используете больше минимума, вы можете запросить, позвонив

 const maxVertexTextureUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
 const maxFragmentTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
 const maxCombinedTextureUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);

MAX_COMBINED_TEXTURE_IMAGE_UNITS - это абсолютный максимум первых 2. В WebGL1 это 8. В WebGL2 это 32. Например, это означает, что в WebGL1 это

MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 4
MAX_TEXTURE_IMAGE_UNITS          = 8
MAX_COMBINED_TEXTURE_IMAGE_UNITS = 8

Это означает, что максимум вы можете использовать 8 единиц. Из них до 4 можно использовать в вершинном шейдере и до 8 можно использовать во фрагментном шейдере, но общее количество не может быть больше 8. Таким образом, если вы использовали 2 в вершинном шейдере, вы могли использовать только 6 связанный фрагментный шейдер, всего 8.

Проверяя webglstats.com, я вижу, что многие графические процессоры поддерживают 64 комбинированных текстурных блока, 32 в вершинном шейдере и 32 во фрагментном шейдере.

Что касается привязки текстур, вы привязываете их к конкретному вызову отрисовки. Другими словами, у вас может быть 1000 текстур, но вы можете использовать только MAX_COMBINED_TEXTURE_IMAGE_UNITS в одном вызове отрисовки.

Обычно

 pseudo code
 for each thing you want to draw
    use program for thing
    set attributes (bind a vertex array) for thing
    set uniforms and bind textures for thing
    draw
person gman    schedule 28.03.2017