У меня есть определенная библиотека, которая использует WebGL1 для рендеринга. Он активно использует текстуры с плавающей запятой и инстансный рендеринг.
В настоящее время кажется, что поддержка WebGL1 довольно странная, поскольку некоторые устройства поддерживают, например, WebGL2, где эти расширения являются основными, но не поддерживают WebGL1 или поддерживают его, но не расширения.
В то же время поддержка WebGL2 не впечатляет. Может быть, когда-нибудь так и будет, но ведь это не так.
Я начал смотреть, что потребуется для поддержки обеих версий.
Что касается шейдеров, я думаю, что в основном я могу обойтись #define
с вещами. Например, #define texture2D texture
и другие подобные вещи.
Когда дело доходит до расширений, это становится более проблематичным, поскольку объекты расширения больше не существуют. В качестве эксперимента я попытался скопировать свойства расширения в объект контекста, например gl.drawArraysInstanced = (...args) => ext.drawArraysInstancedANGLE(...args)
.
Когда дело доходит до текстур, менять особо нечего, возможно, добавить что-то вроде gl.RGBA8 = gl.RGBA
при работе в WebGL1, таким образом, он будет «просто работать» при работе в WebGL2.
Тогда возникает вопрос ... Кто-нибудь пробовал это? Меня беспокоит, что это повлияет на производительность, особенно из-за дополнительной косвенности для вызовов функций. Это также сделает чтение кода менее очевидным, если предполагается, что он может работать в WebGL1. В конце концов, ни в одном контексте WebGL1 нет drawArraysInstanced
или RGBA8
. Это также мешает набирать TypeScript и другие мелочи.
Другой вариант - иметь ветки по всему коду. Две версии шейдеров (или #ifdef
обман), множество разветвлений для каждого места, где требуются форматы текстур, и для каждого места, где выполняется создание экземпляров. Иметь что-то вроде того, что следует повсюду, довольно некрасиво:
if (version === 1) {
instancedArrays.vertexAttribDivisorANGLE(m0, 1);
instancedArrays.vertexAttribDivisorANGLE(m1, 1);
instancedArrays.vertexAttribDivisorANGLE(m2, 1);
instancedArrays.vertexAttribDivisorANGLE(m3, 1);
} else {
gl.vertexAttribDivisor(m0, 1);
gl.vertexAttribDivisor(m1, 1);
gl.vertexAttribDivisor(m2, 1);
gl.vertexAttribDivisor(m3, 1);
}
Наконец, может быть, есть третий способ, о котором я не подумал.
Есть рекомендации?