Входная переменная беззнакового целого числа WebGL 2.0

Я пытался указать буфер Uint32Array на входную переменную uint.

Вся информация, которую я могу найти в Интернете, говорит о том, что это должно быть возможно, но я получаю одну и ту же ошибку, что бы я ни делал:

[.WebGL-0x62401b7e200] GL_INVALID_OPERATION: Vertex shader input type does not match the type of the bound vertex attribute.

Вот мой вершинный шейдер:

#version 300 es
in vec4 a_ipos;
in uint a_cdata;
uniform vec2 ures;

void main() {
    uint x = a_cdata & 0x7C00u;
    uint y = a_cdata & 0x03E0u;
    uint z = a_cdata & 0x001Fu;

    vec4 pos = a_ipos + vec4(float(x), float(y), float(z), 1.);

    gl_Position = vec4(pos.x * ures.y / ures.x, pos.yzw);
}

И вот мой вызов webgl, чтобы указать буфер на атрибут:

gl.bindBuffer(gl.ARRAY_BUFFER, chunkBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Uint32Array(chunkData), gl.STATIC_DRAW);
gl.enableVertexAttribArray(cdataloc);
gl.vertexAttribPointer(
    cdataloc,
    1,
    gl.UNSIGNED_INT,
    false,
    0,
    0
);

Кажется, gl.UNSIGNED_INT не относится к тому же типу, что и uint. Однако в справочной карте GLSL 300 ES указано, что это 32-битное целое число без знака. MDN согласен, что gl.UNSIGNED_INT — это 32-битное целое число без знака.

Я понятия не имею, что я делаю неправильно. Я пробовал использовать gl.INT и in int ..., но все равно ничего. Изменение точности целых чисел на highp также ничего не меняет. (при условии, что highp преобразует целые числа в 32-битные, что, похоже, не так).

Изменение типа на float работает. Но любой другой тип, который я использую, этого не делает.

Я также попробовал использовать gl.SHORT. Это делается для того, чтобы отказаться от теории о том, что тип int в glsl может быть 16-битным целым числом. Все та же ошибка.

Этот вопрос: WebGL: как использовать целочисленные атрибуты в GLSL.

Не решает мою проблему. Поскольку документация, предоставленная в ответе, устарела. GLSL 1.00 ES не допускает целых чисел в атрибутах согласно спецификации .

Однако спецификация GLSL 3.00 ES, похоже, не имеет значения, пока тип не является одним из следующих: boolean, opaque, array, struct.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
157
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это своего рода классическая ошибка. Данные type в vertexAttribPointer() относятся к типу данных в самом массиве (или в буфере).

Он не относится к типу данных атрибута в шейдере. Когда вы используете vertexAttribPointer() данные (по-прежнему) преобразуются в числа с плавающей запятой. Вы можете использовать normalized, чтобы контролировать, нормализуется он или нет, но он все равно преобразуется в числа с плавающей запятой.

На самом деле вам нужно vertexAttribIPointer() (обратите внимание на I для целого числа.)

vertexAttribPointer()
//          ^ No I so Float
vertexAttribIPointer()
//          ^ I for Integer

В документации по vertexAttribPointer() он также упоминается в разделе Целочисленные атрибуты:

Целочисленные атрибуты

Хотя ArrayBuffer может быть заполнен как целыми числами, так и числами с плавающей запятой, атрибуты всегда будут конвертироваться в число с плавающей запятой, когда они отправляются в вершинный шейдер. Если вам нужно использовать целые числа в коде вершинного шейдера, вы можете либо привести число с плавающей точкой обратно к целому числу в вершинном шейдере (например, (int) floatNumber), либо использовать gl.vertexAttribIPointer() из WebGL2.


Вы также можете прочитать больше об этом в спецификации в разделе «Униформа и атрибуты».

Я не пытался проверить, решит ли это мою проблему. Если да, то я отмечу это как ответ. Однако если это правда. КАК В САМОЙ ГЛУБОКОЙ ЯМЕ АДА КТО-ТО ДУМАЕТ, ЧТО ДОБАВИТЬ 2 ФУНКЦИИ, КОТОРЫЕ НА ВЗГЛЯД ВЫГЛЯДЯТ ИДЕНТИЧНЫЕ, НО ВЫПОЛНЯЮЩИЕ 2 СОВСЕМ РАЗНЫЕ ВЕЩИ, БЫЛО ХОРОШЕЙ ИДЕЕЙ? Спасибо, что уделили время поиску решения моей проблемы.

Carlo Augusto Bagnoli Gomez 22.03.2024 01:46

На самом деле сейчас, когда я читаю документацию в MDN. Тогда документы на vertexAttribPointer неверны. Я собираюсь сообщить об этом в Mozilla.

Carlo Augusto Bagnoli Gomez 22.03.2024 02:01

Пожалуйста! Судя по ошибке и фрагменту кода, я могу с уверенностью сказать, что это ваша проблема. Однако не стесняйтесь комментировать, если это не решит проблему. Но да, как я уже сказал, это очень классическая ошибка. Даже новый OpenGL API «страдает» от этого, имея glVertexAttribFormat() и glVertexAttribIFormat() или еще более запутанные glVertexArrayAttribFormat() и glVertexArrayAttribIFormat(), если вы используете DSA.

vallentin 22.03.2024 02:01

Какая часть документации Mozilla, по вашему мнению, неверна? Использование целочисленных данных type для vertexAttribPointer() вполне допустимо, если вы хотите, чтобы они интерпретировались как число с плавающей запятой. Только сейчас я понимаю, что в документации Mozilla это также упоминается, в разделе Целочисленные атрибуты (я обновил ответ, включив в него цитату)

vallentin 22.03.2024 02:03

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