2016-08-09 4 views
1

iOSアプリケーションのフラグメントシェーダで基本的な最適化を行っています。私はgl_FragColorにいくつかの色の1つを割り当てたいと思います。私の最初の試みは三元演算子を使用しました。これは、シミュレータやiPhone 5Cの両方に正しく物事を表示します。iOSでのフラグメントシェーダの動作

lowp float maxC = max(color.r, max(color.g, color.b); 
lowp float minC = min(color.r, min(color.g, color.b); 
gl_FragColor.rgb = (maxC > 1.0 ? result0 : (minC < 0.0 ? result1 : result2)); 

私はあまり分岐して、論理上で複製することができますかどうかを確認するためにmixstepの組み合わせで三項演算子を置き換えることを試みました。残念ながら、このシミュレータではなく、iOSデバイス上で動作します:

lowp float step0 = step(0.0, minC); 
    lowp float step1 = step(1.001, maxC); 
    lowp vec3 mix0 = mix(result1, result2, step0); 
    gl_FragColor.rgb = mix(mix0, result0, step1); 

具体的には、シミュレータで正しく描画画面の一部白い領域は、デバイス上の黒い領域として誤って描かれています。他のすべてはうまく見えます。

上記のstepmixの組み合わせが、3値演算子を使用するアプローチと同じ結果を再現しない理由は何ですか?

答えて

2

OpenGLシェーダでの浮動小数点演算の詳細はわかりにくい場合があります。可能性のあることは、三元演算子がGLSLコンパイラによってゼロ演算に最適化されていることです。どのように折り畳み条件を乗算やその他の単純な演算に変換するかについては、avoiding-shader-conditionalsをご覧ください。最も有用な効用関数は、次のとおり

float when_eq(float x, float y) { 
    return 1.0 - abs(sign(x - y)); 
} 

使用の一例であろう。

float comp = 0.0; 
comp += when_eq(vTest, 0.0) * v1; 
comp += when_eq(vTest, 1.0) * v2; 

上記のコードはVTESTの電流値に応じてV1またはV2のいずれかにCOMPを設定します。この明示的な実装と、コンパイラによって生成された3進数のインプリメンテーションをテストして、どれが高速かを確認してください。

関連する問題