Я пытаюсь заставить этот шейдер работать на действительно старом iDevice, а также на Android.
Даже когда я уменьшаю код до 2 синусоидальных функций на фрагмент, шейдер работает со скоростью около 20 кадров в секунду.
Я подумал о том, чтобы взять лист из книги старых методов шейдинга и создать массив, который содержит набор предопределенных значений триггеров и каким-то образом использовать их для аппроксимации шейдера.
В шейдере, с которым я связан выше, я уже симулирую, что, округляя значения, отправленные в функцию триггера, чем дальше левая мышь (при нажатии), тем меньше качество шейдера. Это на самом деле довольно круто, потому что очень близко к левой стороне это выглядит как совершенно другой и довольно крутой шейдер.
Во всяком случае, у меня есть две дилеммы:
- Я не знаю, какой самый эффективный способ иметь массив из 360 значений в шейдере GLSL, постоянный или равномерный?
Я не могу понять, как поместить число в диапазон, как обычно, если бы я хотел угол между 0 и 360 (да, я знаю, что графические процессоры используют радианы), я бы сделал это так.
func range(float angle) { float temp = angle while (temp > 360) {temp -= 360;} while (temp < 0) {temp += 360;} return temp; }
Однако GLSL не допускает циклы while или рекурсивные функции.
источник
mod
функция - то, что вы хотите. Вы бы написалиmod(angle, 360.0)
.Ответы:
GL_REPEAT
качестве режима обтекания текстуру, и он автоматически запустится в начале снова при доступе с аргументами> 1 (и аналогично для отрицательных аргументов).GL_LINEAR
качестве фильтра текстуры, таким образом получая значения, которые вы даже не сохраняли. Конечно, линейная интерполяция не является на 100% точной для тригонометрических функций, но она, безусловно, лучше, чем без интерполяции.float sin = 2.0 * (texValue.r + texValue.g / 256.0) - 1.0;
(или даже больше компонентов для более мелкого зерна). Это позволяет вам снова получать прибыль от многокомпонентных текстур.Конечно, все еще необходимо оценить, является ли это лучшим решением, поскольку доступ к текстуре также не является полностью бесплатным, а также то, какова будет наилучшая комбинация размера и формата текстуры.
Что касается заполнения текстуры данными и адресации одного из ваших комментариев, вы должны учитывать, что фильтрация текстуры возвращает точное значение в центре текселя , то есть координату текстуры, уменьшенную на половину размера текселя. Так что да, вы должны генерировать значения на
.5
текселях , то есть что-то вроде этого в коде приложения:Однако вы, возможно, все же захотите сравнить производительность этого подхода с подходом, использующим небольшой однородный массив (т. Е.[0,360)
uniform float sinTable[361]
Или, может быть, на практике меньше, следите за ограничением вашей реализации на единообразном размере массива), который вы просто загружаете с соответствующими значениями, используяglUniform1fv
и получить доступ, отрегулировав свой угол до с помощью функции и округлив его до ближайшего значения:mod
источник