Я очень новый для GLSL поэтому, пожалуйста, простите основной характер этих вопросов ..OpenGL ES 2.0 пиксельный шейдер арифметическим некорректен на прошивке
Прежде всего, вызов:
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
для моих устройство возвращает precision = 23
и range = {127, 127}
. Прежде чем я пойду дальше, мое понимание этого состоит в том, что поэтому это 32-битный float (1 знак + 8 exp + 23 мантисса) - это правильно?
Во-вторых, моя цель состоит в том, чтобы эмулировать точность двойного плавания в фрагментном шейдере, используя this method. Я разделил двойной на 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 в форму фрагмента шейдер с возвращаемых значений Привет/Lo. Мундиры объявляются так:
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);
всегда принимает значение 0 на GPU (я отлажено, установив цвета на основе по значению), независимо от того, что я перехожу для u_h0
и u_h1
(я также подтвердил, что оба эти значения были ненулевыми).
Похоже, что компилятор может интерпретировать e
как b - ((a + b) - a) == (b - b) == 0
, то есть оптимизировать код во время компиляции.
Возможно ли это, и если да, то как я могу остановить это?
Спасибо за любую помощь.