# per pixel lighting creating irregular shape?

## Recommended Posts

slicer4ever    6760
hello everyone, i'm trying to implement per-pixel lighting for a simple scene, however, what i expect to be a circlular pattern around the light(the small green dot in the image), is instead looks like an irregular shaped diamond:

[img]http://i46.tinypic.com/21mtctf.png[/img]

[code]
#version 150
struct Light{
vec3 m_Position;
vec4 m_Diffuse;
vec4 m_Ambient;
vec3 m_Attenen;
};
uniform mat4 ProjMatrix;
uniform mat4 ViewMatrix;
uniform mat4 MeshMatrix;
uniform Light Lights[1];

in vec3 i_Vertex;
in vec2 i_TexCoord;
in vec3 i_Normal;

out vec2 o_TexCoord;
out vec3 o_Normal, o_LightDir;
out float o_Distance;

void main(void){
mat4 ViewModel = ViewMatrix*MeshMatrix;
mat3 NormMatrix = transpose(inverse(mat3(ViewModel)));
o_Normal = normalize(NormMatrix*i_Normal);
vec4 v_Vertex = ViewModel*vec4(i_Vertex, 1.0f);
vec3 Aux = (ViewMatrix*vec4(Lights[0].m_Position,1.0f)).xyz-v_Vertex.xyz;
o_LightDir = normalize(Aux);
o_Distance = length(Aux);

o_TexCoord = i_TexCoord;
gl_Position = ProjMatrix*v_Vertex;
return;
}
[/code]

[code]
#version 150
struct Light{
vec3 m_Position;
vec4 m_Diffuse;
vec4 m_Ambient;
vec3 m_Attenen;
};

uniform sampler2D Texture;
uniform vec4 g_Color;
uniform Light Lights[1];

in vec2 o_TexCoord;
in vec3 o_Normal, o_LightDir;
in float o_Distance;

out vec4 o_Color;
void main(void){
o_Color = Lights[0].m_Ambient*g_Color*texture2D(Texture, o_TexCoord);
float NdotL = max(dot(normalize(o_Normal), normalize(o_LightDir)), 0.0f);
if(NdotL>0.0f){
float Att = 1.0f/(Lights[0].m_Attenen.x+Lights[0].m_Attenen.y*o_Distance+Lights[0].m_Attenen.z*o_Distance*o_Distance);
o_Color+=Att*Lights[0].m_Diffuse*NdotL;
}
o_Color.rgb*=o_Color.a;
}
[/code]

##### Share on other sites
L. Spiro    25621
You are doing per-vertex distance calculations. Those should be moved to the pixel shader along with o_LightDir.

Aside from the existing outputs, you are supposed to send a view copy of the vertex positions from the vertex shader to the pixel shader in order to perform these calculations per-pixel. In order words, make v_Vertex an output.

L. Spiro

##### Share on other sites
slicer4ever    6760
[quote name='L. Spiro' timestamp='1339933936' post='4949998']
You are doing per-vertex distance calculations. Those should be moved to the pixel shader along with o_LightDir.

Aside from the existing outputs, you are supposed to send a view copy of the vertex positions from the vertex shader to the pixel shader in order to perform these calculations per-pixel. In order words, make v_Vertex an output.

L. Spiro
[/quote]

ah, thanks L. Spiro, i had suspicions that might have been the issue, but wasn't certain.

one last question, is that i moved:
[code]
vec3 Aux = (ViewMatrix*vec4(Lights[0].m_Position,1.0f)).xyz-o_Vertex.xyz;
[/code]
into the pixel shader, what concerns me is doing a matrix multiplication in the pixel shader, however, since both are uniforms, i'm assuming that the driver well probably optimize it out, but would it be better to multiply my light before submitting it?

##### Share on other sites
L. Spiro    25621
You should pre-multiply light values in every case, but especially so if you are doing per-pixel lighting. The light position, direction, etc., should all be in world-view space before reaching the shaders.

L. Spiro

##### Share on other sites
slicer4ever    6760
[quote name='L. Spiro' timestamp='1339938542' post='4950010']
You should pre-multiply light values in every case, but especially so if you are doing per-pixel lighting. The light position, direction, etc., should all be in world-view space before reaching the shaders.

L. Spiro
[/quote]

alright, thanks for the info=-)