歴史的に言えば、GPU は などのフラグメントごとの命令をサポートしてMIN
おりMAX
、任意の条件付き分岐をサポートするよりもはるかに長い間サポートされてきました。デスクトップ OpenGL でのこの例の 1 つは、GL_ARB_fragment_program
拡張機能 (現在は GLSL に取って代わられている) であり、分岐をサポートしないことを明示的に示していますが、その他の条件付き命令と同様に命令も提供していMIN
ますMAX
。
min()
がどれほど一般的でmax()
ありclamp()
、シェーダーにあるかを考えると、すべての GPU にこれらの操作専用のハードウェアがまだあると確信しています。これは仕様で保証されているわけではありません。実装によってコードを最適化できるためです。ただし、現実の世界では、独自の関数をロールバックするのではなく、GLSL の組み込み関数を使用する必要があります。
唯一の例外は、大量の追加フラグメント処理を避けるために条件が使用されていた場合です。ある時点で、ブランチのコストはブランチ内のすべてのコードを実行するコストよりも少なくなりますが、ここでのバランスはハードウェアに大きく依存するため、ベンチマークを実行して、アプリケーションで実際に役立つかどうかを確認する必要があります。ターゲット ハードウェア。これが私が意味する種類のものです:
void main() {
vec3 N = ...;
vec3 L = ...;
float NDotL = dot(N, L);
if (NDotL > 0.0)
{
// Lots of very intensive code for an awesome shadowing algorithm that we
// want to avoid wasting time on if the fragment is facing away from the light
}
}
0-1 にクランプNDotL
し、すべてのフラグメントのシャドウ コードを常に処理して、最終的なシャドウ項を乗算するだけでNDotL
は、元が <= 0 の場合、多くの無駄な労力がかかりNDotL
ます。理論的には、ブランチを使用してこのオーバーヘッドを回避できます。この種のことが必ずしもパフォーマンスの向上につながるとは限らない理由は、ハードウェアがシェーダー分岐を実装する方法に大きく依存するためです。