Я пишу простую программу WebGL. Я застрял со странным поведением в шейдерной программе:
условие ( 1.01 * 2.0 > 1.0 )
оценивается как истинное, но
состояние ( 0.99 * 2.0 > 1.0 )
оценивается как вспышка
Каждый раз, когда я умножаю число меньше 1.0
на что-то другое, я получаю число меньше 1.0
Почему это так?
[EDIT]
Я использую фрагментный шейдер для изменения 16-битных целочисленных данных без знака на 8-битное растровое изображение, используя уровень окна и высоту окна (линейное изменение) и отображение на экране.
Поскольку в WebGL нет прямого способа хранения 16-битных данных как внутреннего формата, я решил создать Uint8Array(width*height*3)
, сохранить первый байт в канале R, второй в канале B и поместить его в текстуру gl.RGB
, gl.UNSIGNED_BYTE
(может быть, LUMINESCANCE_ALPHA
будет лучше).
В шейдере я восстанавливаю байты словоформы и делаю выравнивание.
Программа шейдера:
#ifdef GL_ES
precision highp float;
#endif
uniform highp sampler2D s_texture;
uniform highp float u_ww;
uniform highp float u_wc;
varying highp vec2 v_texcoord;
void main(void)
{
highp vec3 color = texture2D(s_texture, v_texcoord).rgb;
highp float S = 255.;
highp float d = 65280.;
highp float m = 0.9;
highp float c = color.g*d + color.r*S;
float dp = 0.;
float min = u_wc - u_ww/2.;
float max = u_wc + u_ww/2.;
if( 1.0*2.0 > 1.1 ) gl_FragData[0] = vec4(1,0,0,1);
else{
if( c<min ) c=0.;
else if( c>max ) c=255.;
else c=(255.*(max-c))/u_ww;
c = c/S;
gl_FragData[0] = vec4(c,c,c,1);
}
}
Как видите, тупая строка if( 1.0*2.0 > 1.1 ) gl_FragData[0] = vec4(1,0,0,1);
Это место, где я тестирую арифметику с плавающей запятой. В этом примере все изображение красного цвета, но при условии 0.999999999*2.0 > 1.1
ответ ложный. Я начал что-то подозревать, когда на 16-битном изображении с измененной частотой появились странные артефакты.
Я тестировал его на Chrome 8 и Firefox 4. Я полагаю, что я ничего не понимаю в арифметике с плавающей запятой.