🌓

バーテックスシェーダーから渡されたノーマルベクトルは正規化すべき

2022/03/16に公開

とりあえずこいつを見てくれ
Image from Gyazo

簡単なトゥーンシェーダーですが、左はハイライトがきれいに出ているのに対し、右は形がいびつになっているのがわかると思います。

どうしてこうなった。色々調べた結果を共有します。

ラスタライズ時に線形補間され中間のベクトルの長さが1ではなくなる

一般的に、ノーマルベクトルはバーテックスアトリビュートとしてバーテックスシェーダーに渡され、ラスタライザを通してピクセルシェーダーに渡されます。ラスタライザではバーテックス間のピクセルに割り当てられる値は線形補間で計算されます。

ノーマルベクトルも線形補間されますが、その際に補間された部分のノーマルベクトルの長さが1でなくなるようです。(ラスタライザでの線形補間アルゴリズムの詳細を知らないので間違っているかもしれません。詳しい方教えてくだされ)

対策:正規化する

上記問題は簡単で、ピクセルシェーダーで正規化すればOKです。

// バーテックスシェーダーから渡された法線情報を正規化する
IN.normalWS = normalize(IN.normalWS);

参考

プログラム全文は以下にあります。
テストで作ったプログラム

GitHubで編集を提案

Discussion