GLSL ES中的dFdx / dFdy类比问题

5
我正在编写跨平台应用程序,它应该在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设备都支持它吗?

亚马逊Fire TV Stick Gen1不支持GL_OES_standard_derivatives扩展。 - mchiasson
1个回答

6

正如我之前所说,许多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

附言:我得到的结果与glsl内置函数非常接近,但我的着色器略微模糊。为了解决这个问题,我在1/1.75上添加了乘以像素步长的操作。如果有人知道原因,请告诉我。


我也需要类似的东西,具体来说是fwidth()的替代品。 你能澄清一下你的替代品吗? 特别是“dx”和“dy”变量从哪里来。 另外,我使用的现有着色器只使用了一个参数的fwidth函数:float dist = texture2D(u_texture, vTexCoord).a; float width = fwidth(dist);我不确定这与你的变量.fwidth有什么关系。谢谢。 - darkflame
在我的情况下,有一些已知大小的四边形(它是屏幕空间大小,在我特定的情况下)。导数是函数增长(换句话说,当前f(x1)和下一个f(x2)之间的差异)。我们有x1(这是来自顶点着色器的值),x2=x1+1/width。然后我计算当前像素值(x1)处的myFunc值,然后计算下一个(x2)处的myFunc。然后得到差异。 - tower120
太棒了!我将它与Loop和Blinn的有符号距离着色器一起使用,只需要用一个带有未微分轴设置为零的vec2来包装您的导数。非常感谢! - Mapsy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接