• Create Account

### #ActualSuen

Posted 23 May 2012 - 08:25 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units (rough estimation, of course the vertex positions vary). But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any huge difference. Some would get lit sliiiiightly earlier (perhaps from (0, 0, 44) or (0, 0, 45)).

Is this really the way it is supposed to behave? I can't exactly find a fault in it, I just found it strange that there wouldn't be any significant change until the light is really really close. I assume I would have to use some constant to change the attenuation to my needs?

Update: Seems that using a light radius solved this problem, although I read that it's not physically correct or at least a good approximation of it. Either way opinions are still appreciated about this, or at least suggestion(s) of good light attenuation models to use.

### #5Suen

Posted 23 May 2012 - 07:44 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units. But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any huge difference. Some would get lit sliiiiightly earlier (perhaps from (0, 0, 44) or (0, 0, 45)).

Is this really the way it is supposed to behave? I can't exactly find a fault in it, I just found it strange that there wouldn't be any significant change until the light is really really close. I assume I would have to use some constant to change the attenuation to my needs?

Update: Seems that using a light radius solved this problem, although I read that it's not physically correct or at least a good approximation of it. Either way opinions are still appreciated about this, or at least suggestion(s) of good light attenuation models to use.

### #4Suen

Posted 23 May 2012 - 05:38 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units. But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any huge difference. Some would get lit sliiiiightly earlier (perhaps from (0, 0, 44) or (0, 0, 45)).

Is this really the way it is supposed to behave? I can't exactly find a fault in it, I just found it strange that there wouldn't be any significant change until the light is really really close. I assume I would have to use some constant to change the attenuation to my needs?

### #3Suen

Posted 23 May 2012 - 05:36 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units. But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any huge difference. Some would get lit sliiiiightly earlier (perhaps from (0, 0, 44) or (0, 0, 45)).

Is this really the way it is supposed to behave? I can't exactly find a fault in it. I assume I would have to use some constant to change the attenuation to my needs?

### #2Suen

Posted 23 May 2012 - 05:36 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units. But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any huge difference. Some would get lit sliiiiightly earlier (perhaps from (0, 0, 44) or (0, 0, 45).

Is this really the way it is supposed to behave? I can't exactly find a fault in it. I assume I would have to use some constant to change the attenuation to my needs?

### #1Suen

Posted 23 May 2012 - 05:24 PM

While I've been playing around to solve the fresnel effect (which I'm still stuck at, hopefully an answer can come soon to my reply!) I thought I would give the light attenuation a try. Having tried it out I got some weird results (or perhaps that is just the way it is supposed to look like). I will post both pictures and code for the fragment shader below. I've removed things relating to my fresnel calculations as I wanted to just keep the code less heavy for the reader. Besides I don't want to mix this problem together with the actual problem I have (topic) but I felt it was a bit unnecessary to start a whole new thread about it. So simply put, I'm just doing a Blinn-Phong per-fragment calculation in this post and for now I've just added light attenuation to my diffuse reflection ONLY.

#version 330

//Make a simplification here, assuming the light intensity is already
//combined together with the material properties of the object
uniform vec3 ambientConstant;
uniform vec3 diffuseConstant;
uniform vec3 specularConstant;

smooth in vec3 eyePos;
smooth in vec3 eyeNormal;
smooth in vec3 eyeLight;

out vec4 outputColor;

void main()
{
//Interpolated normal, light direction and view direction
vec3 f_eyeNormal = normalize(eyeNormal);
vec3 f_lightDirection = normalize(eyeLight-eyePos);
vec3 f_viewDirection = normalize(-eyePos);

vec3 halfWay = normalize(f_lightDirection+f_viewDirection); //Halfway vector

//Light attenuation
float lightDistance = length(eyeLight-eyePos);
float att = 1/(lightDistance*lightDistance);

//Blinn-phong reflection model
vec3 ambientReflection = ambientConstant;
vec3 diffuseReflection = diffuseConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1);
vec3 specularReflection = specularConstant*clamp(dot(f_lightDirection, f_eyeNormal), 0, 1)*vec3(pow(clamp(dot(f_eyeNormal, halfWay), 0, 1), 80));

//Final color of the fragment
outputColor.rgb =  ambientReflection + att*diffuseReflection + specularReflection;
outputColor.a = 1.0;
}


As seen in the code I compute the distance to the light and then compute the attenuation as the inverse squared distance. This is then multiplied with my diffuse reflection. If you look at the first image below my mesh is very dark. To be more precise, what it looks like to me is that the remaining value of my diffuse reflection, after having been divided by the inverse squared distance, is so small that basically the only thing contributing to the fragment color is my ambient reflection and of course the specular reflection. Thus the mesh seem to have the same color all over it. I thought this made sense at first because my mesh is located at (0, 0, -50) in the world and the starting position of my light is (0, 0, 50) so there's 100 difference in units. But if you look at the second picture the position of the light is at (0, 0, -20). The distance is much less here, yet the color of the mesh remains exactly the same (the only change here is the movement of the specular highlights but that makes sense as the light is moving closer to the camera). Finally in the third image the position of the light is at (0, 0, -48.7) so the distance here is really really small. Only here is there a change on the color of the mesh and only on a small area of it.

I thought this behaviour was strange as I expected the mesh to get "lit" much earlier but clearly this wasn't the case. I thought it might be the method itself and tried some other methods (for example one were I just used the inverse distance instead of the inverse square distance) but none of them made any difference at all. All of them only displayed a change from a lightposition of (0, 0, -48.0) and onwards (of course if you keep going onwards the light will eventually pass through the mesh and get further away from it again and thus the same problem occurs)

Is this really the way it is supposed to behave?

PARTNERS