【问题标题】:OpenGL ES 2.0 fragment shader arithmetic incorrect on iOSOpenGL ES 2.0 片段着色器算法在 iOS 上不正确
【发布时间】:2023-12-24 05:31:01
【问题描述】:

我对 GLSL 很陌生,所以请原谅这些问题的基本性质..

首先,调用:

int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);

对于我的设备,这将返回 precision = 23range = {127, 127}。在我进一步讨论之前,我对此的理解是,这是一个 32 位浮点数(1 个符号 + 8 个 exp + 23 个尾数)- 这是正确的吗?

其次,我的目标是使用this method 在片段着色器中模拟双浮点精度。我使用以下代码在 CPU 端将一个双精度浮点数拆分为 2 个浮点数:

static double const SPLITTER = (1 << 29) + 1;

static inline void set2d(double a, float* b, float* c) {
    double t = a * SPLITTER;
    double hi = t - (t - a);
    double lo = a - hi;
    *b = (float)hi;
    *c = (float)lo;
}

然后我在片段着色器中使用返回的高/低值设置 2 个制服。制服是这样声明的:

precision highp float;
uniform float u_h0, u_h1;

我遇到的问题是在以下代码中:

float a = u_h0;
float b = u_h1;
float s=a+b;
float e=b-(s-a);  // always 0

无论我为u_h0u_h1 传入什么内容,GPU 上的溢出项float e=b-(s-a); 总是计算为0(我通过根据值设置颜色进行调试)(我还确认这两个都不是-零)。

似乎编译器可能将e 解释为b - ((a + b) - a) == (b - b) == 0,即在编译时优化代码。

这看起来有可能吗?如果有,我该如何阻止这种情况发生?

感谢您的帮助。

【问题讨论】:

    标签: ios opengl-es glsl opengl-es-2.0 fragment-shader


    【解决方案1】:

    变化:

    varying vec2 v_texCoords;
    

    收件人:

    invariant varying vec2 v_texCoords;
    

    在顶点和片段着色器中都解决了这个问题。

    【讨论】: