我对GLSL很新,请原谅这些问题的基本性质。
首先,致电:
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
对于我的设备,这会返回precision = 23
和range = {127, 127}
。在我进一步讨论之前,我对此的理解是,这是一个32位浮点数(1个符号+ 8个exp + 23个尾数) - 这是正确的吗?
其次,我的目标是使用this method在片段着色器中模拟双浮点精度。我使用以下代码在CPU端将一个double分成两个浮点数:
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
溢出项float e=b-(s-a);
总是在GPU上评估为0(我通过设置基于值的颜色进行调试),无论我传入u_h0
和u_h1
(我也是确认这两者都不为零。
似乎编译器可能会将e
解释为b - ((a + b) - a) == (b - b) == 0
,即在编译时优化代码。
这看起来是否可能,如果是这样,我怎么能阻止这种情况发生?
感谢您的帮助。
答案 0 :(得分:0)
更改:
varying vec2 v_texCoords;
要:
invariant varying vec2 v_texCoords;
在顶点和片段着色器中都可以解决问题。