Android 在桌面GPU和移动GPU上打开GL不同的结果

Android 在桌面GPU和移动GPU上打开GL不同的结果,android,opengl,graphics,opengl-es,textures,Android,Opengl,Graphics,Opengl Es,Textures,我一直在尝试将着色器移植到移动设备。我是在安卓设备上,在OpenGL ES 2.0中做这件事的。以下是来自上述站点的片段着色器代码,以供参考: void main(void) { // clamp pixel posiiton in [-1,1] vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy; vec2 uv; // calculate angle of current pixel from origin // atan retu

我一直在尝试将着色器移植到移动设备。我是在安卓设备上,在OpenGL ES 2.0中做这件事的。以下是来自上述站点的片段着色器代码,以供参考:

void main(void)
{
// clamp pixel posiiton in [-1,1]
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
vec2 uv;

// calculate angle of current pixel from origin
// atan return values are in [-pi, pi]
float a = atan(p.y,p.x);

// distance of point from origin
//float r = sqrt(dot(p,p));

float power = 7.0;

// http://en.wikipedia.org/wiki/Minkowski_distance
float r = pow( pow(p.x*p.x,power) + pow(p.y*p.y,power), 1.0/(2.0*power) );

// add global time for a moving tunnel
uv.x = .2/r + iGlobalTime/2.0;
uv.y = a/(3.1416);

// multiplication by r to give a darkened effect  in center
vec3 col = texture2D(iChannel0, uv).xyz * (1.0-r);
//vec3 col = vec3(uv.y, 0.0,0.0);


gl_FragColor = vec4(col,1.0);
}
我在我的手机上得到以下结果(Moto G,三星Galaxy S Advance)。请注意,纹理是如何平坦的,并且有点夹在中间

在emulator(Nexus5API21)(带有模拟主机gpu选项)上运行相同代码时 这是预期的输出


我的纹理环绕模式设置为
GL\u REPEAT
。可能有什么问题?

这是一个精度问题
mediump
,这是ES 2.0着色器中保证支持的最高精度,其浮点幅值范围为[2^-14,2^14],如规范第33页的表格所示(“OpenGL ES着色语言”,版本1.00,可在中找到)

以下语句序列将快速产生下溢:

float power = 7.0;
float r = pow( pow(p.x*p.x,power) + pow(p.y*p.y,power), 1.0/(2.0*power) );
看看这个子表达式:

pow(p.x*p.x,power)
根据着色器开始时的计算/注释,
p.x
的范围为[-1,1]。使用0.1作为值:

pow(0.1 * 0.1, 7.0) = pow(0.01, 7.0) = 10^-14
这正好在
中等
值下溢的限制附近。因此,当
p.x
p.y
接近范围[-0.1,0.1]时,这些子表达式将下溢到零

最好的解决办法是什么并不明显。尝试的一些想法:

  • 如果您的设备支持,请使用
    highp
    precision<编码>高精度
支持在ES 2.0中是可选的,并且仅在定义了
GL\u FRAGMENT\u PRECISION\u HIGH
时才可用
  • 尝试使用低于7.0的指数,看看视觉效果是否仍然满足您的要求
  • 对可能下溢的像素使用某种形式的钳制。你可以丢弃它们,或者把它们涂成黑色。虽然它不会使墙居中,但至少可以避免丑陋的人工制品

  • 老实说,mipmapping似乎存在问题。你的纹理缩小过滤器是什么?@AndonM.Coleman它的
    线性
    缩小和放大。我尝试了最近的
    ,它给出了相同的结果
    GL\u LINEAR\u MIPMAP\u LINEAR
    给出了黑色屏幕划痕。但您提到了这是一个片段着色器,我没有看到浮点类型的精度限定符
    lowp
    在这里是不够的,并且在ES 2.0中不能保证
    highp
    ,因此
    mediump
    是您的最佳选择。@AndonM.Coleman float precision已经设置为
    mediump
    。这看起来很像是一个精度问题。您是否尝试了
    highp
    ?我知道它是可选的,但您正在测试的系统可能支持它。在emulator中,它也被指定为
    mediump
    ,那么它为什么在那里工作呢?此外,使用较低的指数也没有帮助:(指定的精度只是一个最小值。模拟器可能会对所有内容使用32位精度。如果将
    power
    设置为例如4.0,则不会发生任何变化?这很令人惊讶。好吧!确实是精度问题。我将精度更改为
    highp
    ,并且它工作正常,但我不确定即使在精度较低的情况下,桌面上会发生什么指定降低功率会降低中间的人工制品的尺寸!