我的着色器有一點問題。Opengl-glsl單一虛擬光線
頂點
varying vec3 normal, lightDir, eyeVec, spotDir;
varying mat4 viewMat;
uniform vec4 posluce; \\this is light position
uniform mat4 matrix;
uniform vec3 spotdir;
void main(){
viewMat = inverse(matrix);
vec3 posLuceWorld = (posluce*viewMat).xyz;
spotDir = normalize(vec3(vec4(spotdir,0)*viewMat));
normal = gl_NormalMatrix * gl_Normal;
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
lightDir = normalize(posLuceWorld.xyz - (gl_Vertex * viewMat).xyz);
eyeVec = normalize(-vVertex);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
片段
varying vec3 normal, lightDir, eyeVec,spotDir;
varying mat4 viewMat;
const float cos_outer_cone_angle = 0.8; // 36 degrees
void main (void){
vec4 amb = vec4(0.1, 0.1, 0.1, 1.0);
vec4 diff = vec4(0.52, 0.81, 0.98, 1.0);
vec4 spec = vec4(0.52, 0.81, 0.98, 1.0);
float exp = 2.5f;
float cutoff = 25.0f;
float cosCut = cos(cutoff);
vec4 final_color =
(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
(amb * gl_FrontMaterial.ambient);
vec3 L = lightDir;
vec3 D = spotDir;
float cos_cur_angle = dot(-L, D);
float cos_inner_cone_angle = cosCut;
float cos_inner_minus_outer_angle =
cos_inner_cone_angle - cos_outer_cone_angle;
float spot = 0.0;
spot = clamp((cos_cur_angle - cos_outer_cone_angle)/
cos_inner_minus_outer_angle, 0.0, 1.0);
vec3 N = normalize(normal);
float lambertTerm = max(dot(N,L), 0.0);
if(lambertTerm > 0.0){
final_color += diff *
exp *
gl_FrontMaterial.diffuse *
lambertTerm * spot;
vec3 E = eyeVec;
vec3 R = reflect(-L, N);
float specular = pow(max(dot(R, E), 0.0),
gl_FrontMaterial.shininess);
final_color += spec *
gl_FrontMaterial.specular *
specular * spot;
}
gl_FragColor = final_color;
}
我的顯示功能:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Setting camera using orthonormal frame manipulation
Matrix4x4 m;
//Change view with mouse
buildRotationMatrix(camera.frame.Yaxis, deg2rad(-yrot), m);
transform(m, camera.frame.Xaxis);
transform(m, camera.frame.Yaxis);
transform(m, camera.frame.Zaxis);
//i traslate myself with the Keyborad
if (up_key){
camera.position.x += -camera.frame.Zaxis.x * speed;
camera.position.y += -camera.frame.Zaxis.y * speed;
camera.position.z += -camera.frame.Zaxis.z * speed;
}
if (down_key){
camera.position.x += camera.frame.Zaxis.x * speed;
camera.position.y += camera.frame.Zaxis.y * speed;
camera.position.z += camera.frame.Zaxis.z * speed;
}
if (left_key){
camera.position.x += -camera.frame.Xaxis.x * speed;
camera.position.y += -camera.frame.Xaxis.y * speed;
camera.position.z += -camera.frame.Xaxis.z * speed;
}
if (right_key){
camera.position.x += camera.frame.Xaxis.x * speed;
camera.position.y += camera.frame.Xaxis.y * speed;
camera.position.z += camera.frame.Xaxis.z * speed;
}
pitch-=xrot*0.5; // change view speed
if (pitch>90) pitch=90;
if (pitch<-90) pitch=-90;
Camera temp(camera);
Matrix4x4 m2;
buildRotationMatrix(temp.frame.Xaxis, deg2rad(pitch), m2);
transform(m2, temp.frame.Xaxis);
transform(m2, temp.frame.Yaxis);
transform(m2, temp.frame.Zaxis);
Matrix4x4 c;
buildCameraMatrix(temp,c);
glMultMatrixf(c.GL_array());
if(mouse_moved){
mouse_moved=false;// this force my mouse in center
glutWarpPointer(width/2, height/2);
}
xrot=yrot=0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble ratio = static_cast<GLdouble>(width)/static_cast<GLdouble>(height);
gluPerspective(45, //angolo di visuale
ratio, //aspect ratio (rapporto tra larghezza e altezza)
1, //Z near cutting plane
1000); //Z far cutting plane
glMatrixMode(GL_MODELVIEW);
glUseProgram(ShaderProgram);
GLint matrixR = glGetUniformLocation(ShaderProgram, "matrix");
glUniformMatrix4fv(matrixR, 1, GL_FALSE, c.GL_array());
GLint spot = glGetUniformLocation(ShaderProgram, "spotdir");
float spotdirr[3] = {0.0, -1.0, 1.0};
glUniform3fv(spot,1,spotdirr);
GLint pos = glGetUniformLocation(ShaderProgram, "posluce");
float light0_position[4] = {-0.17252*scale, 0.73089*scale, -0.52868*scale, 1};
glUniform4fv(pos,1,light0_position);
glPushMatrix();
creaPavimento(); \\this create my floor
glPopMatrix();
glPushMatrix();
GLfloat front_mat_diffuse[] = {0.25, 0.4, 0.98, 1.0};
GLfloat front_mat_spec[] = {0.4, 0.4, 0.4, 1.0};
GLfloat front_mat_ambi[] = {0.25, 0.25, 0.25, 1.0};
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_spec);
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, front_mat_ambi);
GLfloat mShininess[] = {2};
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
glTranslatef(0.0,1.0,6.0);
glutSolidSphere(0.5, 20, 20);
glPopMatrix();
glFlush();
glutSwapBuffers();
當我用這個shader我得到的光不會照亮我的樓,但只有一個球我問題:爲什麼?怎麼了? 如果我使用OPENGL標準燈工作得很好。
我無法發佈圖片。 對不起,我英文很差。
編輯:
我改了一下着色器。 現在適用於地面和球體,但球體適合地面時,截止點完全錯誤,方向不對。
頂點:
varying vec3 normal, lightDir, eyeVec, spotDirection;
varying mat4 viewMat;
uniform vec4 posluce;
uniform mat4 matrix;
uniform vec3 spotdir;
void main(){
viewMat = inverse(matrix);
spotDirection = normalize(vec3(vec4(spotdir,0.0)*viewMat));
vec3 lightPosition = (posluce * viewMat).xyz;
normal = gl_NormalMatrix * gl_Normal;
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
lightDir = normalize((gl_Vertex * viewMat).xyz + lightPosition);
eyeVec = -vVertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
這是新片段:
varying vec3 normal, lightDir, eyeVec,spotDirection;
varying mat4 viewMat;
const float cos_outer_cone_angle = 0.8; // 36 degrees
void main (void){
vec4 amb = vec4(0.1, 0.1, 0.1, 1.0);
vec4 diff = vec4(0.52, 0.81, 0.98, 1.0);
vec4 spec = vec4(0.52, 0.81, 0.98, 1.0);
float exp = 2.5f;
float cutoff = 25.0f;
float cosCut = cos(cutoff);
vec4 final_color =
(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
(amb * gl_FrontMaterial.ambient);
vec3 L = normalize(lightDir);
vec3 D = normalize(spotDirection);
float cos_cur_angle = dot(-L, D);
float cos_inner_cone_angle = cosCut;
float cos_inner_minus_outer_angle =
cos_inner_cone_angle - cos_outer_cone_angle;
float spot = 0.0;
spot = clamp((cos_cur_angle - cos_outer_cone_angle)/
cos_inner_minus_outer_angle, 0.0, 1.0);
vec3 N = normalize(normal);
float lambertTerm = max(dot(N,L), 0.0);
if(lambertTerm > 0.0){
final_color += diff *
exp *
gl_FrontMaterial.diffuse *
lambertTerm * spot;
vec3 E = normalize(eyeVec);
vec3 R = reflect(-L, N);
float specular = pow(max(dot(R, E), 0.0),
gl_FrontMaterial.shininess);
final_color += spec *
gl_FrontMaterial.specular *
specular * spot;
}
gl_FragColor = final_color;
}
** 1。**着色器是否對地板和球體都有效? ** 2。**地板的法線是否正確? – Angew
1.是的,我在顯示功能中激活了着色器,並且在創建了floor和sphere之後。 2.我使用glutsolidcube和glutsolidsphere創建地板和球體 – user2747630
...並且地板由立方體外部形成,對吧?也許你可以發佈相關的C++代碼。 – Angew