2013-12-23 52 views
1

我的着色器有一點問題。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;              
} 
+0

** 1。**着色器是否對地板和球體都有效? ** 2。**地板的法線是否正確? – Angew

+0

1.是的,我在顯示功能中激活了着色器,並且在創建了floor和sphere之後。 2.我使用glutsolidcube和glutsolidsphere創建地板和球體 – user2747630

+0

...並且地板由立方體外部形成,對吧?也許你可以發佈相關的C++代碼。 – Angew

回答

0

如果我理解你的代碼&的意見正確,球,燈和照相機所在的立方體內。這意味着立方體的法線向外(您正在查看其背面),因此點積dot(N,L)爲負值,這使得lambert_term等於0。這反過來導致整個照明計算被跳過。

您有兩種選擇。請將着色器修改爲照亮背面以及正面,或者正確地面向法線渲染立方體。

+0

我爲您翻譯我的意見!但是奇怪的是因爲立方體正面在球體下面。當我使用opengl燈的結果是正確的... – user2747630

+0

@ user2747630我的意思是在這裏評論這裏,沒有代碼的人。事實上,它與OpenGL照明很好地工作是非常重要的,您應該將其添加到問題。 – Angew

+0

好吧,對不起,我忘了這件事......我已經把它添加到這個問題。 – user2747630