我正在尝试将this tutorial用于每片段着色并使其适应GLSL #version 140.我得到的结果显然不正确。在我看来,我对所提供的法线做错了,因为在同一平面上彼此相邻的一些三角形上的明暗之间存在直接的变化。
顶点着色器代码:
#version 140
in vec3 position;
in vec2 texIn;
in vec3 normal;
smooth out vec2 texCoor;
out vec4 v_position; // position of the vertex (and fragment) in world space
out vec3 NormalDirection; // surface normal vector in world space
uniform mat4 mP, mV, mM; // transformation matrices
uniform mat3 m_3x3_inv_transp;
void main() {
v_position = mM * vec4(position, 1.0);
NormalDirection = normalize(m_3x3_inv_transp * normal);
mat4 mvp = mP*mV*mM;
gl_Position = mvp * vec4(position, 1.0);
texCoor = texIn;
}
片段着色器:
#version 140
uniform mat4 mM, mV, mP;
uniform mat4 mV_inv;
uniform sampler2D texSampler; // sampler for texture access
smooth in vec2 texCoor; // from Vertex shader
in vec4 v_position; // position of the vertex (and fragment) in world space
in vec3 NormalDirection; // surface normal vector in world space
out vec4 colorOut; // fragment color
struct lightSource {
vec4 position;
vec4 diffuse;
vec4 specular;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
vec3 spotDirection;
};
lightSource light0 = lightSource(
vec4(5.0, 5.0, 5.0, 1.0),
vec4(2.0, 2.0, 2.0, 1.0),
vec4(2.0, 2.0, 2.0, 1.0),
0.0, 1.0, 0.0,
180.0, 0.0,
vec3(0.0, 0.0, 0.0)
);
vec4 scene_ambient = vec4(1.2, 1.2, 1.2, 1.0);
struct material {
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
material frontMaterial = material(
vec4(0.2, 0.2, 0.2, 1.0),
vec4(1.0, 0.8, 0.8, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
5.0
);
void main() {
vec3 normalDirection = normalize(NormalDirection);
vec3 viewDirection = normalize(vec3(mV_inv * vec4(0.0, 0.0, 0.0, 1.0) - v_position));
vec3 lightDirection;
float attenuation;
if (0.0 == light0.position.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(light0.position));
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(light0.position - v_position);
float distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (light0.constantAttenuation
+ light0.linearAttenuation * distance
+ light0.quadraticAttenuation * distance * distance);
if (light0.spotCutoff <= 90.0) // spotlight?
{
float clampedCosine = max(0.0, dot(-lightDirection, light0.spotDirection));
if (clampedCosine < cos(radians(light0.spotCutoff))) // outside of spotlight cone?
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, light0.spotExponent);
}
}
}
vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);
vec3 diffuseReflection = attenuation
* vec3(light0.diffuse) * vec3(frontMaterial.diffuse)
* max(0.0, dot(normalDirection, lightDirection));
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(light0.specular) * vec3(frontMaterial.specular)
* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), frontMaterial.shininess);
}
colorOut = vec4(ambientLighting + diffuseReflection + specularReflection, 1.0) * texture(texSampler, texCoor);
}
C ++代码(制服):
// matrices to vertex shader
glm::mat4 modelMatrix = glm::mat4(1.0); // identity matrix - table is static
glUniformMatrix4fv(locations.Mmatrix, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniformMatrix4fv(locations.Pmatrix, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(locations.Vmatrix, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glm::mat3 m_inv_transp = glm::transpose(glm::inverse(glm::mat3(modelMatrix)));
glUniformMatrix3fv(locations.m_3x3_inv_transp, 1, GL_FALSE, glm::value_ptr(m_inv_transp));
glm::mat3 v_inv = glm::inverse(glm::mat3(viewMatrix));
glUniformMatrix4fv(locations.Vmatrix_inv, 1, GL_FALSE, glm::value_ptr(v_inv));