3

私はWebGLバッチレンダラーに取り組んでいます(質問はOpenGLランドでも有効です)。可能な限り少ない drawArrays/drawElements 呼び出し (理想的には 1 回) で描画されるシーン内のすべてのグラフィックスとも呼ばれます。これには、属性に基づいてテクスチャを決定できるようにすることも含まれます。

したがって、私のフラグメント シェーダーでは、次の 2 つのシナリオを検討しています。

1.テクスチャ 0 を画面に描画し、属性を使用して、メモリ内のスプライト シート上でテクスチャが配置される「フレーム」を決定します。フラグメント シェーダーは次のようになります。

precision mediump float;

uniform sampler2D u_spriteSheet;

// Represents position that's framed.
varying vec4 v_texturePosition;

void main() {
    gl_FragColor = texture2D(u_spriteSheet, v_texturePosition);
}

2.シェーダーで「if」ステートメントを実行して、使用する均一な sampler2d を決定します。フラグメント シェーダーは次のようになります。

precision mediump float;

uniform sampler2D u_image1;
uniform sampler2D u_image2;
uniform sampler2D u_image3;
uniform sampler2D u_image4;
....
uniform sampler2D u_image32;

varying uint v_imageId;
// Represents texture position that's framed
varying vec4 v_texturePosition;

void main() {
    if(v_imageId == 1) {
        gl_FragColor = texture2D(u_image1, v_texturePosition);
    }
    else if (v_imageId == 2) {
        gl_FragColor = texture2D(u_image2, v_texturePosition);
    }
    ...
    else if (v_imageId == 32) {
        gl_FragColor = texture2D(u_image32, v_texturePosition);
    }
}

オプション 1 では最大テクスチャ サイズによって制限され、アプローチ 2 では使用可能なテクスチャ レジスタの数によって制限されることを理解しています。議論のために、これらの制限を超えることはないと仮定しましょう。

どちらかにかなりの時間を費やす前に、よりパフォーマンスの高いアプローチを決定しようとしています...すっごく何か考えはありますか?

4

1 に答える 1

4

通常の GPU ハードウェアではシェーダーが SIMD として実行されるため、シェーダー内のステートメントが一般的に遅い場合、つまり、多くのフラグメントが命令ごとに並列に処理されます。簡単に言えば、すべてのスレッドが then 部分を処理する if すべてのスレッドの場合、正の if 条件を持つスレッドのみが実際に実行され、他のスレッドが待機している間に結果を保存します (または計算を実行しますが、結果を保存しません)。その後、すべてのスレッドがelse部分を実行し、肯定的な条件を持つすべてのスレッドが待機します。

したがって、ソリューション#2では、多くのカードのフラグメントシェーダーは、ソリューション#1のように1つだけではなく、32の部分すべてを実行します(一部のカードでは、その部分に続くスレッドがなくなった場合、ifブランチの実行を停止すると言われていますであるため、32 未満の場合もあります)。

したがって、ソリューション#1はフラグメントシェーダーよりも高速であると予想されます。ただし、ソリューションには他のボトルネックがある可能性があるため、フラグメント シェーダーのパフォーマンスが全体的なパフォーマンスと無関係になる可能性があります。

追加の考えとして、多くの GPU では 32 未満のテクスチャしか許可されていないため、多くのデバイスとの互換性を維持したい場合は、おそらく 32 を使用できないでしょう。webglstats.com によると、99% には 16 のテクスチャ ユニットがあり、ほとんどのシーンには 16 を超えるテクスチャがあるため、ソリューション #1 のようなものを実装する方法はおそらくありません。一方、最大のテクスチャ サイズに達した場合は、#2 のようなものも必要になる場合があります。

于 2013-11-15T19:39:30.623 に答える