2010-12-17 10 views
1

私は簡単なWebGLプログラムを書いています。私は、シェーダプログラムで奇妙な行動とこだわっている:WebGLフラグメントシェーダの奇妙な浮動小数点演算子

条件(1.01 * 2.0 > 1.0)はtrueと評価されたが 条件(0.99 * 2.0 > 1.0)

に私は、私は数が少なく入手何か他のものによって1.0よりも少ない数を掛けるたびにflaseと評価します1.0

なぜですか?

[EDIT]

Iは、画面上のウィンドウレベルやウィンドウハイト(線形ランプ)とディスプレイを使用して8ビットのビットマップを16ビット符号なし整数データを変更するフラグメントシェーダを使用しています。 WebGL(AFAIK)に内部フォーマットとして16bitデータを格納する直接的な方法がないので、Uint8Array(width*height*3)を作成し、Rチャンネルに1バイト、Bチャンネルに2バイトを格納し、gl.RGBgl.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の場合、答えはfalseです。私は、リサンプリングされた16ビット画像に奇妙なアーティファクトがあるとき、何かを疑い始めました。

私はChrome 8とFirefox 4でテストしました。私は浮動小数点算術について何か分かりません。

+0

あなたのお手伝いをするにはより多くの文脈が必要です。たとえば、比較結果をどのようにテストしていますか?シェーダ内の条件は、通常のコードよりも悪名高いものです。テストしているコードを正確に教えていただき、適切に対応できるようお勧めします。 –

+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

答えて

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); 

どのように多くのナインバグをトリガするために追加する必要がありますか?まだ0.9で起こっていますか?

これを実行したら、そのコードを使用してChromeまたはFirefox(同じGLSLパーサーを使用する)のバグを報告します。有効桁数が多すぎる定数の解析にバグがある可能性があります。

関連する問題