# GLSL Directional Light

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

## Recommended Posts

Hello,
I'm trying to setup a basic directional light that matches the fixed pipeline.

However, my GLSL version looks like a point light, with very dark edges.
Ambient is zero, specular is zero, and attenuation is off, so it doesn't interfere.

How can I match the same shading as seen in the fixed version?

//////////////////////////////////////////

varying vec3 N;
varying vec3 L;

void main()
{
N = normalize(gl_NormalMatrix * gl_Normal);
L = normalize(gl_LightSource[0].position.xyz);	// directional light

gl_Position = ftransform();
}

//////////////////////////////////////////

varying vec3 N;
varying vec3 L;

void main()
{
N = normalize(N);
L = normalize(L);

float lamb = max( dot(N,L), 0.0 );

vec4 diffuseColor = vec4(1,1,1,1);
gl_FragColor = lamb * diffuseColor;
}


##### Share on other sites

#1: Don’t normalize the light/normal in the vertex shader if you are going to renormalize them in the pixel shader.  Think about where each needs to be normalized and only normalize them there.

Normalize the light vector in the vertex shader since it does not change across the face of the triangle.

The normal will not be normalized across the face of the triangle even if you normalize it in the vertex shader, so only normalize it in the pixel shader.

#2: You are using per-pixel shading while they are using vertex shading.

If you want their result (which you shouldn’t), then perform lighting in the vertex shader, not the pixel shader.  The pixel shader simply outputs the result as the final color.

L. Spiro

##### Share on other sites

Thanks, that was it!

>>Don’t normalize the light/normal in the vertex shader if you are going to renormalize them in the pixel shader.

No problem. I read somewhere that these "varying" variables get interpolated when getting passed around, so I have no idea if there are still normalized or not.

///////////////////////////////////////////////////////////////////

varying vec4 fragColor;

void main()
{
vec3 N = normalize(gl_NormalMatrix * gl_Normal);
vec3 L = normalize(gl_LightSource[0].position.xyz);	// directional light

//////////////////////////////////

float lamb = max( dot(N,L), 0.0 );
vec4 diffuseColor = vec4(1,1,1,1);
fragColor = lamb * diffuseColor;

//////////////////////////////////

gl_Position = ftransform();
}

///////////////////////////////////////////////////////////////////

varying vec4 fragColor;

void main()
{
gl_FragColor = fragColor;
}


##### Share on other sites

so I have no idea if there are still normalized or not.

Think about the result of linearly interpolating between 2 points.
Even if the 2 points are normalized at the start, the points between them will only still be normalized if the start and end point are the same.
Interpolate mentally between these 2 normals:
\   /
\ /
º
Going directly across from one to the other, you can mentally see that the points on the line segment you draw are not unit-length.

The light direction, on the other hand, doesn’t change, so it is the same as interpolating from one point to the same point. So if that point is normalized it will stay normalized. Hence it can be done once in the vertex shader.

L. Spiro

##### Share on other sites

you should also normalize the normal on the vertex shader otherwise you're giving the normal with a greater length an unwanted weight in interpolation

Edited by IYP

##### Share on other sites
If the normals are of unit length on input, multiplication with gl_NormalMatrix (which is deprecated) will result in normals of some consistent ratio.
Meaning in most cases all normals will still be 1 length long, but may all be 0.5 long, etc.
In other words, as long as the normals are the same length in input they will be the same length after gl_NormalMatrix.

L. Spiro

##### Share on other sites
Thanks, this works great for my purposes, but the only downside to doing calculations in the vertex shader, is that I can't use the texture2D sampler anymore. That must be done in the fragment shader, per pixel.

##### Share on other sites

as L. Spiro said you'd really want to do shading on fragment shader for smooth and per fragment shading I don't really see a reason not to do that. and your shading being different from fixed pipe line doesn't mean you're doing it wrong it means fixed pipe line is doing it wrong

Edited by IYP

##### Share on other sites

Thanks, this works great for my purposes, but the only downside to doing calculations in the vertex shader, is that I can't use the texture2D sampler anymore. That must be done in the fragment shader, per pixel.

well i dont know modern glsl but what i know is that you can use sampler2D in a vertex shader.

Another thing you can even make a texture projection where texture is a single circle (filled with a color) and project it onto a scene works exactly as directional light

##### Share on other sites

To get this working with texture coords, I have to pass the lighting factor as a vector, like vec4.
Passing it as a single float to the fragment shader always fails. The float is always zero.

Is this a problem with the GLSL version or somewhere else?

///////////////////////////////////////////////////////////////////

varying float lamb;
varying vec4 diffuseColor;

void main()
{
vec3 N = normalize(gl_NormalMatrix * gl_Normal);
vec3 L = normalize(gl_LightSource[0].position.xyz);	// directional light

float lamb = max( dot(N,L), 0.0 );
diffuseColor = lamb * vec4(1,1,1,1);

//////////////////////////////////

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

///////////////////////////////////////////////////////////////////

uniform sampler2D diffuseMap;
varying float lamb;
varying vec4 diffuseColor;

void main()
{
// fails
//gl_FragColor = lamb * texture2D(diffuseMap, gl_TexCoord[0].st);

// works
gl_FragColor = diffuseColor * texture2D(diffuseMap, gl_TexCoord[0].st);
}


1. 1
Rutin
19
2. 2
3. 3
JoeJ
16
4. 4
5. 5

• 27
• 20
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631700
• Total Posts
3001790
×