Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: [OpenGL 3.3+]Phong shading and transformations

Hybrid View

  1. #1
    Newbie Newbie
    Join Date
    Sep 2012
    Posts
    2

    [OpenGL 3.3+]Phong shading and transformations

    Hello, I would like to find a solution for the problem which is haunting me lately.

    I am starting to use OpenGL3.3+ and shaders(I've been using immediate mode for 2D rendering most of the time, and Irrlicht 3D rendering engine.), so I am practically new at those. After some time fiddling with the new syntax and shaders, I've finally came to the lighting stage and tried to implement phong lighting, everything seemed okay at first, but then I realised it's screwed. After a day and a half of trying to fix it, intense googling for the same problem, I couldn't find a solution. My problem is simple:

    Light is orientating with camera even if it's in a static place(like 0,0,100) so if it's lighting the back of the model, the front is lit, and even more strangely, when I go away from the dark side, it lights up..

    Here's a screenshot:

    (Light is in front of the model, while the back is being lit brightly as I am far away.)

    Here's my phong shader, I've taken it from Anton's OpenGL4 wiki and added texturing support:

    phong.fs
    Code :
    #version 400
     
    in vec4 vpeye; // fragment position in eye coords
    in vec4 vneye; // surface normal in eye coords
    in vec2 UV; // UV coordinates
     
    uniform vec4 lightPosition; // light position in eye coords  
    uniform vec4 Ka; // ambient coefficient
    uniform vec4 Kd; // diffuse coefficient
    uniform vec4 Ks; // specular coefficient
    uniform float Ns; // specular exponent
    uniform vec4 Ld; // diffuse light colour
     
    // Values that stay constant for the whole mesh.
    uniform sampler2D myTextureSampler;
     
    layout (location = 0) out vec4 fragmentColour;
     
    void main() {
     
      vec4 n_eye = normalize(vneye); // normalise just to be on the safe side
      vec4 s_eye = normalize(lightPosition - vpeye); // get direction from surface fragment to light
      vec4 v_eye = normalize(-vpeye); // get direction from surface fragment to camera
      vec4 h_eye = normalize(v_eye + s_eye); // Blinn's half-way vector
      //vec4 r_eye = reflect(-s_eye, vneye); // Phong's full reflection (could use instead of h)
     
      vec4 Ia = vec4(0.1,0.1,0.1,1) * Ka; // ambient light has a hard-coded colour here, but we could load an La value
      vec4 Id = Ld * Kd * max(dot(s_eye, n_eye), 0.0); // max() is a safety catch to make sure we never get negative colours
      vec4 Is = vec4(1,1,1,1) * Ks * pow(max(dot(h_eye, v_eye), 0), Ns); // my ambient light colour is hard coded white, but could load Ls
     
      fragmentColour = texture( myTextureSampler, UV ).rgba *(Ia + Id + Is);
    }

    phong.vs
    Code :
    #version 400
    layout (location = 0) in vec3 vertexPosition;
    layout(location = 1) in vec2 vertexUV;
    layout (location = 2) in vec3 vertexNormal;
     
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    uniform mat3 normalMatrix;
     
    // Output data ; will be interpolated for each fragment.
    out vec2 UV;
    out vec4 vpeye;
    out vec4 vneye;
     
    void main() {
     
    	vpeye = modelViewMatrix * vec4(vertexPosition, 1.0);
    	vneye = vec4(normalMatrix * vertexNormal, 0);
    	UV = vertexUV;
    	gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);
    }

    Also, I think this might be related to my matrices. I load the model with assimp so the normals are correct. The other matrices are set like this:

    The ModelView matrix:
    Code :
    glm::mat4 ModelView=cam->getView()*Model;
    glUniformMatrix4fv(MVMat,1,GL_FALSE,&ModelView[0][0]);

    The NormalMatrix:
    Code :
    //The "normal matrix" is an inverse*transpose of the model*view matrix
    glm::mat4 normat=glm::inverse(glm::transpose(ModelView));
    glUniformMatrix3fv(NMat,1,GL_FALSE,&glm::mat3(normat)[0][0]);

    How I calculate the view matrix:
    Code :
    // Camera matrix
    _view       = glm::lookAt(
    	_pos,           // Camera is here
    	_pos+direction, // and looks here : at the same position, plus "direction"
    	up                  // Head is up (set to 0,-1,0 to look upside-down)
    );

    Hope you can help a poor noobley out and explain some things.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,188
    Light is orientating with camera even if it's in a static place(like 0,0,100) so if it's lighting the back of the model, the front is lit, and even more strangely, when I go away from the dark side, it lights up..
    You're doing your lighting in OpenGL EYE-SPACE in the shader (logical choice), which means the "lightPosition" you're passing into your shader better be in EYE-SPACE. (0,0,100) in EYE-SPACE would be located in the direction of the eye (down the +Z axis). So with that (barring distance attenuation, light cones, etc. which you're not simulating yet) you should be illuminating the side of the object you can see from the eyepoint.

    If you did in-fact want a "static place" in say WORLD-SPACE (such as WORLD-SPACE (0,0,100)), then you'd want to take ((0,0,100) and transform it by your VIEWING transform (to get it into EYE-SPACE) before assigning it the "lightPosition" uniform.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •