Jump to content
  • Advertisement
Sign in to follow this  

[glsl] spotlight problems

This topic is 2802 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a lot of trouble getting my per-pixel spotlight shader to work right. I've attached the code as well as a video demonstrating the problem. The little floating guy in the video represents the position and orientation of the light. As you can see, the problem is that the circle on the ground from the light is the wrong shape, and actually changes shape when I rotate the camera even though the light is never moved. This only happens when I rotate the camera, not when I simply translate it. I've verified that the normals of the ground's vertices are all [0,1,0] as they should be. The relevant values for the light are:

cone angle : 15,
rate of decay : 0,
constant attenuation : 1,
linear attenuation" : 0,
quadratic attenuation : 0

">video link

vertex shader:

#version 130

uniform mat4x4 projectionMatrix;
uniform mat4x4 modelViewMatrix;
uniform mat2x2 textureMatrix;
uniform vec4 globalAmbient;
uniform vec3 lightPosition; // in view space
uniform vec4 lightAmbient;
uniform vec4 lightDiffuse;
uniform vec4 materialAmbient;
uniform vec4 materialDiffuse;

in vec4 position;
in vec2 textureCoordinate;
in vec3 normal;

out vec2 vertexTextureCoordinate;
out vec3 vertexNormal;
out vec4 vertexGlobalAmbient;
out vec3 vertexLightDirection;
out vec3 vertexHalfVector;
out float vertexLightDistance;
out vec4 vertexAmbientColor;
out vec4 vertexDiffuseColor;

void main()
vertexNormal = mat3x3(modelViewMatrix) * normal; // We assume no non-uniform scaling here

// Compute the light direction
gl_Position = modelViewMatrix * position;
vec3 lightVector = lightPosition - gl_Position.xyz;
vertexLightDirection = normalize( lightVector );
vertexLightDistance = length( lightVector );
vertexHalfVector = normalize( vertexLightDirection + gl_Position.xyz );

// Compute ambient and diffuse colors
vertexGlobalAmbient = globalAmbient * materialAmbient;
vertexAmbientColor = materialAmbient * lightAmbient;
vertexDiffuseColor = materialDiffuse * lightDiffuse;

gl_Position = projectionMatrix * gl_Position;
vertexTextureCoordinate = textureMatrix * textureCoordinate;

fragment shader:

#version 130

uniform sampler2D texture;
uniform vec4 lightSpecular;
uniform float lightConstantAttenuation;
uniform float lightLinearAttenuation;
uniform float lightQuadraticAttenuation;
uniform vec3 lightDirection;
uniform float lightConeAngleCosine;
uniform uint lightRateOfDecay;
uniform vec4 materialSpecular;
uniform int materialShininess;

in vec2 vertexTextureCoordinate;
in vec3 vertexNormal;
in vec4 vertexGlobalAmbient;
in vec3 vertexLightDirection;
in vec3 vertexHalfVector;
in float vertexLightDistance;
in vec4 vertexAmbientColor;
in vec4 vertexDiffuseColor;

out vec4 fragmentColor;

void main()
fragmentColor = vertexGlobalAmbient;
vec3 normal = normalize( vertexNormal );

float normalDotLightDirection = max( dot( normal, normalize(vertexLightDirection) ), 0 );
if( normalDotLightDirection > 0 )
float spotEffect = dot( normalize(lightDirection), normalize(-vertexLightDirection) );
if( spotEffect > lightConeAngleCosine )
spotEffect = pow( spotEffect, lightRateOfDecay );

float attenuation = spotEffect / ( lightConstantAttenuation +
lightLinearAttenuation * vertexLightDistance +
lightQuadraticAttenuation * vertexLightDistance * vertexLightDistance );

fragmentColor += attenuation * ( vertexDiffuseColor * normalDotLightDirection + vertexAmbientColor );

vec3 halfVector = normalize( vertexHalfVector );
float normalDotHalfVector = max( dot(normal, halfVector), 0 );
fragmentColor += attenuation * materialSpecular * lightSpecular * pow( normalDotHalfVector, materialShininess );

vec4 texel = texture2D( texture, vertexTextureCoordinate );
fragmentColor *= texel;
fragmentColor.a = texel.a;

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!