What is Half vector in modern GLSL?

13,223

Solution 1

In the fragment shader the vertex coordinates can be seen as a vector that goes from the camera (or the "eye" of the viewer) to the current fragment so by reversing the direction of this vector we then have the "Eye"-vector you are looking for. When calculating the Half-vector you also need to be aware of the direction of the Light-position vector, on the webpage you link they have that on pointing towards the surface, on http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model its pointing away from the surface.

Solution 2

The half-vector is used in specular lighting and represents the normal at micro-imperfections in the surface which would cause incoming light to reflect toward the viewer. When the half-vector is closer to the surface normal, more imperfections align with the actual surface normal. Smoother surfaces will have fewer imperfections pointing away from the surface normal and result in a sharper highlight with a more significant drop off of light as the half-vector moves away from the actual normal than a rougher surface. The amount of drop off is controlled by the specular term, which is the power to which the cosine between the half-vector and normal vector is taken, so smoother surfaces have a higher power.

We call it the half-vector (H) because it is half-way between the vector point to the light (light vector, L) and the vector pointing to the viewer (which is the eye position (0,0,0) minus the vertex position in eye space; view vector, V). Before you calculate H, make sure the vector to the light and the eye are in the same coordinate space (legacy OpenGL used eye-space).

H = normalize( L + V )

You did the correct calculation, but your variables could be named more appropriately. The term light_position here isn't entirely correct, since the tutorial you cited is the Directional light tutorial, which by definition, directional lights don't have position. The light vector for directional lights is independent of the vertex, so here, you have combined a few equations. Keep in mind, the light vector is toward the light, so opposite of the flow of photons from the light.

// i'm keeping your term here... I'm assuming
// you wanted to simulate a light coming from that position
// using a directional light, so the light direction would
// be -light_position, making
// L = -(-light_position) = light_position
vec3 L = light_position;
     // For a point light, you would need the direction from
     // the point to the light, so instead it would be
     // light_position - outVertex
vec3 V = -out_Vertex;
     // really it is (eye - vertexPosition), so (0,0,0) - out_Vertex
vec3 H = normalize(L + V);
Share:
13,223
j riv
Author by

j riv

Updated on June 11, 2022

Comments

  • j riv
    j riv almost 2 years

    http://www.lighthouse3d.com/opengl/glsl/index.php?ogldir2 reports that half vector in OpenGL context is 'Eye position - Light position' but then it goes on to say 'luckily OpenGL calculates it for us' [which is now deprecated].

    How can, practically be calculated (a simple example would be greatly appreciated) [mainly, it puzzles me what "Eye" is and how it can be derived].

    At the moment I managed to make specular calculations work (with good visual result) with half vector being equal to Light where Light is

    vec3 Light = normalize(light_position - vec3(out_Vertex));
    

    Now, I've no idea why that worked.

    [If at least I knew what "Eye" is and how it can be derived practically.]

  • j riv
    j riv over 13 years
    You're saying Eye is only 1/out_Vertex.x, 1/out_Vertex.y, 1/out_Vertx.z?
  • Daniel
    Daniel over 13 years
    No, bad choice of wording on my part there, what I mean is that Eye = (-out_Vertex.x, -out_Vertex.y -out_Vertex.z)