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

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

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

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

C++

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

3DCG

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

GLSL

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

Q&A

受付中

板ポリをPhongシェーダーさせたいが光沢が付かない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

3DCG

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

GLSL

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

2回答

0グッド

0クリップ

822閲覧

投稿2021/12/19 09:59

編集2021/12/21 02:52

提示画像ですが板ポリにPhongのシェーディングを行いたいのですが上手く反射が付きません。シェーダーは参考サイトを移しました。またライトの座標を(0,1000,-500)といったオブジェクトのずっと上で先の座標を指定しましたが見え方が同じです。下記の実現したいこと部の右の画像ような光沢を出したいです。

現状

カメラ座標(0,0,10) 向き(0,0,-1)
オブジェクト座標(0,0,-200) Scale(100,100,0)

#####試したこと
ライト座標をスプライトに限りなく近ずけた。
板ポリを適当な角度に回転させて光沢が出るかどうか確認

#####実現したいこと(右の画像部ような)
イメージ説明

参考サイト: https://learnopengl.com/Lighting/Basic-Lighting
参考サイト: http://tegetegeosprey.g1.xrea.com/opengl/opengl_normalvecotr.htm
イメージ説明

Sprite

cpp

1 2// ##################################### 頂点属性 ##################################### 3 4void FrameWork::D2::Sprite::setAttribute() 5{ 6 size = endSize - startSize; 7 8 vertex->resize(6); 9 10 // 頂点座標 11 vertex->at(0).position[0] = -0.5f; 12 vertex->at(0).position[1] = 0.5f; 13 vertex->at(0).position[2] = 0; 14 15 16 vertex->at(1).position[0] = -0.5f; 17 vertex->at(1).position[1] = -0.5f; 18 vertex->at(1).position[2] = 0; 19 20 vertex->at(2).position[0] = 0.5f; 21 vertex->at(2).position[1] = 0.5f; 22 vertex->at(2).position[2] = 0; 23 24 vertex->at(3).position[0] = 0.5f; 25 vertex->at(3).position[1] = 0.5f; 26 vertex->at(3).position[2] = 0; 27 28 vertex->at(4).position[0] = -0.5f; 29 vertex->at(4).position[1] = -0.5f; 30 vertex->at(4).position[2] = 0; 31 32 vertex->at(5).position[0] = 0.5f; 33 vertex->at(5).position[1] = -0.5f; 34 vertex->at(5).position[2] = 0; 35 36 //UV座標 37 float sizeX = 1.0f / (float)size.x; 38 float sizeY = 1.0f / (float)size.y; 39 40 vertex->at(0).uv[0] = sizeX * startSize.x; 41 vertex->at(0).uv[1] = sizeY * endSize.y; 42 43 vertex->at(1).uv[0] = sizeX * startSize.x; 44 vertex->at(1).uv[1] = sizeY * startSize.y; 45 46 vertex->at(4).uv[0] = sizeX * startSize.x; 47 vertex->at(4).uv[1] = sizeY * startSize.y; 48 49 vertex->at(2).uv[0] = sizeX * endSize.x; 50 vertex->at(2).uv[1] = sizeY * endSize.y; 51 52 vertex->at(3).uv[0] = sizeX * endSize.x; 53 vertex->at(3).uv[1] = sizeY * endSize.y; 54 55 vertex->at(5).uv[0] = sizeX * endSize.x; 56 vertex->at(5).uv[1] = sizeY * startSize.y; 57} 58 59 60// 面法線 61glm::vec3 GetSurfaceNormal(glm::vec3 v1, glm::vec3 v2, glm::vec3 v3) 62{ 63 return glm::cross(v2 - v1,v3 - v2); 64} 65 66 67// ##################################### 法線 設定 ##################################### 68void FrameWork::D2::Sprite::setNormal() 69{ 70 glm::vec3 sur1 = GetSurfaceNormal( 71 glm::vec3(vertex->at(0).position[0], vertex->at(0).position[1], vertex->at(0).position[2]), 72 glm::vec3(vertex->at(1).position[0], vertex->at(1).position[1], vertex->at(1).position[2]), 73 glm::vec3(vertex->at(2).position[0], vertex->at(2).position[1], vertex->at(2).position[2])); 74 75 glm::vec3 sur2 = GetSurfaceNormal( 76 glm::vec3(vertex->at(3).position[0], vertex->at(3).position[1], vertex->at(3).position[2]), 77 glm::vec3(vertex->at(4).position[0], vertex->at(4).position[1], vertex->at(4).position[2]), 78 glm::vec3(vertex->at(5).position[0], vertex->at(5).position[1], vertex->at(5).position[2])); 79 80 81 glm::vec3 s = sur1 + sur2; 82 s = glm::normalize(s); 83 glm::vec3 vec1 = glm::normalize(sur1); 84 glm::vec3 vec2 = glm::normalize(sur2); 85 86 //printf("%f\n",vec1.z); 87 88 vertex->at(0).normal[0] = vec1.x; 89 vertex->at(0).normal[1] = vec1.y; 90 vertex->at(0).normal[2] = vec1.z; 91 92 vertex->at(1).normal[0] = s.x; 93 vertex->at(1).normal[1] = s.y; 94 vertex->at(1).normal[2] = s.z; 95 96 vertex->at(2).normal[0] = s.x; 97 vertex->at(2).normal[1] = s.y; 98 vertex->at(2).normal[2] = s.z; 99 100 101 102 103 104 vertex->at(3).normal[0] = s.x; 105 vertex->at(3).normal[1] = s.y; 106 vertex->at(3).normal[2] = s.z; 107 108 vertex->at(4).normal[0] = s.x; 109 vertex->at(4).normal[1] = s.y; 110 vertex->at(4).normal[2] = s.z; 111 112 vertex->at(5).normal[0] = vec2.x; 113 vertex->at(5).normal[1] = vec2.y; 114 vertex->at(5).normal[2] = vec2.z; 115 116} 117 118 119 120 121// ##################################### テクスチャ描画 ##################################### 122void FrameWork::D2::Sprite::Draw(glm::mat4 projection,glm::vec3 position, int texNum, float r, glm::vec2 s, glm::vec2 start, glm::vec2 end) 123{ 124 125 shaderTexture.setEnable(); 126 glBindVertexArray(vao); 127 glBindBuffer(GL_ARRAY_BUFFER, vbo); 128 129 startSize = start; //テクスチャ始点 130 endSize = end; //テクスチャ終点 131 132 vertex->resize(6); 133 setAttribute(); //頂点属性 設定 134 135 setNormal(); //法線 設定 136 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VertexAttribute) * vertex->size(), vertex->data()); 137 138 //Transform 139 glm::vec3 pos = position; 140 pos.y = (float)FrameWork::windowContext->getSize().y - pos.y - (glm::vec2(end - start).y / 2); 141 pos.x = pos.x + (glm::vec2(end - start).x / 2); 142 //setPosition(pos); //座標 143 144 145 setPosition(position); // 146 setScale(glm::vec2(100,100)); //スケール 147 setRotate(pi); //回転 148 pi += PI / 100; 149 150 //描画 151 152 shaderTexture.setUniform3f("uLightPosition", glm::vec3(0, 100, -200)); 153 //shaderTexture.setUniform3f("uLightPosition", glm::vec3(0, 0, 10)); 154 155 shaderTexture.setUniform3f("uLightColor", glm::vec3(1, 1, 1)); 156 shaderTexture.setUniform3f("uObjectColor", glm::vec3(1, 0, 0)); 157 shaderTexture.setUniform3f("uViewPosition", glm::vec3(0, 0, 10)); 158 shaderTexture.setUniform1f("uAmbientStrength",0.2f); 159 shaderTexture.setUniform1f("uSpecularStrength",0.5); 160 shaderTexture.setUniform1f("uShininessStrength",32.0); 161 162 shaderTexture.setUniformMatrix4fv("uTranslate",getMatTranslation()); 163 shaderTexture.setUniformMatrix4fv("uRotate", getMatRotate()); 164 shaderTexture.setUniformMatrix4fv("uScale", getMatScale()); 165 shaderTexture.setUniformMatrix4fv("uViewProjection", projection); 166 //shaderTexture.setUniformMatrix4fv("uViewProjection", glm::ortho(0.0f, (float)FrameWork::windowContext->getSize().x, 0.0f, (float)FrameWork::windowContext->getSize().y)); 167 //printf("%d\n",textureID.at(texNum)); 168 169 //glActiveTexture(GL_TEXTURE0); //テクスチャ有効 170 //glBindTexture(GL_TEXTURE_2D, textureID.at(texNum)); //テクスチャバインド 171 172 173 174 glDrawArrays(GL_TRIANGLES, 0, vertex->size()); //描画 175 176 //バインド解除 177 glBindVertexArray(0); 178 glBindBuffer(GL_ARRAY_BUFFER, 0); 179 //glBindTexture(GL_TEXTURE_2D, 0); 180 181 shaderTexture.setDisable(); 182}
GLSL
/*######################################################################### # フラグメントシェーダー ###########################################################################*/ #version 420 //#extension GL_ARB_explicit_uniform_location : require layout(location = 2) in vec3 vPosition; layout(location = 3) in vec3 vNormal; uniform vec3 uLightPosition; //ライト座標 uniform vec3 uLightColor; //ライト色 uniform vec3 uObjectColor; //オブジェクトの色 uniform vec3 uViewPosition; //カメラ座標 uniform float uAmbientStrength; //環境光の強さ uniform float uSpecularStrength; //鏡面反射の強さ uniform float uShininessStrength; //反射輝度の強さ layout (location = 0) out vec4 fragColor; //out vec4 fragment; void main() { // ambient // float ambientStrength = 0.1; vec3 ambient = uAmbientStrength * uLightColor; // diffuse vec3 norm = normalize(vNormal); vec3 lightDir = normalize(uLightPosition - vPosition); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = diff * uLightColor; // specular //float specularStrength = 0.5; vec3 viewDir = normalize(uViewPosition - vPosition); vec3 reflectDir = reflect(-lightDir, norm); //float uShininessStrength = 32; float spec = pow(max(dot(viewDir, reflectDir), 0.0), uShininessStrength); vec3 specular = uSpecularStrength * spec * uLightColor; vec3 result = (ambient + diffuse + specular) * uObjectColor; fragColor = vec4(result, 1.0); }
/*######################################################################### # 頂点シェーダー ###########################################################################*/ #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; vPosition = vec3(model * vec4(vertexPosition,1.0)); vNormal = mat3(transpose(inverse(model))) * vertexNormal; gl_Position = (uViewProjection * model) * vertex; }

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

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

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

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

fana

2021/12/20 01:56

> ライトの座標を(0,1000,-500)といったオブジェクトのずっと上… とか言われても,その数値がどのくらいの影響を発揮する想定で定められた値なのかは読み手には全く不明です. ポリゴンと光源と視点がこういう配置関係にあるならば,こういう具合にこのくらいの陰影が付くハズである →のに,実際はこうなっている といった具体的なテスト状況と想定結果を述べるべきです. (手計算が簡単にできるようなテスト状況を用意し,頂点や面の中央位置等と言った位置での理屈上の結果を手計算で求め,それと実行結果とを比較する.)
fana

2021/12/20 02:01

既存の回答で触れられていますが, そもそも「板ポリ」って何ですか?という点に関して,法線の観点での説明が必要でしょう. 単なる「平面」を想定したものなのであれば,頂点の法線が揃っていることは想定通りなのでしょうし.
退会済みユーザー

退会済みユーザー

2021/12/21 01:33

質問を修正しました。

回答2

0

当てずっぽうですが

shaderTexture.setUniform1f("uAmbientStrength", 1.5);

これ強すぎて,ambient 成分だけで飽和しませんか?
こいつを弱めてみたら(例えばとりあえず 0 にしてみるとかしたら)陰影具合が見えるようになったりしませんか?

↓みたいな,あからさまに陰影が付くだろう配置関係にでもしてテストしてみる感じで.

* ←光源(かなり近い位置に配置) ━━━━━━━━━━━━ ←ポリゴン(法線は↑向き)

投稿2021/12/20 02:15

fana

総合スコア10796

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

退会済みユーザー

退会済みユーザー

2021/12/20 08:35

試しましたが反射が表示されません。
fana

2021/12/20 09:13

「反射が表示される」というのはどのような状況の事を指すのですか? ambientを成分の係数を0にしても陰影は見られないのですか? ambientの係数を0にした状態で光源とポリゴンと視点の位置関係が変化しても描画色が一定なのでしょうか?
fana

2021/12/20 09:37

点光源が写り込んでいるようなイメージですか. (陰影自体は見られるようになったんですかね?) Specular 成分が鋭い変化を見せないとそういう絵にはならないわけですから, (法線が単一である)平面でそういう絵を得ようとすれば この回答に図示したように「かなり近い位置」に点光源を置く必要があるかと思いますが. (で,あとはそれを観測できるような位置に視点を置く必要もある)
退会済みユーザー

退会済みユーザー

2021/12/20 09:49

かなり近い位置にライトを置いて、法線の値を適当にじったり、計算した正確な値に戻りたり色々したのですが表示されません。またライトの色、オブジェクトの色それぞれの強さの値をいじると板ポリの色が変化するためシェーディングの実装自体は出来ると思います。
fana

2021/12/21 00:35

[質問への追記・修正、ベストアンサー選択の依頼] に記したように, 「理屈上ではこういう絵が得られるハズ」というパラメータを用いて動作検証してください. 「色々やったけどダメでした」では読み手には情報量ゼロに等しいわけで, そのような具体的な形での検証結果情報を出さない限り進展はないでしょう. #あと,他の回答にも応答しましょう.

0

コードを細かく検証はしていませんが、2つのトライアングルを同じ平面に置いて1つの四角形を作っているのですよね。そしてsur1sur2は各トライアングルの面法線なんですよね。ということは、sur1sur2は同じ向きですよね。ということは、その2つの法線を足して正規化したssur1sur2を正規化したvec1vec2は同じ値なのではないですか。結局、各頂点に同じ法線を与えているのでは。

Phongシェーディングは、ポリゴン内部の各ピクセルについて、頂点法線を補間して計算した法線で陰影を計算するものなので、各頂点法線が同じなら意味がないです。

投稿2021/12/19 11:24

itagagaki

総合スコア8390

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

fana

2021/12/20 02:05 編集

重箱の隅的コメント: > 各頂点法線が同じなら意味がないです というのは少々乱暴かな,と. Phongの反射モデルでは法線が同じでも同一面上の各画素の色は specular 成分により差が生じ得るので. (「Phongシェーディング」(補間法)が意味を成さずとも「Phongの反射モデル」(色の計算法)の側は状況次第で働き得る,的な.) --- おっと,コード見た感じ「平行光源」じゃなくて「点光源」なんですね. ならば diffuse 成分も差を生じ得る感じですね.
itagagaki

2021/12/20 02:17

PhongシェーディングとPhongの反射モデルを一体となるものとお考えになってのコメントと思いますがそれは違うと思います。この質問と私の回答はPhongシェーディングに関することです。
fana

2021/12/20 02:25 編集

> 上手く陰影が付きません というシェーダの処理結果の話,すなわち質問は 「Phongシェーディング + Phongの反射モデル を実装した物」の話であろうと捉えました. > 値を変えると見え方は変わるのですが反射描画がされず という文言は,どちらかと言えば「反射モデル」側の話かな,と. (まぁ,質問者としては2つを区別していない気もしますが)
itagagaki

2021/12/20 02:29

まあ確かに平面にどうして陰影を期待しているのか疑問には思いましたが。質問者の名前も確認すべき案件でした。
退会済みユーザー

退会済みユーザー

2021/12/21 00:53

法線を変な方向に色々ずらしたのですが反射が現れず結局同じ出力結果になってしまうのですがなせでしょうか?

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

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

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

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenGL

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

C++

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

3DCG

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

GLSL

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