iOS 上的 OpenGL ES 2.0 片段着色器算法不正确
OpenGL ES 2.0 fragment shader arithmetic incorrect on iOS
我是 GLSL 的新手,所以请原谅这些问题的基本性质..
首先,请致电:
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
对于我的设备,此 returns precision = 23
和 range = {127, 127}
。在我进一步讨论之前,我对此的理解是这是一个 32 位浮点数(1 符号 + 8 exp + 23 尾数)- 这是正确的吗?
其次,我的目标是使用 this method 在片段着色器中模拟双浮点精度。我使用以下代码在 CPU 侧将 double 拆分为 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;
}
然后我使用返回的 hi/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_h0
和 u_h1
传入什么,溢出项 float e=b-(s-a);
在 GPU 上的计算结果始终为 0(我通过根据值设置颜色进行调试)(我还确认这两个都是非零的)。
似乎编译器可能将 e
解释为 b - ((a + b) - a) == (b - b) == 0
,即在编译时优化代码。
这看起来有可能吗?如果有,我该如何阻止这种情况发生?
感谢您的帮助。
变化中:
varying vec2 v_texCoords;
收件人:
invariant varying vec2 v_texCoords;
在顶点和片段着色器中修复了这个问题。
我是 GLSL 的新手,所以请原谅这些问题的基本性质..
首先,请致电:
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
对于我的设备,此 returns precision = 23
和 range = {127, 127}
。在我进一步讨论之前,我对此的理解是这是一个 32 位浮点数(1 符号 + 8 exp + 23 尾数)- 这是正确的吗?
其次,我的目标是使用 this method 在片段着色器中模拟双浮点精度。我使用以下代码在 CPU 侧将 double 拆分为 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;
}
然后我使用返回的 hi/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_h0
和 u_h1
传入什么,溢出项 float e=b-(s-a);
在 GPU 上的计算结果始终为 0(我通过根据值设置颜色进行调试)(我还确认这两个都是非零的)。
似乎编译器可能将 e
解释为 b - ((a + b) - a) == (b - b) == 0
,即在编译时优化代码。
这看起来有可能吗?如果有,我该如何阻止这种情况发生?
感谢您的帮助。
变化中:
varying vec2 v_texCoords;
收件人:
invariant varying vec2 v_texCoords;
在顶点和片段着色器中修复了这个问题。