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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

GLSL

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

Q&A

0回答

777閲覧

OBJローダーで法線が正しく設定できない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

GLSL

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

0グッド

0クリップ

投稿2021/10/28 11:32

編集2021/10/31 03:37

提示コードですが以下のようにPhongのシェーディングを行いたいのですが提示画像のように立方体の陰影がおかしくなるのですがこれは何が原因なのでしょうか?参考サイトを参考にした記述したのですが原因がわかりません。

現状

GLSLコードはPhongシェーディングです。
Mode.cppはobjローダーです。
現状、Model.cppのLoadobj()関数でblenderで出力したobjファイルをロードしています。GLSLは提示サイトを参考に記述しました。
頂点と法線は正しく読み込まれていることを確認しました。頂点インデックスは使っていません。
立方体の面を1つの三角形に減らして実装したのでが一枚目の画像ですがライティングの陰影が出てきるのでシェーダーファイルが原因でないことを突き止めました。

知りたいこと

objローダーの法線の設定方法が知りたい。

参考サイト: https://learnopengl.com/Lighting/Basic-Lighting
Github: https://github.com/Shigurechan/GL/tree/14b9ed0e2d87eafaae0b3b11fd42660b7d3f07b7
イメージ説明

Fragment Shader
/*######################################################################### # ###########################################################################*/ #version 420 //#extension GL_ARB_explicit_uniform_location : require /*######################################################################### # ###########################################################################*/ #version 420 //#extension GL_ARB_explicit_uniform_location : require layout(location = 2) in vec3 fPosition; layout(location = 3) in vec3 fNormal; uniform vec3 lightPos; uniform vec3 lightColor; uniform vec3 objectColor; uniform vec3 viewPos; out vec4 fragment; void main() { // ambient float ambientStrength = 0.1; vec3 ambient = ambientStrength * lightColor; // diffuse vec3 norm = normalize(fNormal); vec3 lightDir = normalize(lightPos - fPosition); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = diff * lightColor; // specular float specularStrength = 0.5; vec3 viewDir = normalize(viewPos - fPosition); vec3 reflectDir = reflect(-lightDir, norm); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); vec3 specular = specularStrength * spec * lightColor; vec3 result = (ambient + diffuse + specular) * objectColor; fragment = vec4(result, 1.0); }
Vertex Shader
/*######################################################################### # ###########################################################################*/ #version 420 //#extension GL_ARB_explicit_uniform_location : require layout(location = 0) in vec3 vertexPosition; layout(location = 1) in vec3 vertexNormal; uniform mat4 uTranslate; uniform mat4 uRotate; uniform mat4 uScale; uniform mat4 uViewProjection; layout(location = 2) out vec3 vPosition; layout(location = 3) out vec3 vNormal; void main() { vec4 vertex = vec4(vertexPosition,1.0); mat4 model = uTranslate * uRotate * uScale; gl_Position = (uViewProjection * model) * vertex; vPosition = vec3(model * vec4(vertexPosition,1.0)); vNormal = mat3(transpose(inverse(model))) * vertexNormal; }
Model.cpp
// ##################################### .objファイル読み込み ##################################### void FrameWork::D3::LoadObj(const char *fileName, ObjFile &attribute) { ObjFile obj; std::vector<int> vertexIndex; std::vector<int> uvIndex; std::vector<int> normalIndex; std::vector<glm::vec3> vertex; std::vector<glm::vec2> uv; std::vector<glm::vec3> normal; FILE *file = fopen(fileName, "r"); if (file == NULL) { std::cerr << ".OBJファイルが開けません: " << fileName << std::endl; assert(0); } else { while (true) { char line[500]; int res = fscanf(file, "%s", line); if (res == EOF) { break; } if (strcmp(line, "v") == 0) { glm::vec3 vert; fscanf(file, "%f %f %fn", &vert.x, &vert.y, &vert.z); vertex.push_back(vert); } else if (strcmp(line, "vt") == 0) { glm::vec2 u; fscanf(file, "%f %fn", &u.x, &u.y); uv.push_back(u); } else if (strcmp(line, "vn") == 0) { glm::vec3 norm; fscanf(file, "%f %f %fn", &norm.x, &norm.y, &norm.z); normal.push_back(norm); } else if (strcmp(line, "f") == 0) { unsigned int v[3], u[3], n[3]; int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%dn", &v[0], &u[0], &n[0], &v[1], &u[1], &n[1], &v[2], &u[2], &n[2]); vertexIndex.push_back(v[0]); vertexIndex.push_back(v[1]); vertexIndex.push_back(v[2]); uvIndex.push_back(u[0]); uvIndex.push_back(u[1]); uvIndex.push_back(u[2]); normalIndex.push_back(n[0]); normalIndex.push_back(n[1]); normalIndex.push_back(n[2]); } } for (unsigned int i = 0; i < vertexIndex.size(); i++) { unsigned int vi = vertexIndex[i]; unsigned int ui = uvIndex[i]; unsigned int ni = normalIndex[i]; glm::vec3 v = vertex[vi - 1]; glm::vec2 u = uv[ui - 1]; glm::vec3 n = normal[ni - 1]; VertexAttribute attrib; attrib.position[0] = v.x; attrib.position[1] = v.y; attrib.position[2] = v.z; attrib.uv[0] = u.x; attrib.uv[1] = u.y; attrib.normal[0] = n.x; attrib.normal[1] = n.y; attrib.normal[2] = n.z; obj.attribute.push_back(attrib); } } attribute = obj; }

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

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

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

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

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

fana

2021/10/29 01:24

> Vertex Shader のコード提示部分に,Fragment Shader の内容が混ざり込んでしまっているように見えます.
fana

2021/10/29 02:10 編集

Vertex Shader の > vNormal = mat3(transpose(inverse(model))) * vertexNormal; ここの部分がどんな意味の演算をしているのかを説明願えますか? この演算に関する説明が存在する参考元がある場合にはそれを提示していただくのでも構いません. --- 【追記】 この問いへの回答は無理にしていただかなくてもよいです. (なんとなくわかりましたので. → 質問の現象とは関係ないかな,と思えます.)
fana

2021/10/29 04:14

質問文が編集されましたが,それだと変じゃありませんか? コードが3個提示されていて, * 1個目には,2種類のシェーダのコードが書かれていると見える (←これが最初のコメントで指摘した事柄.Vertex Shaderの コードだけにするべきでは?) * 2個目は,Fragment Shader のコードである * 3個目は,謎のcppコードである …と見えますが.
退会済みユーザー

退会済みユーザー

2021/10/29 04:18

文章を修正しました。
fana

2021/10/29 04:31

前述の質問文の記述形態の話とはまた別の話として…… シェーダコード側の実装が間違っているのか,それとも,cpp側の処理に問題があるのか? という切り分けをすべきと思います. シェーダコードの実装が妥当か否かを確認する際には > blenderで出力したobjファイルをロードして… という話は不要なハズです. 同様に,objファイルをロードするような話側の動作確認を行う際にはシェーダは不要です.
退会済みユーザー

退会済みユーザー

2021/10/29 04:33

シェーダーが間違えているのか? OBJローダーが間違えているのかがわからないのです。
fana

2021/10/29 04:41

【「OBJローダー」とかいう実装を全く含まないプログラム】を用意して,そこでそのシェーダコードを使ってみれば良いのでは? と言っているのですが. それでまともにレンダリングできるならばシェーダ側はOKなのだと判断できるのではないのですか? まずはその確認をすべきでしょう. 少数の三角形で形作られたテスト用の簡単な形状:{立方体だとか,ピラミッドみたいな形だとか,粗雑な球っぽい何かだとか…}くらいであれば, データを全てハードコーディングでも用意できるでしょうから,そういうのを数種類レンダリングさせてみるべきです.
退会済みユーザー

退会済みユーザー

2021/10/29 05:59

はい、実験して追記しました。
fana

2021/10/29 06:20

> 立方体の面を1つの三角形に減らして実装したのでが一枚目の画像ですがライティングの陰影が出てきるのでシェーダーファイルが原因でないことを突き止めました。 私には その画像を見ても 三角形1個が正常に描画できている結果なのか否か がさっぱりわかりませんが…
退会済みユーザー

退会済みユーザー

2021/10/29 09:13

三角形一個は正常に描画出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問