I implemented a simple point light with normal mapping on RenderMonkey and copied it over to my own framework in C++ and for some odd reason I am having issues as you can see below:
First of all it’s not a spotlight, though it looks like it. The normal map seems fine as the highlights are correct.
I am doing my light and view direction vector calculations in eye space (premultiplying the light position and view position in the application by the current view matrix) however; I get this strange result. There is not a problem in the calculation of the view matrix. I believe I have checked everything but I hope I can get some input here or maybe someone can suggest somewhere else to look for the source of the problem.
Maybe there is still something you don’t understand:
uniform vec3 eyePosition; /*In eye space*/
in eye space, coordinates are relative to the eye so in eye space, the eye position is always at (0,0,0).
So, when you transform a vertex to eye space multiplying this one by the modelview matrix, its position is relative to the eye position.
I red-green-blue line represent tangent-binormal-normal?
If yes, they are wrong, the normal should always “point” away from the face.
If the normal is the green one then the shader is wrong cause you compute the z coordinate with the normal.
BTW you can avoid to pass the binormal as parameter but you can simply compute it using a cross product.
I calculate the binormal using cross product anyway but to be honest I don’t know whether passing a vec3 or doing a cross product in the shader is more efficient.
I don’t know what you meant by “…If the normal is the green one then the shader is wrong cause you compute the z coordinate with the normal…” the last row of TBN matrix is the normal so when you multiply a vector by that matrix you do a dot with the last row for the z coordinate.
“I calculate the binormal using cross product anyway but to be honest I don’t know whether passing a vec3 or doing a cross product in the shader is more efficient.”
GPU performs math operations insanly fast whereas (depedning on geometry) sending lots of binormals (Vec3) down the pipeline is very inefficient and takes more video ram to store. its once per-vertex anyways.
Uniforms variables are shader program objects and do ont belong to a vertex or a fragment shader. So I would think it very stupid to send a uniform everytime the vertex or the fragment shader is invoked. IMO, it is at least cached since uniforms are per-primitive “properties/attribute”.
So, in the end, I do not know if passing binormal as uniform is faster or slower than computing it for each vertex.
dogdemir, right now, I do not have the time to look deeply at your code, but to support what Rosario said, the vertical vector is eye space is always the Y axis, the one orthogonal and pointing out of the screen is the Z axis. Maybe, you had not taken care of that.
Sorry, my English is still awful (I’m working on it).
You are using the Normal to compute the Z, the Tangent to compute the X, so the Binormal is inverted (you are using a left-handed coordinate system), check it again.
I think there’s some confusion in the TBN matrix cause is the only difference that I found with my shader (edit: and the obvious eyePosition that is wrong).
@dletozeun: bitangent are vertex attributes, not uniform.
i guess you mean not uniforms but attribs which are part of the vertex stream which has to undergo this and that and requires some calls to set it up plus consumes more memory which can be used for something else. imho cross product once per vertex rules.
not much time to look through the code either but important to say that giving a guess the transformation is wrong here. also how do you compute the tangent and binormal before using them?
I am starting to think that there is a problem with the texture space transformation too. I will go ahead and give the code below. The code adds a single polygon to a mesh. I updated the code since the first post and I am not sure whether this works for polygons with more than 3 vertices but right now I only work with triangles so it shouldn’t matter.
V0,V1,V2 are the vertices of the triangle and S and T are texture coordinates and I am solving the following system:
-compute face normal
-compute face tangent
-for each vertex in the polygon
----compute the new average of the normal/tangent/bitangent of the vertex in the mesh
-add polygon to the mesh