Size of specular Highlight changes with camera distance

I dont know if this is supposed to be that way, but it doesnt seem realistic. My specular highlights stay the same size on my screen no matter how far away the camera is from the surface/vertex. I would like it to stay the same size.
here is my Fragment shader

#version 430
#define PI 3.1415926535897932384626433832795
uniform vec3 lightColor;
uniform sampler2D tex;
uniform vec3 ambientLight;
uniform vec3 lightPosition;
uniform vec3 cameraPosition;


in Vertex{
	vec4 rawPosition; // Vertex Position only multiplied by the transformationmatrix. ( gl_Position is also multiplied by the projection and view matrices)
	vec2 uv;
	vec4 normal; // the normals have also been multiplied by the transformationmatrix ( is this correct? my normals have a w-value of 0.0f but the transformationmatrix makes a difference. without it the reflections dont seem be in the right place.
}vertexIn;

out vec4 color;

void main(){
	vec3 normal = normalize(vec3(vertexIn.normal.x, vertexIn.normal.y, vertexIn.normal.z));
	vec3 worldPosition = vec3(vertexIn.rawPosition.x, vertexIn.rawPosition.y, vertexIn.rawPosition.z);
	
	vec3 lightVector = normalize(lightPosition - worldPosition);
	vec3 reflection = normalize(reflect((-1.0)*lightVector, normal));
	vec3 cameraVector = normalize(cameraPosition - worldPosition);

	float lightAngle = clamp(dot(lightVector, normal), 0.0, 1.0);
	float cameraAngle = clamp(dot(cameraVector, reflection), 0.0, 1.0);
	float specular = pow(cameraAngle, 100);
	

	vec4 actColor = texture(tex, vertexIn.uv);
	vec4 diffuseLight = vec4(lightColor, 1.0) * lightAngle;
	vec4 specularLight = vec4(lightColor, 1.0) * specular;
	color = actColor * clamp(diffuseLight, vec4(ambientLight, 1.0), vec4(1.0, 1.0, 1.0, 1.0)) + specularLight;
	}

here is an imgur link to visualize what i mean. the lightsource is the small cube above the middle of the grid

thanks for the help

My specular highlights stay the same size on my screen no matter how far away the camera is from the surface/vertex. I would like it to stay the same size.

Well, first, I’m really unsure about what you said. They stay the same but you want them to stay the same ?

The specular amount depends on the angle between the viewer and the light reflected ray. In your animation, you seem to keep this angle. So to my opinion, the result is good.

You’re right, Kind of misleading Statement.

What i want is that the Highlight stays the same size on my geometry. Right now it is more like something on my Screen than on the geometry.

As you said, the highlight is dependent on the direction vector to the camera. So the area of fragments being lit up by the highlight should not change, even if I go closer and further away, as long as the vector to the camera stays the same. But as you can see in the gif, if I move away far enough, almost all the fragments of that plane are highlighted. How can I avoid this? My guess is that it is something with precision errors with the vector and the normal or something… but even that should not change because normalize(cameraPosition-fragmentPosition) will always have the same vector no matter how far away I am from the fragment…

You can use attenuation. But of course, this will work only for non-directional lights.

See this page for an explanation of the Blinn-Phong model.

There are three factors which affect the amount of specular reflection at a given point on a surface: the direction of the vector between the point and the viewer, the direction of the vector between the point and the light, and the direction of the surface normal.

If neither the viewer nor the light are close to the surface, then the vectors between a point on the surface and the viewer or the light won’t vary much across the surface. The shape of the specular highlight will be dominated by the amount of variation in the surface normal, i.e. by the curvature of the surface. The highlight (i.e. the region of the surface where the normal is roughly mid-way between the toward-light and toward-viewer vectors) will have a near-constant size in world space, with the size on screen varying as the object moves toward or away from the viewer.

If the surface is approximately flat (i.e. the normal direction is the roughly constant across the surface), then the only factors affecting the specular highlight are the toward-viewer and toward-light vectors. Additionally, if the light is far from the surface, that leaves only the direction of the toward-viewer vector. This vector is determined solely by the viewport coordinates. So in that situation, the size and shape of the specular highlight will be fixed in screen space, and independent of the distance of the viewer from the surface.

@Silence
Attenuation and/or Blinn-Phong is something i will definitely have to implement, but i would have expected a more hands on solution for this issue. It does not seem like i did anything wrong like i expected though, so i think i will just leave this for now.

@GClements
i tried my specular light on a sphere with smooth shading now, and it looks a lot better there. but obviously i will also want the specular highlight on flat surfaces to be realistic, and appearently that is what blinn-phong is used for. i have other priorities now though, and will probably come back to that later.

Thanks to both of you for shedding some light on my issue :wink:
Have a nice friday!

EDIT:
I have now implemented blinn phong, because it did not seem as hard to do as i originally thought. i dont feel like i entirely understand why it solved the issue, but it works. the reflection behaves a lot more like you would expect it to. thanks again :smiley:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.