[解決済み] GLSLドットプロダクトの不具合
2022-02-12 12:56:42
質問
そこで、OpenGLを使って基本的なディフューズ・ライティングを実装しようとしたのです。私は法線ベクトルと光ベクトルを取り、そのベクトルの内積を使ってピクセルの明るさを計算する簡単なシェーダを書きました。以下は、私の出力です。
見ての通り、最初の2つのケースでは問題なく動作しますが、3つ目のケースでは完全に壊れています。ちなみに、[0, 0, -1] もうまくいきませんし、[0, 1, 1] は光が近づいてくるのと同じ出力になります ([0, 1, 0]).以下は私のシェーダーです。
- バーテックスシェーダ。
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightDirection;
out vec3 normal;
out vec3 lightDir;
void main()
{
normal = normalize(aNormal);
lightDir = normalize(lightDirection);
gl_Position = projection * view * model * vec4(aPos, 1.0f);
}
- フラグメントシェーダー。
#version 330 core
in vec3 normal;
in vec3 lightDir;
out vec4 FragColor;
void main()
{
float grey = max(dot(-lightDir, normal), 0.0f);
FragColor = vec4(grey, grey, grey, 1.0f);
}
問題はドット積と関係があると推測されますが、理由が見つかりません。
解決方法は?
拡散光は、以下の式で計算されます。
max(dot(-lightDir, normal), 0.0f);
. ということは、もし
dot (-lightDir, normal)
が0より小さい場合、シーンは完全に黒くなります。
は、その
ドット積
の2
単位ベクトル
は、2つのベクトルがなす角の余弦である。したがって、角度が > 90° と < 270° の場合、結果は 0 より小さくなる。
つまり、背面から光を当てた場合、真っ黒に見えるということです。
光の方向は、ワールド空間におけるベクトルです。
dot(-lightDir, normal)
は、法線もワールド空間のベクトルである場合にのみ意味を持ちます。
トランスフォーム
normal
をモデル空間から世界空間に変換する。
normal = inverse(transpose(mat3(model))) * normalize(aNormal);
関連
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み】'std::cout'への未定義の参照
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++