PDA

View Full Version : Very Very Strange results with shaders



abhishek bansal
06-14-2011, 09:00 AM
hello all...

I am trying to learn Open GL lighting pipeline...i am following tutorials from lighthouse3D...in one of there tutorial they have simulated openGL lighting pipeline in a vertex shader which is this..


/* -------------------------------------------------------

This shader implements a directional light per vertex using the
diffuse, specular, and ambient terms acoording to "Mathematics of Lighthing"
as found in the book "OpenGL Programming Guide" (aka the Red Book)

António Ramires Fernandes

--------------------------------------------------------- */

void main()
{
vec3 normal, lightDir, viewVector, halfVector;
vec4 diffuse, ambient, globalAmbient, specular = vec4(0.0);
float NdotL,NdotHV;

/* first transform the normal into eye space and normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);

/* now normalize the light's direction. Note that according to the
OpenGL specification, the light is stored in eye space. Also since
we're talking about a directional light, the position field is actually
direction */
lightDir = normalize(vec3(gl_LightSource[0].position));

/* compute the cos of the angle between the normal and lights direction.
The light is directional so the direction is constant for every vertex.
Since these two are normalized the cosine is the dot product. We also
need to clamp the result to the [0,1] range. */

NdotL = max(dot(normal, lightDir), 0.0);

/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;

/* compute the specular term if NdotL is larger than zero */
if (NdotL > 0.0) {

NdotHV = max(dot(normal, normalize(gl_LightSource[0].halfVector.xyz)),0.0);
specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess);
}

gl_FrontColor = globalAmbient + NdotL * diffuse + ambient + specular;

gl_Position = ftransform();
}


now i am sending variable values through this set of command in openGL


glLightfv(GL_LIGHT0, GL_POSITION, lpos);

glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

now a strange thing i am finding is when i put above commands in my init() function i get different results and different when i put them in my render() function for same values of all variables....why is this happening??

i am attaching both results..
here variable values are..


float lpos[4] = {1.0,0.0,1.0,0.0};

GLfloat diffuse[] = { 0.5, 0.0, 1.0, 1.0 };
GLfloat mat_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };

GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };

GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };

GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_specular[] = { 1.0,1.0, 1.0, 1.0 };
GLfloat high_shininess[] = { 100.0 };


Thank You

vivek vyas
06-14-2011, 09:52 AM
I am not understand where your init is
but
it look like matrix which are multiplied are different

if your init() is inside main for define and not change
then it not get multiplied with a matrix(projection, modelview)

but when you put in Render function then it will get multiplied with matrix

to find more specifically look in RedBook there is some movelight.c

and see how functions are puted to move the light
if you change that you will get different result
specifically light position as your pics give that idea
i can't explain it very well but when you look on example it may be cleared

abhishek bansal
06-14-2011, 09:55 AM
ya i did some experiments and found out that only
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
is causing the problem ...but why..?? i can't understand i ll look at the example as u said...

abhishek bansal
06-14-2011, 10:02 AM
I am not understand where your init is


my init is in Main () function..called one time only..

skynet
06-14-2011, 10:31 AM
Your problems seem to arise, because

glLightfv(GL_LIGHT0, GL_POSITION, lpos);

multiplies the incoming light position with the modelview matrix that is set at this moment in order to transfer the given light position/direction into eyespace. Make sure, you set the intended modelview matrix before calling glLightfv.

vivek vyas
06-14-2011, 11:22 AM
if you don't know(but i think you know)

model-view
both are two matrix


model->Translate,Scale,Rotate...
view->gluLookAt()which is also Translate Rotate...

make some changes on your light co-ordinates

Try to Rotate The Teapot
I think
you may find light as rotating in one case
and light is still in another(what you aspect)
still I can't Explain it very well but you should realize that what is happening

abhishek bansal
06-15-2011, 02:57 AM
ya actually i read it in RedBook as u suggested and found out that since light coordinates are calculated in eye space and open gl treats light position like any other primitive...all modelview/projection transformations are applied to light position as well....
now my render function is as follows


glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
gluLookAt(0.0,5.0,5.0,
0.0,0.0,0.0,
0.0f,1.0f,0.0f);

glRotatef(a,0,1,0);
glColor3f(1.0,0.0,0.0);


glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);

glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glutSolidTeapot(1);
a+=0.4;

glutSwapBuffers();


now in above function if i put
glLightfv(GL_LIGHT0, GL_POSITION, lpos); after glLoadIdentity() light would remain still through out the scene... if put it after gluLookAt()it ll get multiplied by viewing matrix...and if i put it after glRotatef() then it will get multiplied by modelview matrix and light will rotate like primitive...but what will be consequences of light position getting multiplied by viewing matrix..??this i don't understand...!!

BionicBytes
06-17-2011, 08:51 AM
but what will be consequences of light position getting multiplied by viewing matrix..??this i don't understand...!!

Your light position will be multiplied by the glModelView matrix and end up in eye-space.
This is what you generally want to do, and what all internal fixed function OpenGL calculations expect. Think of it simply this way: by multiplying something by the View matrix, that something becomes visible (i.e. transformed by the camera).

abhishek bansal
06-17-2011, 09:02 AM
ohkay....
thank you all for your kind help....!!!