View Full Version : Equivalent of gl_LightSource[0].halfVector?

lordmule

12-14-2010, 12:45 AM

I can't seem to get compute the right half vector, where L = light vector, V = view vector and H =L + V. Am I doing this correctly?

Vertex shader:

varying vec3 v;

...

v = vec3(gl_ModelViewMatrix * gl_Vertex);

Fragment shader

varying vec3 v;

...

vec3 L = normalize(gl_LightSource[0].position.xyz - v);

vec3 V = normalize(-v);

vec3 H = normalize(L + V);

I found an Orange book example that is similar but requires eyePosition:

// extract positions from input uniforms

vec3 lightPosition = gl_LightSource[0].position.xyz;

vec3 eyePosition = -osg_ViewMatrix[3].xyz / osg_ViewMatrix[3].w;

// H = halfway vector between light and viewer from vertex

vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);

vec3 L = normalize(lightPosition - P);

vec3 V = normalize(eyePosition - P);

vec3 H = L + V;

thanks

Alfonse Reinheart

12-14-2010, 01:04 AM

I can't seem to get compute the right half vector, where L = light vector, V = view vector and H =L + V.

How do you know you can't? How do you know what you're getting is the wrong value?

Also, is L in the same space as V?

I found an Orange book example that is similar but requires eyePosition:

I don't know how that works. P is in camera space. eyePosition is in... world space?

lordmule

12-14-2010, 02:31 AM

Thanks for response Alfonse.

How do you know you can't? How do you know what you're getting is the wrong value?

I render using gl_LightSource[0].halfVector, switch code to my halfVector equiv and re-render. not the same :(

is L in the same space as V?

if you mean in modelview space, then I'd say yes.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);

glLoadMatrixf(camera_mat);

glPushMatrix();

glUseProgramObjectARB(0);

glColor3f(0,1,1);

update_lights();

if (drawlights)

draw_lights();

glUseProgramObjectARB(shader);

render_objects();

glPopMatrix();

glutSwapBuffers();

I could not find anything in the documentation on how gl_LightSource[0].position is handled or half vector is computed. Good thing there is Mesa3d (http://www.mesa3d.org/) library to guide an answer. I found this in src/mesa/shader/prog_statevars.c :

const GLuint ln = (GLuint) state[2];

GLfloat p[3];

/* Compute infinite half angle vector:

* halfVector = normalize(normalize(lightPos) + (0, 0, 1))

* light.EyePosition.w should be 0 for infinite lights.

*/

COPY_3V(p, ctx->Light.Light[ln]._Position);

NORMALIZE_3FV(p);

ADD_3V(value, p, ctx->_EyeZDir);

NORMALIZE_3FV(value);

value[3] = 1.0;

So I changed the vertex shader:

varying vec3 halfVector, n;

...

//halfVector = normalize(gl_LightSource[0].halfVector.xyz);

halfVector = normalize(normalize(gl_LightSource[0].position.xyz) + vec3(0, 0, 1));

Tested with Phong shader:

varying vec3 halfVector, n;

...

float NH = max(dot(n,halfVector),0.0);

vec4 spec = gl_FrontMaterial.specular * gl_LightSource[0].specular *

pow(NH,gl_FrontMaterial.shininess);

Works!

I only wish I could see how to derive this solution.

Powered by vBulletin® Version 4.2.2 Copyright © 2014 vBulletin Solutions, Inc. All rights reserved.