# GLSL light with correct specular calculation?

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

## Recommended Posts

I have writed this shader. I have got a bunch of examples in the internet and every shader that I test, got strange effects in the specular reflection. So I post here my code: vertshader
varying vec3 normal;
varying vec4 ecPosition;

void main()
{
normal = gl_NormalMatrix * gl_Normal;

//eye coordinate position
ecPosition = gl_ModelViewMatrix * gl_Vertex;

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}


varying vec3 normal;
varying vec4 ecPosition;

sampler2D tex;

void main()
{
float dist; //dist = distance between eye and light position
vec3 aux, L, n, V, R, s; /*L = light vector direction(to the light position),
n = normal,
V = viewer vector,
R = reflection vector,
s = L+V normalized.
*/

//Precalculate some needed variables
n = normalize(normal);
aux = vec3(gl_LightSource[0].position - ecPosition);
dist = length(aux);
L = normalize(aux);
V = vec3(normalize(-ecPosition));
//R = normalize(-reflect(L, n)); //????
s = normalize( L + V );

//vec4 pixelFinalColor = vec4(1.0, 1.0, 1.0, 1.0);
vec4 pixelFinalColor = gl_FrontMaterial.emission +//emission light +
(gl_LightModel.ambient * gl_FrontMaterial.ambient);//global ambient light

float Ldotn = max( dot( L, n ), 0.0 );
if ( Ldotn > 0.0 ){ //Illuminate only the pixels than can be illuminated
vec4 specularterm = pow( max( dot( s, n ), 0.0 ), gl_FrontMaterial.shininess ) * gl_FrontLightProduct[0].specular;
vec4 diffuseterm = Ldotn * gl_FrontLightProduct[0].diffuse;
vec4 ambientterm = gl_FrontLightProduct[0].ambient;
//vec4 spotlighteffect = 1.0;
float attenuationfactor = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
vec4 contribution = attenuationfactor * /*spotlight effect **/ (ambientterm + diffuseterm + specularterm);

pixelFinalColor[3] = gl_FrontMaterial.diffuse[3];//????
//pixelFinalColor += contribution;
pixelFinalColor += clamp(contribution, 0.0, 0.1);
}
vec4 texcolor = texture2D(tex,gl_TexCoord[0].st);

gl_FragColor = pixelFinalColor * texcolor;
}


What I am doing wrong?

##### Share on other sites
I recognize that shader.. I found it to be full of crazy stuff that was more problematic than supporting, and after a few words of wisdom from the good folks here, I ditched the shader completely.

I do not, however, recognize any specular error. I had other problems, like the light becoming dimmer as I looked away from it, and it seemed to move whenever I moved, but those were simple problems I solved by updating the light's position every frame as well as defining a mesh's material properties (specular, diffuse, ambient and shininess) on each frame.

##### Share on other sites
Can you post a screenshot with those "strange effects"?

BTW. That fragment shader is much too complicated. It's slow as hell. I suggest writing a new one.

##### Share on other sites
Like this one:

but I managed to fix this. Was the clamp that I do not put before.

Well, everything is almost working now, exept for one detail that I figured just before: If I try to illuminate a object that is not textured, I get a specular of grey :>

but it to work like this one :>

hum, how can I multiply correctly the texcolor in the fragshader?

	//Precalculate some needed variables	n = normalize(normal);	aux = vec3(gl_LightSource[0].position - ecPosition);	dist = length(aux);	L = normalize(aux);	V = vec3(normalize(-ecPosition));	//R = normalize(-reflect(L, n));	s = normalize( L + V );		//vec4 pixelFinalColor = vec4(1.0, 1.0, 1.0, 1.0);	vec4 pixelFinalColor = gl_FrontMaterial.emission +//emission light +			(gl_LightModel.ambient * gl_FrontMaterial.ambient);//global ambient light		float Ldotn = max( dot( L, n ), 0.0 );	if ( Ldotn > 0.0 ){ //Illuminate only the pixels than can be illuminated		vec4 specularterm = pow( max( dot( s, n ), 0.0 ), gl_FrontMaterial.shininess ) * gl_FrontLightProduct[0].specular;		vec4 diffuseterm = Ldotn * gl_FrontLightProduct[0].diffuse;		vec4 ambientterm = gl_FrontLightProduct[0].ambient;		//vec4 spotlighteffect = 1.0;		float attenuationfactor = 1.0 / (gl_LightSource[0].constantAttenuation +				gl_LightSource[0].linearAttenuation * dist +				gl_LightSource[0].quadraticAttenuation * dist * dist);		vec4 contribution = attenuationfactor * /*spotlight effect **/ (ambientterm + diffuseterm + specularterm);				pixelFinalColor[3] = gl_FrontMaterial.diffuse[3];//????		pixelFinalColor += clamp(contribution, 0.0, 1.0);	}	vec4 texcolor = texture2D(tex,gl_TexCoord[0].st);		gl_FragColor = pixelFinalColor * texcolor;}

##### Share on other sites
There's an error in the lighting equation. Specular term should not be multiplied by the texture color. Right now you're doing Gouraud shading but you should be doing Phong shading. Try adding the specular term to the resulting color. Also I don't know why you're doing
pixelFinalColor[3] = gl_FrontMaterial.diffuse[3];

Try chagning
vec4 contribution = attenuationfactor * /*spotlight effect **/ (ambientterm + diffuseterm + specularterm);

to:
vec4 contribution = attenuationfactor * /*spotlight effect **/ (ambientterm + diffuseterm);

And:
gl_FragColor = pixelFinalColor * texcolor;

to:
gl_FragColor = pixelFinalColor * texcolor + specularterm;

##### Share on other sites
hehehe worked very well. Thanks :D
Well, I do "pixelFinalColor[3] = gl_FrontMaterial.diffuse[3];" cause red book says so.
Or I'm confusing something?
Tomorrow I post the line where the book says this is done.

##### Share on other sites
@ Tsumuji & Lord Faron
the reason for the "pixelFinalColor[3] = gl_FrontMaterial.diffuse[3];" is because you dont want to modulate the alpha channel of the material by lighting, however that line should come right before (from what i can see) "gl_FragColor = pixelFinalColor * texcolor;"

##### Share on other sites
The book says in page 221 at the end of the 2nd paragraph: "...(Remeber that the final A or alpha component at a vertex is equal to the material's diffuse alpha value at that vertex.)".

I don't know if I put tis line where it is, or as you said Exorcist, but this must be done rifght?

And Lord Faron, where can I better the performance of this shader? I can't see how can I get better results since I want a per-pixel effect...

1. 1
2. 2
JoeJ
20
3. 3
frob
17
4. 4
5. 5

• 10
• 10
• 12
• 13
• 9
• ### Forum Statistics

• Total Topics
632197
• Total Posts
3004729

×