I am working on a personal graphics engine, and I began to develop a spot of light. The problem is that rendering is illogical. For simplicity, I cleared all the information about controlling light and texture inside the shader example below.
Here is the vertex shader code:
#version 400 layout (location = 0) in vec3 VertexPosition; uniform mat4 ModelViewMatrix; uniform mat4 MVP; out vec3 VPosition; void main(void) { VPosition = vec3(ModelViewMatrix * vec4(VertexPosition, 1.0f));
And the fragment shader code:
#version 400 in vec3 Position; //IN EYE COORDINATES layout (location = 0) out vec4 FragColor; uniform int lightCount; struct SpotLight { vec4 Position; //ALREADY IN EYE COORDINATES vec3 La, Ld, Ls; vec3 direction; float exponent; float cutoff; }; uniform SpotLight LightInfos[1]; vec3 getLightIntensity(void) { vec3 LightIntensity = vec3(0.0f); for (int idx = 0; idx < lightCount; idx++) { vec3 lightDirNorm = normalize(vec3(LightInfos[idx].Position) - Position); vec3 spotDirNorm = normalize(LightInfos[idx].direction); float angle = acos(dot(-lightDirNorm, spotDirNorm)); float cutoff = radians(clamp(LightInfos[idx].cutoff, 0.0f, 90.0f)); vec3 ambient = vec3(0.1f, 0.1f, 0.8f); //Color out of the spotlight cone. vec3 spotColor = vec3(0.1f, 0.8f, 0.1f); //Color within the spotlight cone. if (angle < cutoff) { LightIntensity = spotColor; } else { LightIntensity = ambient; } } return (LightIntensity); } void main(void) { FragColor = vec4(getLightIntensity(), 1.0f); }
Here's the C ++ code where I post the properties of the light position:
glm::vec4 lightPositionVec = viewMatrix * glm::vec4(lightPosition[0], lightPosition[1], lightPosition[2], lightPosition[3]); program->setUniform(std::string("LightInfos[").append(Utils::toString<int>(idx)).append("].Position").c_str(), lightPositionVec);
Here are the properties of the spot of light:
<position x="0.0" y="2.0" z="0.0" w="1" /> <direction x="0.0" y="-1.0" z="0.0" /> <exponent>3.0</exponent> <cutoff>50.0</cutoff>
View Properties:
<camera name="cam1"> <perspective fovy="70.0" ratio="1.0" nearClipPlane="0.1" farClipPlane="1000.0"/> <lookat> <eye x="0.0" y="50.0" z="50.0" /> <target x="0.0" y="0.0" z="0.0" /> <up x="0.0" y="1.0" z="0.0"/> </lookat> </camera>
I checked this data before sending it to the program shader in my C ++ code, and they are correct.
And here is the result:

And if I put the camera closer to the plane with the following camera properties:
<camera name="cam1"> <perspective fovy="70.0" ratio="1.0" nearClipPlane="0.1" farClipPlane="1000.0"/> <lookat> <eye x="0.0" y="10.0" z="20.0" /> <target x="0.0" y="0.0" z="0.0" /> <up x="0.0" y="1.0" z="0.0"/> </lookat> </camera>
The result is the following (closer to reality, but still not correct):

As you can see, this is not logical: I have a spot at x = 0, y = 1, z = 0, a downward direction of light (x = 0, y = -1, z = 0), so I do not understand this result. In addition, all my vectors are in eye coordinates. I get the impression that the effect of spotlight depends on the position of the camera. Can anybody help me?