1
我目前有一个任务是在openGL/GLSL中实现Phong照明模型。下面是我正在使用的两个着色器。问题是在片段着色器中,如果我没有将vColor
添加到gl_FragColor
那么整个形状都是黑色的。但是,如果我添加vColor
,那么整个形状就是那种根本没有光照的颜色。我一直试图解决这个问题几个小时,现在没有运气。这是什么原因?这是在我的着色器的问题,或者在OpenGL代码中的问题?我正在使用一种材质和一种点光源,我将在着色器后显示这些光源。Phong照明模型实际上并没有照亮任何东西
编辑:如果我设置gl_FragColor = vec4(N, 1.0)
那么物体看起来是这样的:
顶点着色器:
#version 150
in vec4 vPosition;
in vec3 vNormal;
uniform mat4 vMatrix;
uniform vec4 LightPosition;
out vec3 fNorm;
out vec3 fEye;
out vec3 fLight;
void main() {
fNorm = vNormal;
fEye = vPosition.xyz;
fLight = LightPosition.xyz;
if(LightPosition.w != 0.0) {
fLight = LightPosition.xyz - vPosition.xyz;
}
gl_Position = vMatrix * vPosition;
}
片段着色器:
#version 150
in vec3 fNorm;
in vec3 fLight;
in vec3 fEye;
uniform vec4 vColor;
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform mat4 vMatrix;
uniform vec4 LightPosition;
uniform float Shininess;
void main(){
vec3 N = normalize(fNorm);
vec3 E = normalize(fEye);
vec3 L = normalize(fLight);
vec3 H = normalize(L + E);
vec4 ambient = AmbientProduct;
float Kd = max(dot(L, N), 0.0);
vec4 diffuse = Kd * DiffuseProduct;
float Ks = pow(max(dot(N, H), 0.0), Shininess);
vec4 specular = Ks * SpecularProduct;
if(dot(L,N) < 0.0)
specular = vec4(0.0, 0.0, 0.0, 1.0);
gl_FragColor = vColor + ambient + diffuse + specular;
}
设置材料和光:
void init() {
setMaterials(vec4(1.0, 0.0, 0.0, 0.0), //ambient
vec4(1.0, 0.8, 0.0, 1.0), //diffuse
vec4(1.0, 1.0, 1.0, 1.0), //specular
100.0); //shine
setLightSource(vec4(1.0, 0.0, 0.0, 1.0), //ambient
vec4(1.0, 0.0, 0.0, 1.0), //diffuse
vec4(1.0, 0.0, 0.0, 1.0), //specular
vec4(1.0, 2.0, 3.0, 1.0)); //position
setProducts();
....
}
/*
* Sets the material properties for Phong lighting model.
*/
void setMaterials(vec4 amb, vec4 dif, vec4 spec, GLfloat s) {
ambient = amb;
diffuse = dif;
specular = spec;
shine = s;
glUniform1f(vShininess, shine);
}
/*
* Set light source properties.
*/
void setLightSource(vec4 amb, vec4 dif, vec4 spec, vec4 pos) {
ambient0 = amb;
diffuse0 = dif;
specular0 = spec;
light0_pos = pos;
glUniform4fv(vLightPosition, 1, light0_pos);
}
/*
* Find the products of materials components and light components.
*/
void setProducts(){
vec4 ambientProduct = ambient * ambient0;
vec4 diffuseProduct = diffuse * diffuse0;
vec4 specularProduct = specular * specular0;
glUniform4fv(vAmbientProduct, 1, ambientProduct);
glUniform4fv(vDiffuseProduct, 1, diffuseProduct);
glUniform4fv(vSpecularProduct, 1, specularProduct);
}
编辑后,似乎很清楚,法线似乎是错误的。你有没有尝试过在很简单的东西上使用着色器,就像平面上的法线刚刚朝上或者其中一个过剩基元一样? – PeterT
您需要开始通过可能性进行调试。首先,通过将这些直接写入屏幕,确保您的照明制服正确地通过。像'gl_FragColor = ambient'等等。然后通过将这些颜色写入颜色值来确保获得的法线是合理的。然后,通过写这个来看看点(N,L)是什么。等等,直到你找到停止合理的部分。 –