2010-12-17 90 views
1

我在寫一個簡單的WebGL程序。我被困在着色器程序一個奇怪的行爲:在WebGL片段着色器中奇怪的浮點運算

條件(1.01 * 2.0 > 1.0)計算結果爲真實的,但 條件(0.99 * 2.0 > 1.0)計算結果爲FLASE

每當我被什麼東西乘以數量較少比1.0否則我得到了一些較小的比1.0

爲什麼這樣呢?

[編輯]

我使用片段着色器使用窗高和窗HIGHT(線性斜坡)和顯示在屏幕上,以16位無符號的整數數據更改爲8位位圖。 既然在WebGL(AFAIK)中沒有直接存儲16bit數據的內部格式,我決定創建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上測試過它。我相信我不瞭解浮點運算。

+0

很可能我們需要更多的上下文來幫助您。例如,你如何測試你的比較結果?着色器中的條件比普通代碼更挑剔。我建議您向我們提供您正在測試的確切代碼,以便我們能夠爲您提供適當的幫助。 – 2010-12-17 23:34:36

+0

你在哪個平臺上運行?這可能與GL/GL ES着色器編譯器中的錯誤有關。如果您有更簡單的着色器,問題是否會持續存在,例如'if(1.0 * 2.0> 1。1)gl_FragData [0] = vec4(1.0.0.1); else gl_FragData [0] = vec4(0,1,0,1);' ? – rotoglup 2010-12-21 19:41:45

回答

2

也許它不使用浮動。

試試這個:

float xa = 1.01; //then change to 0.99 
float xb = 1.0; 
float xc = 2.0; 
if (xa * xb > xc) 
    ... 

這是否幫助?如果是這樣,也許編譯器(或硬件)由於某種原因將它們轉換爲int。

1

您應該將着色器剝離到最小的情況。

if(1.0*2.0 > 1.1) gl_FragData[0] = vec4(1,0,0,1); 
else gl_FragData[0] = vec4(1,0,1,1); 

if(0.999999*2.0 > 1.1) gl_FragData[0] = vec4(1,0,0,1); 
else gl_FragData[0] = vec4(1,0,1,1); 

多少787-9你需要添加觸發錯誤?它仍然發生在0.9?

一旦你完成了,使用該代碼來報告Chrome或Firefox(他們使用相同的GLSL分析器)的錯誤。解析具有太多有效數字的常量是完全可能的。