現在、Blender で作成し、次のオプションを設定して assimp を介してロードした 3D シーンでいくつかの照明を設定しています。
aiProcess_GenSmoothNormals | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_FlipUVs
現在、私は自分のプログラムで本当に奇妙な不具合に悩まされています。次のプロパティを使用して、照明用のフラグメント シェーダーにPhong シェーディングを実装しています。
- 各モデルにはテクスチャが設定されています。
- 各モデルには、モデルから読み込まれた法線ベクトルがあります (おそらく aiProcess_GenSmoothNormals フラグのため、いくつかの事前計算が行われています)。
- 鏡面反射光はすべてのオブジェクトに作用します。
- 拡散色は正常に機能します。
ただし、パイプ オブジェクトは異なります。拡散反射光の色は常にパイプの反対側にあり、鏡面反射光は正しい側にあります。鏡面反射光は正常に機能しているのに、拡散成分は常に反対側にあるため、これは奇妙なことです。ブレンダーで円柱オブジェクトを特定のポイントを超えてスケーリングすると、この効果に気付きました (より小さいスケーリングされた円柱は正常に機能します)。特定のしきい値を超えて円柱オブジェクトをスケーリングすると、おそらく何か関係があります。
私のシーンでは、パイプのようなオブジェクトには鏡面反射光コンポーネントが機能していますが、拡散色は光源の反対側にあります。
ブレンダーで見た法線
私の最初の推測では、それは法線スケーリングと関係があるということでしたが、頂点シェーダーでその目的のために既に法線マトリックスを使用しており、シーン内の他のオブジェクトは問題なく動作します。
頂点シェーダー:
#version 330
layout (location = 0) in vec3 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 color;
layout(location = 4) in vec2 texCoord;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec3 lightPos;
out vec3 Position;
out vec3 Normal;
out vec3 LightPos;
out vec2 TexCoord;
void main()
{
gl_Position = projection * view * model * vec4(vertex, 1.0);
// Position
Position = vec3(view * model * vec4(vertex, 1.0));
// Normal
mat3 normalMat = transpose(inverse(mat3(view * model)));
Normal = normalMat * normal;
// Lighting
LightPos = vec3(view * vec4(lightPos, 1.0));
// Texture
TexCoord = texCoord;
}
フラグメント シェーダー:
#version 330
in vec3 Position;
in vec3 Normal;
in vec3 LightPos;
in vec2 TexCoord;
uniform sampler2D texture0;
out vec4 outColor;
void main()
{
// defaults
vec4 ambient = vec4(0.2);
vec4 diffuse = vec4(0.4);
vec4 specular = vec4(0.5);
vec4 texColor = texture(texture0, TexCoord);
// Phong shading
vec3 LightDir = normalize(LightPos - Position);
vec3 Norm = normalize(Normal);
vec3 ViewDir = normalize(-Position);
vec3 ReflectDir = reflect(-LightDir,Norm);
float specularContribution = pow(max(dot(ViewDir, ReflectDir), 0.0), 32);
// Calculate diffuse component
vec4 I = diffuse * max(dot(Norm, LightDir), 0.0);
diffuse = clamp(I, 0.0, 1.0);
// Calculate specular component
specular = specular * specularContribution;
outColor = texColor * (diffuse + ambient + specular);
}
編集
デバッグ目的で、2 番目の描画パスですべての頂点法線を表示するジオメトリ シェーダーを追加しました。ただし、法線を表示すると、カメラの動きに合わせてわずかに動いてしまいますが、これは行うべきではありません。これがおそらく前述の問題の原因であると推測しています。
通常の動きを説明する小さなビデオを作成しました:通常の動きの問題を表示する Youtube ビデオ。
このビデオは、カメラが移動するにつれて方向を変えるピンクの法線を示しています。これはあってはならないことであり、その理由はわかりません。法線行列が正しくないのでしょうか、それとも assimp が法線を正しくロードしないのでしょうか?