OpenGL shader: a spotlight and a directional light

匿名 (未验证) 提交于 2019-12-03 09:02:45

问题:

I want to have two light sources: a directional one and a spotlight. I cannot seem to get what I am doing wrong -- probably not understanding how shaders work! I get the first light fine but no sign of the effects of the second one (aka spotlight). Here is the fragement shader that I came up with:

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: Surely this is a problem that has been solved.... Anyone?

回答1:

Here is what I came up with:

The vertex shader:

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;   } 

And the fragment shader:

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; } 

Which give this image:



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!