PDA

View Full Version : Problems Calculating Surface Reflectance in Shader

11-14-2006, 08:34 PM
[EDIT] I tried this shader pair out in ShaderDesigner with all lights disable and it worked. Any suggestions on what I might be doing wrong?
CD
-------------------------

I am trying to write a shader which calculates a quantity of reflected light from a source. Sounds simple enough, but I am having problems with it....

Here are my assumptions:

1 - The source location and view point are the same. That is, the viewer is observing the amount of light reflected back to his position, which is also the origin of the light.

2 - I know the broadband reflectance of a material as a function of incidence angle and view angle. That is, for some discrete angles, I know brdf(in, out) = blah blah blah.

I use a GL light to mimic the source.

glEnable(GL_LIGHTING);
float lightPosition[4] = {m_source->m_WorldPos[0], m_source->m_WorldPos[1], m_source->m_WorldPos[2], 0.0f};
glLightfv( GL_LIGHT0, GL_POSITION, lightPosition ); // This sets our light positionTo begin with I would just be happy to set the fragment color to the dot of the vertex normal and light direction, but I can't seem to get that to work (which is all I am trying to do with the code below)...

varying vec3 normal,lightDir;
varying float NdotL;
varying float LdotN;

void main()
{
vec4 ecPosition;
vec3 aux;

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

// transform vertex to eye space, normalize result
ecPosition = normalize(gl_ModelViewMatrix * gl_Vertex);

aux = vec3(gl_LightSource[0].position-ecPosition);
lightDir = normalize(aux);
NdotL = dot(normal, lightDir);
LdotN = dot(lightDir, normal);

gl_Position = ftransform();

varying vec3 normal,lightDir;
varying float NdotL;
varying float LdotN;

void main()
{
float value = 1.0;

if (NdotL > 0.0) {

value = pow(NdotL, 3);
}

gl_FragColor = vec4(value, value, value, 0.0);
}The problem I see is that NdotL is constant, even though the object I am rendering is a cylinder. I would have thought it would roll off at the edges.... Also the cylinder is pitching and yawing, so I would have thought I would see some change as it moves, but no change.

What am I doing wrong?

CD

CaseMillennium
11-14-2006, 11:35 PM
My guess is these lines are wrong:

// transform vertex to eye space, normalize result
ecPosition = normalize(gl_ModelViewMatrix * gl_Vertex);

aux = vec3(gl_LightSource[0].position-ecPosition);
If you normalize ecPosition it is no longer position but a unit vector so aux just gets bogus results. You need to normalize the vector after you calculated the light vector.

11-15-2006, 05:49 AM

I was hoping that was my problem too.... I thought it was as I received the exact same answer on the GL forum on codesampler.com, but I am still seeing the same problem.

As I mentioned, this shader worked before in ShaderDesigner. So I must be doing something else in my app that is just wrong enough to mess it up.

NdotL is right at 1.0 for all vertices, which seems wrong to me.

If I insert the following

Originally posted by CaseMillennium:
My guess is these lines are wrong:

// transform vertex to eye space, normalize result
ecPosition = normalize(gl_ModelViewMatrix * gl_Vertex);

aux = vec3(gl_LightSource[0].position-ecPosition);
If you normalize ecPosition it is no longer position but a unit vector so aux just gets bogus results. You need to normalize the vector after you calculated the light vector.

k_szczech
11-15-2006, 10:29 AM
NdotL is right at 1.0No, I bet NdotL <= 0.0
For zero and negative NdotL you fragment shader will produce white color.

As I mentioned, this shader worked before in ShaderDesigner. So I must be doing something else in my app that is just wrong enough to mess it up.That would be matrix and light setup and that's what probably different in your app and shader designer. Furthermore it could also couse wrongly written shader (see CaseMillennium's post) to appear to work in shader designer. I believe CaseMillennium's advice should fix the problem on the shader's side.
As for application side - remember that light position gets transformed by modelview matrix when you specify that position in your app. You can change matrix later (before rendering polygons) and it won't affect gl_LightSource[0].position.

11-15-2006, 12:46 PM
i have made some changes to the shaders since the original post. I checked the value of NdotL and it really is 1.0 for all vertices.

CD

Originally posted by k_szczech:

NdotL is right at 1.0No, I bet NdotL <= 0.0
For zero and negative NdotL you fragment shader will produce white color.

As I mentioned, this shader worked before in ShaderDesigner. So I must be doing something else in my app that is just wrong enough to mess it up.That would be matrix and light setup and that's what probably different in your app and shader designer. Furthermore it could also couse wrongly written shader (see CaseMillennium's post) to appear to work in shader designer. I believe CaseMillennium's advice should fix the problem on the shader's side.
As for application side - remember that light position gets transformed by modelview matrix when you specify that position in your app. You can change matrix later (before rendering polygons) and it won't affect gl_LightSource[0].position.

k_szczech
11-15-2006, 03:15 PM
No, I bet NdotL <= 0.0Yeah, I misread your post. You did write that

i have made some changes to the shaders since the original postI've tested your original shader in my editor - it seemed to work fine but it started to work better (properly) after applying CaseMillennium's fix.