いくつかのバリエーションで MSAA のサポートを実装しました。
コンテキスト ベース (コンテキストを設定し、それに応じたパラメーター リストを渡すときに wglChoosePixelFormatARB を呼び出す) または FBO への MSAA レンダリングを有効にする (色と深度のレンダーバッファー アタッチメントを持つマルチサンプリング FBO と、カラー アタッチメントを持つ別の FBO を作成する) のいずれかを使用できます。解決のため)、アンチエイリアスは全体的に機能しているようです。
ただし、アンチエイリアシングを有効にすると、スペキュラー ライティングに関連すると思われるアーティファクトがいくつか見つかりました。コンテキストベースの CSAA では最悪であり、コンテキストベースの MSAA ではかなり悪いですが、FBO にレンダリングするときに MSAA を使用すると、はるかに改善されます。
私がテストに使用した航空機モデルの 1 つで、特にエンジン シリンダーといくつかの「ワイヤー」の周りで非常に目立ちます (実際には線ではなく、細いシリンダーです)。
画像でわかるように、スペキュラ ライトをオフにすると、問題はほとんどなくなりましたが、何が原因なのかはよくわかりません。
上の画像では、次のシェーダー コードを使用して鏡面反射を計算しています (すべてのライトのループ内)。
if( matShininess > 0.0 )
{
vec3 reflectionCamSpace = reflect(-lightDirectionCamSpace, faceNormal);
vec3 surfToViewerCamSpace = normalize (-vertPositionCamSpace);
float dotSpecular = max( 0.0, dot (reflectionCamSpace, surfToViewerCamSpace) );
float specularFactor = pow( dotSpecular, matShininess );
specularTerm += vec3(lgt.specular * specularFactor);
}
また、異なる照明モデルの間にはかなりの違いがあるようです:
左側はスペキュラ ハイライト用に上記のコードを使用していますが、右側はこれを使用しています (すべてのライトを反復処理するメイン ライト ループ内)。
if( matShininess > 0.0 )
{
vec3 surfToViewerCamSpace = normalize (-vertPositionCamSpace);
vec3 halfAngle = normalize(lightDirectionCamSpace + surfToViewerCamSpace);
float specularFactor = dot(faceNormal, halfAngle);
specularFactor = clamp(specularFactor, 0, 1);
specularFactor = lightDot != 0.0 ? specularFactor : 0.0;
specularFactor = pow(specularFactor, matShininess);
specularTerm += vec3(lgt.specular * specularFactor);
}
では、FBO ベースの MSAA とコンテキスト ベースの MSAA を使用する場合に、なぜそれほど大きな違いがあるのか 疑問に思っています。また、そもそも問題を引き起こすために、スペキュラー ハイライトで何が間違っていたのでしょうか?
編集:以下の投稿で要求されたように、コンテキストと FBO を介して 16xQ CSAA の結果を比較するためのテストも追加しました (FBO の場合、glRenderbufferStorageMultisample の代わりに RenderbufferStorageMultisampleCoverageNV を使用しています)。ここでも、FBO の結果の方が優れているように見えます (ただし、まだ説得力はありません)。