考虑以下片段着色器。 当我在模拟器或 iPhone 5 (8.3) 上运行它时,它会显示预期的颜色(红色)。 如果我在 iPhone 6 Plus (8.2) 上运行它,它会转到第二个 if 子句(绿色),这显然是错误的,因为计算的正确结果应该在 1.22 左右。 如果我直接提供 atan 参数作为编译时间常数,则计算有效。

我已经尝试过最新的 Xcode 6.2 和最新的 6.3 Beta。

void main()
{
    highp float y = 0.57;
    highp float x = 0.21;

    highp float a = atan(y, x); 
    // works if changed to atan(0.57, 0.21);
    // does not work if changed to atan(y / x);

    if (a > 1.2 && a < 1.25)
    {
        // Should always come here
        // Works on Simulator, iPhone 5
        gl_FragColor = vec4(1, 0, 0, 1);
    }
    else if (a > 1.5 && a < 1.55)
    {
        // Comes here on iPhone 6 Plus
        gl_FragColor = vec4(0, 1, 0, 1);
    }

    return;
}

更新:情节变厚。

如果我按以下方式更改着色器,错误就会消失并且 atan 返回正确的值。 似乎我对 x 和 y 的任何内容都必须是编译时常量以外的东西。 这也解决了我的生产代码中根本没有编译时常量的问题。 顺便说一句,同样的问题也会影响 acos 和 asin。

highp float y = texCoord.x;
highp float x = texCoord.x;

if (x == x) // Removing this line makes error return
{
    x = 0.21;
}

if (y == y) // Removing this line makes error return
{
    y = 0.57;
}

另一个例子。 这就是我实际使用它的方式。

如果我这样计算,它会在 iPhone 6 上失败:

float y = sin(lon2 - lon1) * cos(lat2);
float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1);

float bearing = atan(y, x) + 2.0 * pi;

return mod(bearing, 2.0 * pi);

如果我这样做,它会起作用:

float y = texCoord.y;
float x = texCoord.x;

if (y == y)
{
    y = sin(lon2 - lon1) * cos(lat2);
}

if (x == x)
{
    x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1);
}

float bearing = atan(y, x) + 2.0 * pi;

return mod(bearing, 2.0 * pi);

#1楼 票数:1

这看起来像是编译时常量传播错误。

您的if (x == x)子句看起来可以被编译器消除,但由于它是 fp 值,因此它实际上是对NaN的测试。

即,将任何内容与 NaN 进行相等性比较总是错误的,即使您将值与自身进行比较。

看起来这个测试正在阻止编译器传播你的常量值,如果你从你的编译中要求汇编器输出,这应该是显而易见的。

#2楼 票数:0

我也在 iOS13 上用 atan 试验了一个 bug 我用这个方法来计算两点之间的角度

float getAngle(vec2 point, vec2 center) {
  float y = point.y - center.y;
  float x = point.x - center.x;
  return atan(y, x);
}

每当我用相同的点值调用这个方法时,它就会出错。

vec2 p1 = vec2(40.0, 30.0);
vec2 p2 = vec2(40.0, 30.0);
float angle = getAngle(p1, p2);

似乎调用 atan(0.0, 0.0) 错误

我能够在 iOS 上完成这项工作的方式是改变这样的方法

float getAngle(vec2 point, vec2 center) {
  float y = point.y - center.y;
  float x = point.x + 0.000000001 - center.x;
  return atan(y, x);
}

添加 0.000000001 确保两点相减不会等于 0。

  ask by Seppo translate from so

未解决问题?本站智能推荐:

2回复

GLSL代码使应用程序在iPhone 6 Plus上崩溃

我发现某些特殊的GLSL书写风格会使iPhone 6 Plus崩溃而没有任何日志。 例如,如果您在下面编写类似GLSL的代码,它将在glLinkProgram崩溃。 但是,如果将“ a”的定义移动到函数中,则它将正常工作。 在iPhone5或5s中不会发生这种情况。 您
1回复

GLSL:iPhone应用程序无法访问内置属性?

我在这里真是绝望。 我使用Xcode,试图在iPhone上实现一些OpenGL。 我必须为Phong-Lighting编写一个着色器。 我尽力声明了自己的几何形状(顶点,索引,计算等),并将各自的参数作为属性传递给着色器(用GLSL编写)。 使用这些属性可以正常工作,一些真正的基本着色器
1回复

GLSL'texture2D':在iPhone上找不到匹配的重载函数OpenGL ES2

我正在尝试使用GLSL的着色器,但是当我尝试从纹理中获取数据以尝试简单的对比度增强算法时,我得到了一个有趣的错误。 它发生在这个代码中,其中“final”是用于保存正在处理的颜色的vec4变量。 这里的想法是将像素的颜色从周围的颜色中推出(实验想法)。 我将在代码中标记出错误的行。
1回复

将GLSL着色器与iOS一起使用纹理与OpenGL ES 2

Google不存在此信息。 我需要将纹理坐标传输到我的着色器程序,但是ATTRIB_TEXCOORD不存在。 glVertexAttribPointer怎么办? 谢谢。
1回复

Cocos2d - iPhone上的月食效应

我有一个关于实现像月食这样的效果的问题。 效果应该在这个gif的前几秒看起来像。 就像一个越过圆圈的黑色阴影。 理想的情况是一个函数,我可以通过百分比传递一个参数,将这个数量作为圆圈上的阴影: 我面临的问题是我的背景是渐变。 所以不可能有一个黑色圆圈在月球上移动以获得效果。
1回复

OpenGL ES-iPhone4-片段着色器变量计数

我在片段着色器中有大量变量(着色器中有30个制服(主要是vec4),着色器中约有20个变量(vec3,float,vec4))。 它在iPhone5S上运行正常,但在iPhone4上却存在严重问题。 GPU时间是1s /帧,而98%的时间是着色器运行时间。 根据Apple API
2回复

iPhone中使用了什么版本的GLSL?

我知道iPhone使用OpenGL ES 2.0,但我不知道底层语言GLSL的版本。 是1.3,1.4,2.0还是其他?
3回复

有没有办法在iPhone上使用程序集手工编码的着色器,而不是使用GLSL?

我想使用手工编码的汇编语言顶点和片段着色器,以便在使用OpenGL ES 2.0的iPhone上对非常优化的着色器进行编程。 我在Google周围搜索,但找不到示例,即使Apple SDK允许也是如此。