我试图为动画多维数据集添加一些基本的灯光效果,但由于某种原因它只显示一个空白的彩色窗口。我在找到问题时完全迷失了方向。在添加照明之前,代码工作正常。我找到问题的第一件事是添加
gl_FragColor = vec4(1.0,1.0,0.0,1.0);
到片段着色器的末尾,以避免可能出错的所有光照计算。但它只是改变了窗口中显示的颜色。我不确定这个问题是由于相机设置还是计算法线或其他因素造成的。这是我用来加载多维数据集的obj文件数据:
v -1.0 -1.0 1.0
v 1.0 -1.0 1.0
v 1.0 1.0 1.0
v -1.0 1.0 1.0
v -1.0 -1.0 -1.0
v 1.0 -1.0 -1.0
v 1.0 1.0 -1.0
v -1.0 1.0 -1.0
vn 0.577350 0.577350 -0.577350
vn 0.577350 -0.577350 -0.577350
vn -0.577350 -0.577350 -0.577350
vn -0.577350 0.577350 -0.577350
vn 0.577350 0.577350 0.577350
vn 0.577350 -0.577350 0.577350
vn -0.577350 -0.577350 0.577350
vn -0.577350 0.577350 0.577350
f 0 1 2
f 2 3 0
f 1 5 6
f 6 2 1
f 7 6 5
f 5 4 7
f 4 0 3
f 3 7 4
f 4 5 1
f 1 0 4
f 3 2 6
f 6 7 3
这是相机设置和矩阵计算:
float move = -4.0f;// sinf(SDL_GetTicks() / 1000.0 * (2 * 3.14) / 5); // -1<->+1 every 5 seconds
float angle = 0.0;// SDL_GetTicks() / 1000.0 * 45; // 45° per second
glm::vec3 axis_y(0, 1, 0);
glm::mat4 translation = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, move));
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(angle), axis_y);
glm::mat4 scaling = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f, 1.0f, 1.0f));
glm::mat4 model = translation * rotation * scaling;
glm::mat4 view = glm::lookAt(glm::vec3(0.0, 2.0, 0.0), glm::vec3(0.0, 0.0, -4.0), glm::vec3(0.0, 1.0, 0.0));
glm::mat4 projection = glm::perspective(45.0f, 1.0f*screen_width / screen_height, 0.1f, 10.0f);
glm::mat4 mvp = projection * view * model;
glm::mat4 mv = view * model;
glm::mat4 normalMatrix = glm::transpose(glm::inverse(mv));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mv));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(normalMatrix));
并且顶点着色器包括:
gl_Position = mvp * vec4(position,fade);
我已经按如下方式定义了照明属性:
float shininess = 5.0f;
glm::vec3 lightDirection = glm::vec3(0.0f, 1.0f, 2.0f);
glm::vec4 lightAmbient = glm::vec4(1, 0.83, 0.75, 1.0f);
glm::vec4 lightDiffuse = glm::vec4(1.0f, 1.0f, 0.4f, 1.0f);
glm::vec4 lightSpecular = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
glm::vec4 materialAmbient = glm::vec4(1, 0.83, 0.75, 1.0f);
glm::vec4 materialDiffuse = glm::vec4(1.0f, 1.0f, 0.4f, 1.0f);
glm::vec4 materialSpecular = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
glUniform1f(uniform_shininess, shininess);
glUniform3fv(uniform_lightDirection, 1, glm::value_ptr(lightDirection));
glUniform4fv(uniform_lightAmbient, 1, glm::value_ptr(lightAmbient));
glUniform4fv(uniform_lightDiffuse, 1, glm::value_ptr(lightDiffuse));
glUniform4fv(uniform_lightSpecular, 1, glm::value_ptr(lightSpecular));
glUniform4fv(uniform_materialAmbient, 1, glm::value_ptr(materialAmbient));
glUniform4fv(uniform_materialDiffuse, 1, glm::value_ptr(materialDiffuse));
glUniform4fv(uniform_materialSpecular, 1, glm::value_ptr(materialSpecular));
和片段着色器是:
uniform float shininess;
uniform vec3 lightDirection;
uniform vec4 lightAmbient;
uniform vec4 lightDiffuse;
uniform vec4 lightSpecular;
uniform vec4 materialAmbient;
uniform vec4 materialDiffuse;
uniform vec4 materialSpecular;
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void){
vec4 Ia = lightAmbient * materialAmbient;
vec4 Id = vec4(0.0,0.0,0.0,1.0);
vec4 Is = vec4(0.0,0.0,0.0,1.0);
vec3 L = normalize(lightDirection);
vec3 N = normalize(vNormal);
float lambertTerm = dot(N,-L);
if(lambertTerm > 0.0){
Id = lightDiffuse * materialDiffuse * lambertTerm;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(L, N);
float specular = pow( max(dot(R, E), 0.0), shininess);
Is = lightSpecular * materialSpecular * specular;
}
vec4 finalColor = Ia + Id + Is;
finalColor.a = 1.0;
gl_FragColor = finalColor;
//gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
这两个变化来自顶点着色器:
vNormal = vec3(normalMatrix * vec4(normals, 1.0));
vec4 vertex = mv * vec4(positions, 1.0);
vEyeVec = -vec3(vertex.xyz);
我猜测的是,如果法线和光照计算出错,那么片段着色器中的最后一行gl_FragColor = vec4(1.0,1.0,0.0,1.0);应该取消它们。但是,这没有任何帮助。我尝试了不同的相机位置,但这并没有任何区别。