2012-07-06 113 views
2

我想要两个光源:定向光源和聚光灯。我似乎无法得到我所做的错误 - 可能不了解着色器的工作原理!我得到的第一个光很好,但没有第二个(又名聚光灯)效果的迹象。这里是我想出了fragement着色器:OpenGL着色器:聚光灯和定向灯

varying vec4 diffuse,ambientGlobal, ambient; 
varying vec3 normal,lightDir,halfVector; 
varying float dist; 


void main() 
{ 
    vec3 n, halfV, viewV, ldir; 
    float NdotL, NdotHV; 
    vec4 color = ambientGlobal; 
    float att, spotEffect; 
    n = normalize(normal); 

    NdotL = max(dot(n,normalize(lightDir)),0.0); 

    if (NdotL > 0.0) { 

     att = 1.0/(gl_LightSource[0].constantAttenuation + 
       gl_LightSource[0].linearAttenuation * dist + 
       gl_LightSource[0].quadraticAttenuation * dist * dist); 
     color += att * (diffuse * NdotL + ambient); 

     halfV = normalize(halfVector); 
     NdotHV = max(dot(n,halfV),0.0); 
     color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess); 

     spotEffect = dot(normalize(gl_LightSource[1].spotDirection), normalize(-lightDir)); 
     if (spotEffect > gl_LightSource[1].spotCosCutoff) { 
      spotEffect = pow(spotEffect, gl_LightSource[1].spotExponent); 
      att = spotEffect/(gl_LightSource[1].constantAttenuation + 
        gl_LightSource[1].linearAttenuation * dist + 
        gl_LightSource[1].quadraticAttenuation * dist * dist); 

      color += att * (diffuse * NdotL + ambient); 


      halfV = normalize(halfVector); 
      NdotHV = max(dot(n,halfV),0.0); 
      color += att * gl_FrontMaterial.specular * gl_LightSource[1].specular * pow(NdotHV,gl_FrontMaterial.shininess); 
     } 

    } 

    gl_FragColor = color; 
} 

PS:这肯定是已经解决了....任何问题吗?

+0

您不需要使用任何类型的着色器来实现[点光源和聚光灯](http://www.opengl.org/archives/resources/faq/technical/lights.htm)。如果你仍然想使用着色器,[这看起来像一个有前途的教程](http://www.ozone3d.net/tutorials/glsl_lighting_phong.php)。 – Oskar 2012-07-09 18:32:17

+0

我需要每个像素着色,你不能用顶点着色 - 更新问题。令人遗憾的是,第二个链接(教程)指出将单个光源作为聚光灯,而不是将聚光灯添加到已经存在的着色器中。尽管如此,谢谢你的回答。 – Sardathrion 2012-07-10 07:12:43

+0

然后,您可以声明自己的灯而不使用OpenGL管道。用一个整数表示传递哪种类型的灯光。我很抱歉这个链接没有多大用处。 – Oskar 2012-07-10 08:50:37

回答

4

这里是我想出了:

顶点着色器:

varying vec3 N; 
varying vec3 v; 
void main(void) 
{  
    v = vec3(gl_ModelViewMatrix * gl_Vertex);  
    N = normalize(gl_NormalMatrix * gl_Normal); 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

而片段着色器:

varying vec3 N; 
varying vec3 v; 
#define MAX_LIGHTS 2 
void main (void) 
{ 
    vec4 finalColour; 

    for (int i=0; i<MAX_LIGHTS; i++) 
    { 
     vec3 L = normalize(gl_LightSource[i].position.xyz - v); 
     vec3 E = normalize(-v); 
     vec3 R = normalize(-reflect(L,N)); 
     vec4 Iamb = gl_FrontLightProduct[i].ambient;  
     vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0); 
     Idiff = clamp(Idiff, 0.0, 1.0);  
     vec4 Ispec = gl_FrontLightProduct[i].specular 
        * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); 
     Ispec = clamp(Ispec, 0.0, 1.0); 
     finalColour += Iamb + Idiff + Ispec; 
    } 
    gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColour; 
} 

这给这一形象:

enter image description here