これは、ジオメトリシェーダーなしでOpenGLが行っていたこととまったく同じではありませんか?
いいえ、そうではありません。GSはオプションのステップであり、デフォルトのステップではありません。
OpenGLがジオメトリシェーダーを実行するには、「プリミティブアセンブリ」と呼ばれるものを実行する必要があります。を使用して一連の三角形をレンダリングするとGL_TRIANGLE_STRIP
、OpenGLは内部の処理を実行して、隣接する3つの頂点ごとに個々の三角形に変換し、ワインディングの順序を適切に変更します。
通常、GSを使用しない場合、このプロセスは1回実行されます。ただし、GSを使用する場合は、GSを実行する前に実行する必要があります。ただし、GSはまったく異なるプリミティブタイプ(クワッドなど)を出力できるため、GSの後に実行する必要もあります。
だから今、あなたはシステムに基本的に無料でたくさんの余分な仕事をさせています。結局のところ、OpenGLはGSが何もしていないと仮定することはできません(これは決定できない問題です)。
さらに、GSが存在する場合、多くの最適化が機能しなくなります。インデックス付きレンダリングを検討してください。
要素配列バッファーの各インデックスは、頂点シェーダーから同じ出力を生成します。そのため、GPUはこれらの出力をT&L後のキャッシュにキャッシュすることがよくあります。すでにキャッシュ内にあるインデックスが見つかった場合、VSは再度実行されません。キャッシュからデータを取得するだけです。
それは何ですか"?「それ」は... プリミティブアセンブリユニットです。GSを使用すると2回実行されることです。インデックスキャッシングのもの?GS の入力に対してのみ機能します。
では、GSの出力はどうなりますか?まあ、それはハードウェアに依存しています。しかし、それは何らかの種類のメモリバッファに入る必要があります。そして、そこに問題があります。そのバッファはまったくインデックス付けされていません。glDrawArraysのような状況です。
したがって、のインデックスバッファを送信すると0, 1, 2, 0, 2, 3
、T&L後のキャッシュで4つの頂点に変換されます。ただし、GS後の頂点バッファーには、6つの頂点が含まれています。ポストGSバッファはより多くのスペースを使用します。したがって、T&L後に最適化された三角形のリストまたはストリップを適切に作成する問題を経験し、パススルーGSを自分のようにひっくり返すと、基本的にその最適化によるパフォーマンスの約半分が失われます。
役に立たなかったわけではありませんが、痛いです。
これに加えて、多くのGL 3.xクラスGPU(別名:DX10)にはかなり小さなGS後のバッファーがありました。バッファが小さいほど、同時にアクティブにできるGS呼び出しが少なくなります。したがって、GSでハードウェアが効果的にボトルネックになります。テッセレーションは4.xクラスのハードウェアの大きな機能であるため、このようなハードウェアのほとんどは、GSをより重いものに使用するのに十分なバッファーを備えています。
そのため、GSを使用すると、コードの頂点処理がボトルネックになる可能性が高くなります。もちろん、頂点シェーダーとフラグメントシェーダーをより複雑にすることで、その時点での無料のパフォーマンスであるため、いつでもそれを有利に使用できます。
GSによるスローダウンの詳細については、この記事を参照してください。
ここでGSの程度親指の基本的なルールは次のとおりです。あなたはそれをレンダリングするようになりますと思うので、GSを使用することはありません速いです。あなたがしようとしていることを可能にするとき、あなたはそれを使うべきです。しようとしていることが最適化である場合は、別のものを使用します。
これの一般的な例外は次のとおりです。