質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

1回答

1856閲覧

GLSL 平行光源の光の当たり方がおかしいのか?正しいのか知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

0クリップ

投稿2020/11/21 11:43

編集2020/11/24 11:06

提示画像ですが平行光源を使ったフォングの反射モデルですが黒い部分は光当たっていない面の色だと思うのですがこれはシェーダーが間違えているためのバグなのでしょうか?平行光源の向きを画面に表示させるには難易度が高すぎて出来ないの質問でしました。

イメージ説明

CPP

1/***************************************************************************************************************** 2* ライティング  .vert 3******************************************************************************************************************/ 4 5#version 400 6 7//************ layout 8layout(location = 0) in vec3 in_Position; //頂点座標 9layout(location = 1) in vec2 in_TexCoord; //テクスチャ座標 10layout(location = 2) in vec3 in_Normal; //法線 11 12//************ uniform 13uniform mat4 worldMatrix; //ワールド行列 14uniform mat4 viewMatrix; //ビュー行列 15 16//************ フラグメントの送る 17out vec2 fragTexCoord; //UV 18out vec3 fragNormal; //法線 19out vec3 fragWorldPos; //ワールド空間(位置) 20 21/////////////////////////////////////////////////////// 22void main() 23{ 24 //同次元座標に変換してワールド座標に変換 25 vec4 pos = vec4(in_Position, 1.0); 26 pos = worldMatrix * pos; 27 fragWorldPos = pos.xyz; 28 29 30 vec4 p = vec4(in_Position, 1.0); 31 gl_Position = viewMatrix * pos; 32 33 //fragNormal = (vec4(inNormal, 0.0f) * worldMatrix).xyz; 34 fragNormal = in_Normal; 35 36 fragTexCoord = in_TexCoord; 37} 38/////////////////////////////////////////////////////// 39

CPP

1/***************************************************************************************************************** 2* ライティング  .frag 3******************************************************************************************************************/ 4#version 400 5 6//並行光源用の構造体 7struct DirectionalLight 8{ 9 vec3 mDirection; //光の方向 10 vec3 mDiffuseColor; //拡散反射色 11 vec3 mSpecColor; //鏡面反射色 12}; 13 14//************ .vertexから来た 15in vec2 fragTexCoord; //UV 16in vec3 fragNormal; //法線 17in vec3 fragWorldPos; //ワールド空間(位置) 18 19//************ uniform 20uniform sampler2D uTexture; //テクスチャ画像 21 22uniform vec3 CameraPos; //カメラ位置 23uniform vec3 AmbientLight; //環境光の強さ 24uniform float SpecPower; //表面の鏡反射指数 25 26uniform DirectionalLight DirLight; //平行光源 27 28//************ 画面に出力 29out vec4 out_color; //色 30 31/////////////////////////////////////////////////////// 32void main() 33{ 34 //表面法線 N 35 //vec3 N = normalize(fragNormal); 36 vec3 N = fragNormal; 37 38 //表面から光源へのベクトル L 39 vec3 L = normalize(-DirLight.mDirection); 40 41 //表面からカメラへのベクトル V 42 vec3 V = normalize(CameraPos - fragWorldPos); 43 44 //Nに関する -L の反射 R 45 vec3 R = normalize(reflect(-L, N)); 46 47 //フォンの反射を計算する 48 vec3 Phong = AmbientLight; 49 float NdotL = dot(N, L); 50 if (NdotL >= 0) 51 { 52 vec3 Diffuse = DirLight.mDiffuseColor * NdotL; 53 vec3 Specular = DirLight.mSpecColor * pow(max(0.0, dot(R, V)), SpecPower); 54 Phong += Diffuse + Specular; 55 } 56 57 //最終的な色はテクスチャの色 x フォンの光(alpha = 1) 58 59 out_color = texture(uTexture, fragTexCoord) * vec4(Phong, 1.0); 60 61// out_color = texture(uTexture, fragTexCoord); 62 63} 64/////////////////////////////////////////////////////// 65

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

バーテックスシェーダ側のコードをぱっと見した感じ,
法線に何の演算もされていないのがおかしいように思います.

法線のデータはモデルのローカルな座標系で与えられているのだと思うので,
pos = worldMatrix * pos;
なる変換によってオブジェクトが回転しているのだとすれば,法線も相応に回転させないとダメでしょう.

※念のため記しておくが,「単に法線にもworldMatrixを乗じればよい」という話ではない:法線とは「向き」であるから,法線を平行移動とかスケーリングするのは間違っているから.回転だけを適用する.

投稿2020/11/24 11:23

編集2020/11/24 11:24
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/11/24 11:56 編集

法線も回転とは法線を毎フレーム再算出ということでしょうか? .vertexを  fragNormal = ( worldMatrix * vec4(in_Normal, 0.0f)).xyz; このようにしてみましたがわかりませんw
fana

2020/11/24 11:54

法線自体は(頂点の座標とかと同様に)固定データ.バーテックスシェーダの中で頂点座標と同様に回転を適用する
退会済みユーザー

退会済みユーザー

2020/11/24 12:02

glm::mat4 worldMatrix = getMove() * getScale() * getRotate(); のgetRorate();ということでしょうか?つまり uniformで持っていくのでしょうか?
fana

2020/11/24 12:08

とりあえず回転マトリクスをuniformにして持っててみれば良いかと.
退会済みユーザー

退会済みユーザー

2020/11/24 12:34 編集

//fragNormal = ( RotateMatrix * vec4(in_Normal, 0.0f)).xyz; fragNormal = ( vec4(in_Normal, 0.0f) * RotateMatrix ).xyz; 両方試しましたがうまく動作しません提示画像ようなおかしな?感じになってしまうのですがこれはなぜでしょうか?
fana

2020/11/25 03:03

(1) その絵での,色がある場所と真っ黒な場所の境界 に何か心当たりはありませんか? 例えば,立方体の1個の面をたくさんの三角形で構成していてポリゴンの境界である,とか. (2) 提示の絵では3面が見えてますが,全てが同じ明るさ?であるように見えるのも謎です. まずはテクスチャみたいな余計な要素を省いて確認すべきではないでしょうか. シェーディングも,最初はdiffuseだけにするとか. (3) > 両方試しましたが マトリクスを乗じる方向があやふやなのようであれば,復習が必要に思います. 行き当たりばったりになってしまいます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問