2013-11-26 16 views
9

私はシャドウマッピングを実装しているWebGLプログラムで作業しています。各フラグメントの深さ値を計算した後、最後にフラグメントが影にあるかどうかに基づいて照明を計算するif文があります。 depthは、シャドウマップの深さで、light_tex_coordlight1のシーン空間のフラグメントの位置であるWebGLフラグメントシェーダがif文で正しく分岐しない

gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1); 
if (light_tex_coord.z - depth <= 0.0) { 
    gl_FragColor += vec4 
     (calcLighting(light1, eye_dir, eye_dir_norm, normal) 
     , 0.0 
    ); 
} 

Shadows not being correctly computed, branch never taken

light1はモデルの周りを回転する点光源、light0はカメラに静的に配置された点光源です。

ここで問題となるのは、ifブランチが決して撮影されないため、シーンにはlight0しか適用されないということです。 depthlight_tex_coord、およびcalculateLightingが正しく動作することを確認しました。正しく、赤、緑で描画される影なしで描画される領域を陰に

if (light_tex_coord.z - depth <= 0.0) { 
    gl_FragColor = vec4(0,1,0,1); 
} else { 
    gl_FragColor = vec4(1,0,0,1); 
} 

Shadowed fragments correctly computed and drawn as red and green

原因:ここでは

は、次のコードで上記の交換、しかし、奇妙なことです。つまり、ブランチは正しく評価されます。これでそれを置き換える:

gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1); 
gl_FragColor += vec4 
    (calcLighting(light1, eye_dir, eye_dir_norm, normal) 
    , 0.0 
    ); 

Lighting computed without shadows

は照明が正常に(ただし、サンセリフの影)を計算するようにします。 if文でより高価なcalcLighting関数を呼び出すと、それを取ることが気にならないようです。

さらに、私はclamp関数を使用することを含むいくつかの方法で照明を適用しようとしました。常に追加を行い、第2のcalcLighting呼び出しを1または0で乗算するための象限演算子を使用し、if文をさまざまな方法で配置します。何も動作していないようです。

webglでの分岐がどのように機能しているのか分かりませんか?

+0

別の 'vec4'変数に色を累積しようとしましたか?**これだけ他の変数の値を' gl_FragColor'に割り当てます**。シェーダの 'gl_FragColor'への複数回の書き込みは、その値を読み込む(これは' + = 'を実装するために必要です)サポートされているはずですが、すべてのアカウントでこの問題がこれらのアクションの1つまたは両方に関連しているようですあなたのコントロールフローを与えます。 –

+0

私は、上記のスニペットの 'gl_FragColor'のすべてのインスタンスをアキュムレータ' vec4 acc; 'で置き換えようとしました。私は 'gl_FragColor = acc;'でシェーダの最後にのみ割り当てました。上記のいずれの場合にも変更はありません。 – Cookyt

+0

fsコード全体を提供できますか? また、コードを 'gl_FragColor + = vec4(calcLight(..)、1.0)'に変更しても何か違いはありますか? [note 1.0 alpha value] –

答えて

0

WebGlコンテキストでは深さがサポートされていない可能性があります。それを使用する式は無視されます。

あなたは(getContextAttributesでこれを確認することができます)の代わりに支店の

+0

私のjavascriptコードでは、深さの拡張子をチェックし、存在しなければ、深度の値をカラーバッファに書き込みます。いずれにしても、私がこれをテストしたブラウザは深度拡張をサポートしています。 – Cookyt

0

、あなたはこのような本当に過激なものと考えている:それはちょうどそれは、世界で最も美しいソリューションではありません

gl_FragColor += vec4 (
    calcLighting(light1, eye_dir, eye_dir_norm, normal) 
    , 0.0 
    ) * abs (min (sign (light_tex_coord.z - depth), 0.0)); 

を、しかし、あなたが探しているもののラインに沿って何かを得るかもしれません。それは基本的にあなたのlight_tex_coord.z - depth <= 0.0条件式を取り、あなたはどちらか廃棄分岐結果を維持することにより、照明を掛けることができます素敵な浮動小数点0.0または1.0にそれを作ります。シェイダーの種類動的フロー制御が導入される前に動作するようにしました。

+0

きちんとしたアイデアですが、残念ながらそれを使用しても効果がないようです。 – Cookyt

0

話題だここに私の2セント2歳ですが:

は、私は同様の問題を抱えていたし、次の文を含む議論をインターネット上のページを発見:

[... ](条件付き ブロック内に画像を書き込むような狂気のことをしない限り)。 [...]

は、だから、私は修正文「場合」のみCOLで、)(メインに

vec4 col; 

ローカル一時変数でのピクセルの色を入れてみました、と私は設定します最後のピクセルの色:

gl_FragColor = col; 

これは私の問題を解決しました。もちろん、すべての状況でその最後の行にフローが到達するようにするためには、面倒な追加プログラミングが必要な場合があります。

関連する問題