Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSL per pixel point light shading

VC++, OpenGL, SDL

I am wondering if there is a way to achieve smoother shading across a single Quad of geometry. Right now, the shading looks smooth with my point light, however, the intensity rises along the [/] diagonal subdivision of the face. The lighting is basically non-visible in-between vertices.

enter image description here

enter image description here

enter image description here

This is what happens as the light moves from left to right

As I move the light across the surface, it does this consistently. Gets brightest at each vertex and fades from there.

Am I forced to up the subdivision to achieve a smoother, more radial shade? or is there a method around this?

Here are the shaders I am using:

vert

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{            
    vertex_normal = normalize(gl_NormalMatrix * gl_Normal);
    vertex_light_position = normalize(gl_LightSource[0].position.xyz);

    gl_FrontColor = gl_Color;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

frag

varying vec3 vertex_light_position;
varying vec3 vertex_normal;

void main() 
{
    float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);
    gl_FragColor = gl_Color * diffuse_value;
}

My geometry in case anyone is wondering:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(pos_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(pos_x + size_x, pos_y - size_y, depth);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(pos_x + size_x, pos_y, depth);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(pos_x, pos_y, depth);
glEnd();
like image 405
grep Avatar asked Feb 23 '23 02:02

grep


1 Answers

There are a couple things I see as being possible issues.

Unless I am mistaken, you are using normalize(gl_LightSource[0].position.xyz); to calculate the light vector, but that is based solely on the position of the light, not on the vertex you are operating on. That means the value there will be the same for every vertex and will only change based on the current modelview matrix and light position. I would think that calculating the light vector by doing something like normalize(glLightSource[0].position.xyz - (gl_ModelViewMatrix * gl_Vertex).xyz) would be closer to what you would want.

Secondly, you ought to normalize your vectors in the fragment shader as well as in the vertex shader, since the interpolation of two unit vectors is not guaranteed to be a unit vector itself.

like image 116
nonVirtualThunk Avatar answered Mar 04 '23 00:03

nonVirtualThunk