Нулевой gl_VertexID для каждой вершины при перерисовке из обработчика событий в Firefox

#firefox #safari #webgl #webgl2

Вопрос:

Я использую gl_VertexID для выбора текстуры (передавая ее в переменной от вершины к шейдеру фрагментов), и этот подход хорошо работает для первого drawElements() . Но когда я перерисовываю кадры на mousemove событии, мой шейдер получает ноль gl_VertexID для каждой вершины в Firefox (в Chrome он отлично работает).

ОБНОВЛЕНИЕ: я прикрепляю код своих шейдеров:

вершина.glsl:

 #version 300 es

precision mediump float;

in vec2 texture;
in vec3 position;

out vec2 vert_texture;
flat out int vert_vertex_id;

uniform mat4 projection;
uniform mat4 view;

void main() {
    vert_texture = texture;
    vert_vertex_id = gl_VertexID;
    gl_Position = projection * view * vec4(position, 1.0);
}
 

фрагмент.glsl

 #version 300 es

precision mediump float;

in vec2 vert_texture;
flat in int vert_vertex_id;

out vec4 frag_color;

uniform int texture_index[MAX_TEXTURE_IMAGE_UNITS];
uniform sampler2D textures[MAX_TEXTURE_IMAGE_UNITS];

vec4 get_texture_color(int index, vec2 point) {
    switch (index) {
        case 0: return texture(textures[0], point);
        case 1: return texture(textures[1], point);
        case 2: return texture(textures[2], point);
        case 3: return texture(textures[3], point);
        case 4: return texture(textures[4], point);
        case 5: return texture(textures[5], point);
        case 6: return texture(textures[6], point);
        case 7: return texture(textures[7], point);
#if MAX_TEXTURE_IMAGE_UNITS >= 16
        case 8: return texture(textures[8], point);
        case 9: return texture(textures[9], point);
        case 10: return texture(textures[10], point);
        case 11: return texture(textures[11], point);
        case 12: return texture(textures[12], point);
        case 13: return texture(textures[13], point);
        case 14: return texture(textures[14], point);
        case 15: return texture(textures[15], point);
#endif
#if MAX_TEXTURE_IMAGE_UNITS >= 32
        case 16: return texture(textures[16], point);
        case 17: return texture(textures[17], point);
        case 18: return texture(textures[18], point);
        case 19: return texture(textures[19], point);
        case 20: return texture(textures[20], point);
        case 21: return texture(textures[21], point);
        case 22: return texture(textures[22], point);
        case 23: return texture(textures[23], point);
        case 24: return texture(textures[24], point);
        case 25: return texture(textures[25], point);
        case 26: return texture(textures[26], point);
        case 27: return texture(textures[27], point);
        case 28: return texture(textures[28], point);
        case 29: return texture(textures[29], point);
        case 30: return texture(textures[30], point);
        case 31: return texture(textures[31], point);
#endif
    }
}

void main() {
    for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS;   i) {
        if (vert_vertex_id < texture_index[i]) {
            frag_color = get_texture_color(i, vert_texture);
            break;
        }
    }
}
 

Здесь я использую gl_VertexID переданный из вершинного шейдера для определения количества текстур путем доступа texture_index .

ОБНОВЛЕНИЕ 2: Я обнаружил такое же поведение в Safari (после включения WebGL2), поэтому могу предположить, что это не ошибка Firefox.

Комментарии:

1. Я использую firefox 68 на macos 10.12 и только вчера реализовал вершинный шейдер drawArrays на основе gl_VertexID, и он работает здесь, хотя я не передаю его шейдеру фрагментов. Также я анимирую с помощью requestAnimationFrame. У вас есть какой-нибудь код, которым можно поделиться?

2. Поэтому я просто попытался передать gl_VertexID своему шейдеру фрагментов. Поскольку это не соотношение 1:1, int передается «плоским», но тогда это, по-видимому, подчиняется правилам «ProvokingVertex», которые, хотя и не представлены в API WebGL2, мне кажется, что они реализованы как последняя вершина каждого треугольника. Может быть, вы это уже знаете, но я кое-чему научился 🙂

3. @Питер Я поделился кодом шейдеров.

4. Что ж, похоже, ты намного опередил меня в этом деле. До сих пор я не пробовал новый текстурный массив. Похоже, вы визуализируете GL_POINTS, поэтому «вызывающая вершина» не должна быть проблемой. (vert_vertex_id Просто наблюдение, и не связанное с реальной проблемой. Может быть, попробуйте переключить цикл рендеринга на RAF, так как здесь это, похоже, работает. Я использую tinygo/Wasm, но рад поделиться некоторым кодом, если это необходимо. Единственное другое предложение-в firefox есть настройка аппаратного ускорения. Извини, что я не смог тебе больше помочь.