0

これは私のフラグメントシェーダーです:

#version 120
uniform sampler2D sampler0;
uniform bool isf1;

vec4 f1(vec4 color) {
...
}
vec4 f2(vec4 color) {
...
}

void main()
{
    gl_FragColor = texture2D( sampler2, gl_TexCoord[0].xy);
    gl_FragColor = f1(gl_FragColor);
    if(isf1) gl_FragColor = f2(gl_FragColor); //How to avoid it?
}

テクスチャの解像度は 1920x1080 なので、「if」は 2073600 回呼び出しますが、これは非常に非効率的です。すべてのテクセルに対して 'if' を 1 回だけ起動する方法は?

4

5 に答える 5

1

他の人が言ったように、シェーダーで を回避する唯一の方法は、if異なるバージョンのプログラムを用意することです。

コメントで、呼び出す必要がある関数が実際には 6 つあると述べています (おそらく、その情報を質問に追加できます)。ifs をsに置き換えて#ifdef、プログラムの (64?) バージョンを自動的に生成できます (コードの先頭に適切な#defines を追加することにより)。

これの欠点は、さまざまな条件でさまざまなオブジェクトを多数描画している場合、描画ごとにシェーダー プログラムを切り替える必要があり、シェーダーのブランチよりもコストがかかる可能性があることです。

注意すべきことの 1 つは、隣接するフラグメントが同じパスをたどる場合、(最近の gpu では) ブランチはそれほど高価ではないということです。あなたの場合、すべてのフラグメントは同じパスをたどるので、ブランチは可能な限り安価です。

于 2013-06-20T09:19:35.150 に答える
0

少し遅いかもしれませんが、こちらsubroutineのLighthouse3d によるチュートリアルをご覧になることをお勧めします。

さらに、より基本的なブランチについては、 および を使用して最適化することもできclampますmixこのチュートリアルでは、非常に良い例を示します。

于 2014-07-18T20:29:23.487 に答える
0

渡した外部変数、つまり boolean に基づいてコードの一部を実行していますf1。代わりにサブルーチンを使用する必要があります。レンダリングする前に基づいて OpenGL プログラムでサブルーチンを設定し、isf1「f1」であるすべてのものをレンダリングします。f1 ではないものについて繰り返します。これにより、すべてのフラグメントでクロック サイクルを浪費する代わりに、シェーダーの外部で適切な機能が1 回選択されます。

于 2013-06-19T20:52:44.137 に答える