Search code examples
javaopenglglslshaderphong

How to pick light source for Phong shading implementation?


I am trying to implement the Phong shading model and I am unsure of how to pick a light source. More specifically, I do not understand what the light source should look like. Should it be a vec3? Or maybe a matrix, which I have defined in my Java code? Also, if we suppose that I want the camera to be the light source, what should be different to a different light source, like a point somewhere else in the view world? I would really apreciate an explanation or maybe a guidance of how I should go about solving something like this and not just code.

This is what I have in my vertex shader so far:

 #version 330
 layout(location=0) in vec3 vertex;
 layout(location=1) in vec3 normals;

 uniform mat4 viewMatrix;
 uniform mat4 projMatrix;

 out vec3 vertexColor;
 out vec3 pixelCoordinates;
 out vec3 normalizedNormals;

  void main(){

    if (gl_VertexID < 6) {
            vertexColor = vec3(1.0, 0.0, 0.0);
        } else if (gl_VertexID < 12) {
            vertexColor = vec3(0.0, 1.0, 0.0);
        } else if (gl_VertexID < 18) {
            vertexColor = vec3(0.0, 0.0, 1.0);
        } else if (gl_VertexID < 24) {
            vertexColor = vec3(1.0, 1.0, 0.0);
        } else if (gl_VertexID < 30) {
            vertexColor = vec3(1.0, 0.0, 1.0);
        } else {
            vertexColor = vec3(0.0, 1.0, 1.0);
        }



pixelCoordinates = vec3(viewMatrix*vec4(vertex,1.0));
normalizedNormals = normalize(mat3(viewMatrix)*normals);
gl_Position = projMatrix*viewMatrix*vec4(vertex, 1.0);

 }

and this is how my fragment shader looks like currently:

 #version 330

in vec3 vertexColor;
in vec3 pixelCoordinates;
in vec3 normalizedNormals;
out vec3 pixelColor;

void main(){



float il = 1;
float ia = 0.2;
float id ;

vec3 v = normalize(-pixelCoordinates);

}

When I compile I get a black screen, which of course occurs because I am still misssing the ambient light and the final light coming out, for which I need to set a light source.


Solution

  • The simplest light source that you can define is a directional light. For a directional light, all you need is a vec3 which contains the light direction. Use that light direction directly with calculating the Phong illumination model.

    Beware of the specific direction vectors you are using => either

    1. perform the calculations with the direction towards the light source and the direction towards the viewer, or
    2. perform the calculations with the incoming light direction and the direction from the viewer towards the surface

    I'm mentioning this because if you mess up the directions, your dot product (cosine) between the two vectors will be negative.

    It is very important to make sure that all your data is in the SAME space when performing the illumination calculation. I.e., make sure that your light direction is in the same space as your vertex position as your viewer/camera position.

    The two most obvious choices for the spaces are: world space and view space. If you choose world space, you could pass in the position of the viewer/camera as a uniform and the light direction would remain the same; if you are going for the view space, the viewer/camera will be at (0,0,0) always, but you have to transform the light direction in every frame into view space - in your case using the matrix mat3(viewMatrix) should do the trick if you are not using non-uniform scaling for your scene.

    Once you have successfully calculated the illumination for a directional light, you can move on to other light sources like point lights, which are defined mainly by a position vector (from which you, again, calculate a direction vector per vertex). There are lots of good tutorials about this topic on the internet.