实现 PhongModel 着色时。镜面反射项出现在几何体的两侧。使用半向量计算镜面反射项。
在前面的输出图像中,它似乎计算正确。光在相机后面,物体在相机前面。
[光……相机……物体]
但是当去另一边时,即使没有漫反射项,我仍然会得到一些镜面反射,我不确定我是否应该这样做。在下面的图片中,物体和灯光都在相机前面,灯光在物体后面。
[相机……物体……光]
我想也许镜面反射应该乘以符号(fLDotN)?但结果似乎并不好。一般是怎么处理的?
我的猜测是我是
光照均匀位置在相机空间中设置:
vec3 ptLightPos_CS=vec3(matLookAt*vec4(ptLightPos, 1));
具有法线和半向量的结果图像: Phong Specular+Diffuse Results
顶点着色器
// Input layouts
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexCoord;
in vec3 vertexTangent;
in vec3 vertexBitangent;
// Output layouts
// Uniform variables
uniform VertexUniforms
{
mat4 uniform_Projection;
mat4 uniform_ModelView;
mat4 uniform_NormalMatrix;
};
// In variables
// Out variables
out vec2 vs_uv;
out vec3 vs_normal;
out vec3 vs_tangent;
out vec3 vs_bitangent;
out vec3 vs_pos;
// Global variables
/*************/
void main()
{
// Convert the vertex to clip space
vec3 vcPos=vec3(uniform_ModelView*vec4(vertexPosition, 1.0f));
vec4 vertexProj = uniform_Projection * vec4(vcPos, 1.0f);
///--- Tangent space
vs_normal=normalize(vec3(uniform_NormalMatrix * vec4(vertexNormal, 0)));
vs_tangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexTangent, 0)));
vs_bitangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexBitangent, 0)));
///---
vs_pos=vcPos;
// UV
vs_uv=vertexTexCoord;
gl_Position = vertexProj;
}
片段着色器
// Output layouts
out vec4 outColor;
// Uniform variables
uniform vec3 uniform_v3LightDiffuseColor;
uniform vec3 uniform_v3LightSpecularColor;
uniform sampler2D uniform_tDiffuse;
uniform sampler2D uniform_tNormal;
uniform vec3 uniform_v3LightPos;
// In variables
in vec2 vs_uv;
in vec3 vs_normal;
in vec3 vs_tangent;
in vec3 vs_bitangent;
in vec3 vs_pos;
// Out variables
// Global variables
/*************/
#define PI 3.141592
void main()
{
const vec3 T=normalize(vs_tangent);
const vec3 B=normalize(vs_bitangent);
const vec3 N=normalize(vs_normal);
const mat3 mTBN=mat3(T, B, N);
vec3 vNormal=mTBN*((texture2D(uniform_tNormal, vs_uv).xyz*2.0-1.0));
vNormal=normalize(vNormal);
const vec3 vEye=normalize(-vs_pos);
const vec3 vLightDir=normalize(uniform_v3LightPos-vs_pos);
const vec3 vLightDiffuse=vec3(0.5,0.5,0.5);//uniform_v3LightDiffuseColor;
const vec3 vLightSpecular=vec3(0.5,0.5,0.5);//uniform_v3LightSpecularColor;
const vec3 vMatDiffuse=vec3(0.5,0.5,0.5);//texture2D(uniform_tDiffuse, vs_uv).xyz;
const vec3 vMatSpecular=vMatDiffuse;
const float fMatSpecularPower=0.8;
const float fLDotN=max(dot(vLightDir, vNormal), 0);
//-- Diffuse
float fDiffuseContrib = fLDotN;
//-- Specular
vec3 v3HalfVect=normalize(vEye+vLightDir);
float fSpecularContrib=pow(clamp(dot(v3HalfVect, vNormal), 0.0, 1.0), fMatSpecularPower);
vec3 vDiffuse=fDiffuseContrib*vMatDiffuse*vLightDiffuse;
vec3 vSpecular=fSpecularContrib*vMatSpecular*vLightSpecular;
vec3 vcFinal=vDiffuse+vSpecular;
outColor = vec4(vcFinal, 1);
//outColor = vec4(vNormal.xyz, 1);
//outColor = vec4(vEye.xyz, 1);
//outColor = vec4(vLightDir.xyz, 1);
//outColor = vec4(v3HalfVect.xyz, 1);
}