glsl es аналог dFdx/dFdy

Пишу кроссплатформенное приложение. Он должен работать на устройствах Android.
Я хочу использовать dFdx/dFdy для сглаживания. Но, к сожалению, glsl es 2.0 не поддерживает производные.

Могу ли я чем-то заменить dFdx/dFdy? т.е. 1/sprite_width, 1/sprite_height в пикселях экрана.

Как я уже сказал, мне нужно, чтобы это работало на устройствах Android. И я увидел, что мое устройство поддерживает GL_OES_standard_derivatives, которые позволяют ему использовать эти функции. Все ли устройства Android opengl es 2.0 поддерживают это?


person tower120    schedule 16.03.2014    source источник
comment
Amazon Fire TV Stick Gen1 не поддерживает расширение GL_OES_standard_derivatives.   -  person mchiasson    schedule 15.04.2017


Ответы (1)


Как я уже сказал, многие устройства Opengl ES 2.0 поддерживают расширение GL_OES_standard_derivatives.
Но для тех, кто этого не делает, я придумал обходной путь:

float myFunc(vec2 p){
return p.x*p.x - p.y; // that's our function. We want derivative from it.
}


// this calculated in vertex shader
// width/height = triangle/quad width/height in px;
vec2 pixel_step = vec2(1/width, 1/height);       

float current = myFunc(texCoord);
float dfdx = myFunc(texCoord + pixel_step.x) - current;
float dfdy = myFunc(texCoord + pixel_step.y) - current;

float fwidth = abs(dx) + abs(dy);       // from khronos doc #http://www.khronos.org/registry/gles/extensions/OES/OES_standard_derivatives.txt

P.S. Я получаю очень близкие результаты к встроенным модулям glsl, немного более размытым (в моем шейдере). Чтобы исправить это, я добавил умножить pixel_step на 1/1,75. Если кто-то знает, почему, дайте мне знать.

person tower120    schedule 17.03.2014
comment
Мне также нужно что-то подобное, в частности замена fwidth(). Не могли бы вы уточнить вашу замену? В частности, откуда берутся переменные dx и dy. Также в существующем шейдере я использовал функцию fwidth с одним параметром: float dist = texture2D(u_texture, vTexCoord).a; float width = fwidth(dist); I am не уверен, как это связано с вашей переменной.fwidth. Спасибо, - person darkflame; 07.03.2015
comment
Ну, в моем случае был какой-то quad с известным размером (в моем конкретном случае это был размер экранного пространства). Производная - это функция роста (другими словами, разница между текущим f(x1) и следующим f(x2) ). У нас есть x1 (это значение исходит из вершинного шейдера), x2=x1+1/ширина. Затем я вычисляю значение myFunc при текущем значении пикселя (x1), а затем вычисляю myFunc при следующем (x2). Потом получил разницу. - person tower120; 09.03.2015
comment
Это круто! Я использовал это в сочетании с Loop и подписанным шейдером расстояния Блинна, мне просто нужно было обернуть вашу производную в vec2 с недифференцированной осью, установленной на ноль. Огромное спасибо! - person Mapsy; 08.07.2016