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

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

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

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

C++

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

GLSL

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

Q&A

解決済

1回答

1498閲覧

正射形でフォンシェーディングを行いたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

GLSL

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

0グッド

0クリップ

投稿2021/06/09 10:56

正射形でフォンのシェーディングを行いたいのですが以下ような表示になってしまいうまく光沢が表現できません。なぜでしょうか?そもそも正射形ではできないのでしょうか?

イメージ説明

cpp

1// ##################################### レンダリング ##################################### 2void Game::Renderer()const 3{ 4 sprite->setEnable(); 5 6 7 8 //std::cout << "ああ" << std::endl; 9 10 sprite->setUniform3f("uCameraPos", glm::vec3(0, 0, 1)); 11 12 sprite->setUniform3f("uAmbientLight", glm::vec3(0.2, 0.2, -1.0)); 13 sprite->setUniform3f("uDirLight.mDirection", glm::vec3(0.0, 0.0, -1.0)); 14 sprite->setUniform3f("uDirLight.mDiffuseColor", glm::vec3(1, 1, 1)); 15 sprite->setUniform3f("uDirLight.mSpecColor", glm::vec3(1, 1, 1)); 16 sprite->setUniform1f("uSpecPower", 1.0f); 17 18 sprite->DrawGraph(glm::vec2(WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2 - 75), 0, 0.0f, glm::vec2(0, 0), glm::vec2(0, 0), glm::vec2(200, 150)); 19 20 21 22 sprite->setDisable(); 23 24}

glsl

1/*######################################################################### 2# フォング 頂点シェーダー 3###########################################################################*/ 4#version 330 5#extension GL_ARB_explicit_attrib_location: enable 6 7 8 9 10// ###################### 頂点属性 ###################### 11layout(location = 0) in vec2 vertexPosition; //座標 12layout(location = 1) in vec2 vertexUV; //UV座標 13layout(location = 2) in vec3 vertexNorm; //法線 14 15// ###################### 出力 ###################### 16layout(location = 3) out vec2 vUV; //UV 17layout(location = 4) out vec3 vNorm; //法線 18layout(location = 5) out vec3 vPosition; //座標 19 20// ###################### Unifrom ###################### 21uniform mat4 uScale; //スケール 22uniform mat4 uRotate; //回転 23uniform mat4 uTranslate; //平行移動 24 25uniform mat4 uViewProjection; //ビュープロジェクション行列 26 27 28 29 30void main() 31{ 32 vec4 vertex = vec4(vertexPosition,0.0,1.0); //同次元座標 33 mat4 model = uTranslate * uRotate * uScale; //モデル行列 34 gl_Position = (uViewProjection * model) * vertex; //頂点座標 クリップ空間 35 36 vNorm = (vec4(vertexNorm,0.0) * uViewProjection).xyz; //法線 37 38 vPosition = vertex.xyz; 39 vUV = vertexUV; //UV座標 40}

glsl

1/*######################################################################### 2# フォング フラグメントシェーダー 3###########################################################################*/ 4#version 330 5 6#extension GL_ARB_explicit_attrib_location: enable 7 8 9 10// ###################### 変数 ###################### 11 12//ライト 13struct DirectionalLight 14{ 15 vec3 mDirection; // 平行光源 16 vec3 mDiffuseColor; // 拡散反射色 17 vec3 mSpecColor; // 鏡面反射色 18}; 19 20// ###################### 入力 ###################### 21layout(location = 3) in vec2 vUV; //UV座標 22layout(location = 4) in vec3 vNorm; //法線 23layout(location = 5) in vec3 vPosition; //座標 24 25// ###################### Unifrom ###################### 26uniform sampler2D uImage; //イメージ 27 28uniform vec3 uCameraPos; //カメラ 29uniform float uSpecPower; //鏡面反射強さ 30uniform vec3 uAmbientLight; //環境光 31 32uniform DirectionalLight uDirLight; //平行光源 33 34 35 36// ###################### 出力 ###################### 37out vec4 fragment; 38 39 40 41 42 43void main() 44{ 45 vec3 N = normalize(vNorm); 46 vec3 L = normalize(-uDirLight.mDirection); 47 vec3 V = normalize(uCameraPos - vPosition); 48 vec3 R = normalize(reflect(-L, N)); 49 50 vec3 Phong = uAmbientLight; 51 float NdotL = dot(N,L); 52 if(NdotL > 0) 53 { 54 vec3 Diffuse = uDirLight.mDiffuseColor * NdotL; 55 vec3 Specular = uDirLight.mSpecColor * pow(max(0.0, dot(R, V)), uSpecPower); 56 Phong += Diffuse + Specular; 57 } 58 59 60 61 fragment = texture(uImage,vUV) * vec4(Phong, 1.0f); 62}

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

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

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

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

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

guest

回答1

0

ベストアンサー

射影方式とシェーディング計算の間には本質的な関連性はありません.

ぱっと見では,バーテックスシェーダ内の

vNorm = (vec4(vertexNorm,0.0) * uViewProjection).xyz; //法線

が,妥当な処理なのか? と疑問が湧きます.

投稿2021/06/10 03:33

fana

総合スコア11996

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

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

退会済みユーザー

退会済みユーザー

2021/06/11 00:59

質問ですが vNorm = (vec4(vertexNorm,0.0f) * ((uViewProjection * model))).xyz; //法線 としましたが上手く表示されません。何が悪いのでしょうか?値をいろいろ変更しましたが原因がどうしてもわかりません。
fana

2021/06/11 01:15

逆に質問しますが, > gl_Position = (uViewProjection * model) * vertex; は,「ベクトル = 行列 * ベクトル」という形ですが, vNormの側の記述は,これとは違っていて 「ベクトル = ベクトル * 行列」という形に見えます. 両者の間では乗算の項の順序が異なっていますが,両者の記述の違いは何なのでしょうか? 私自身,後者側の形のコードをシェーダに書いたときにどうなるのかを把握していないので,説明願いたいです.
退会済みユーザー

退会済みユーザー

2021/06/11 01:24

ベクトル = 行列 * ベクトル としてみましたが正解なのかわかりません
fana

2021/06/11 01:37 編集

「やってみた」では意味がありませんし, 正解かどうか不明なまま実装をいじくってもやはり意味がないのではありませんか? そもそも, > vNorm = ... の,演算の意図とは何なのでしょうか? 「フラグメントシェーダで必要となる vNorm とは何か?」という話がまずあって,それに即したものをバーテックスシェーダで用意してやる,という話なのでしょうから, 「フラグメントシェーダで必要となる vNorm とは何か?」が不明な状態でバーテックスシェーダ側を > いろいろ変更 しても意味はないですし,原因を掴むこともできないでしょう. vNormが「法線」なのであれば,これは 「位置ベクトル」ではなくて「方向ベクトル」 です. それに対して,座標(位置ベクトル)と同じ演算を施すのは間違っていますよね.(っていうあたりからもう全く理解してないのだと思うが…) > vNorm = (vec4(vertexNorm,0.0f) * ((uViewProjection * model))).xyz; //法線 では,model という行列を作用させようとしているようですが, 法線をスケーリングする意味は無いでしょうし,"並進" を施したら「向き」が変わってしまいます. uViewProjection についても同様です.そのマトリクスを作用させたら何が起こるのか? それは所望の演算なのか? 各ベクトル量や,実施している演算の「意味」を把握しない限り,いつまでたっても,このあたりの話を満足に扱うことはできないでしょう. 算数と数学に関する基礎的な学力が圧倒的に足りていないのだと見受けます. 世の中の大多数の人々は一生三角関数も使わずに過ごすのでしょうから(←偏見か?),あなただけが極端に「足りていない」という話ではありません.多分,普通でしょう. しかし,あなたは算数や数学が必要になることを あえてやろうとしている のですから,算数や数学が必要になっているわけです. 己の意思でわざわざ苦行に挑むのであれば,必要なことをしっかり勉強しましょう.
退会済みユーザー

退会済みユーザー

2021/06/11 02:07

vNorm = vertexNorm; とすることで実装出来ました。
fana

2021/06/11 02:15

うん,まぁ,それで満足ならいいんじゃない? (99%くらいの確率で それは違うんじゃないか? とは思うが)
退会済みユーザー

退会済みユーザー

2021/06/11 07:53

vNorm = ( model * vec4(vertexNorm,0.0) ).xyz; //法線 としましたが正解なのでしょうか?
fana

2021/06/11 08:02

> model = uTranslate * uRotate * uScale; なんてものを「法線」に対して用いること自体がおかしくね? という私の意見は既に述べているつもりなのだけど.
fana

2021/06/11 08:05

> 正解なのでしょうか? だけではなく,何故あなたがそのような実装を行うに至ったのか? という考えを述べてください. (これは正しいか? というだけの問いを相手にしていても,こちらとしてはまるで得るものがないので)
退会済みユーザー

退会済みユーザー

2021/06/11 08:06

法線をワールド座標に変換してフラグメントシェーダーに送信してフォンのシェーディングを行いたいのですが法線の送り方は正しいのでしょうか?
fana

2021/06/11 08:31 編集

えっとー,たとえばー, ある頂点の「モデル座標系での」データが, ・位置 (3,2) ・法線 (1,0) だとするじゃん? で,「モデル座標系」の原点ってのは「ワールド座標系」で(10,10)であるとしよう. (回転とスケーリングは特に必要なくて,単に原点位置のみが異なる状況) この「モデル座標系」での値である頂点のデータを「ワールド座標系」の値に変換したい,と. そしたら,変換結果はどうなるんですかね? 座標は,(3,2) + (10,10) で (13, 12) でしょうけど, 法線はどうしますか? 座標と同じ演算を行って (1,0) + (10,10) で (11,10) にするべきでしょうか? (1,0) と (11,10) では,長さも方向も変わっちゃってますけど.
fana

2021/06/11 08:31

同じことを,スケーリングや回転についても考えてください.真面目に. 行列 model は, model = uTranslate * uRotate * uScale; であり,並進と回転とスケーリングを全て含んでいるわけですが,本当にこれを「法線」に乗じるべきですか?
退会済みユーザー

退会済みユーザー

2021/06/11 08:41

なるほど。違いますね。ではどういったことをするべきなのでしょうか?
fana

2021/06/11 08:52

うーん, どうあっても絶対に自分自身では考えないぞ! という,圧倒的な強い意志みたいなものを感じざるを得ない… ここまでで ・あなたに対しては取るべき行動の指針は十二分に示したつもりですし, ・あなたでない誰かが読んだ場合を想定しても十分な情報は示したと思いますし ・私ではこれ以上簡潔に説明できる気がしませんし ・どうやらこの話を続けても私には得るものがなさそうですから 本件については,私はこれ以上は続けないこととします.
退会済みユーザー

退会済みユーザー

2021/06/11 09:43

> なるほど。違いますね。ではどういったことをするべきなのでしょうか? 横から失礼します、勉強してみてはいかがでしょうか。 ただ「数学難しすぎて無理w」ということでしたら、諦めるのも一つの手だと思います。
fana

2021/06/14 02:21

> 諦める 「ここの部分の話はどうしても理解が追い付かないからもうブラックボックスとするぜ!」という部分的な諦め方もあります. このあたりの3Dまわりの話は,部分的にブラックボックスとすることが比較的行いやすいように思えます. 私は数学が超苦手なので,毎度そのように諦めています. 割ける時間や自身の脳力等の事情次第では「無理なものは無理」なので, 内側はわからんけど IN と OUT だけを把握する→内側のことは忘れて使う という手段に出ることも時には必要です.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問