The problem with trying to achieve per-pixel bump-mapping lies in the concept of trying to find the light vector on a per-pixel basis. The only way I could figure that I could send such data into the fragment shader was to not do that at all. Instead, I made sure that the fragment shader had all the necessary data to do the same thing by itself. In the vertex shader I basically calculated light position as a 3d texture coordinate.
First I needed to find out the position of the light relative to the texture. This value must be the same for each and every vertex that passes through the vertex shader regarding this polygon. To do this I simply multiplied the light vector by the vertex's tangent and saved that value as the x coordinate, then by the binormal and saved that as y, then the normal and saved that as z.
Next what I needed to do this was find out how texture coordinates relate to the geometry coordinates. The answer is the degree the texture is scaled to the polygon. The upper right corner of a texture is always (1.0, 1.0). If I have a polygon that is 10.0x10.0 units and the texture is stretched to fit that entire area, the scale is 10.0:1.
I multiplied the texture scale by the texture coordinate at that particular vertex and then added this result to the new light vector. This resulting vector, the light position as a texture coordinate, gave me a value that was the same for each and every vertex. I sent it off to the fragment shader.
In the fragment shader I subtracted this point from the texture coordinate to the find light vector and scaled it up by 2. I then found the dot product with it and the tangent map (scaled and biased) (N.L), and modulated it with the base map ((N.L)*basemap). The problem here was that the light was reversed, as if the ambient light was bright and the "light" I was moving around actually emitted darkness. To fix this I used the COMP_BIT_ATI modifier on N.L when I was modulating it with the base map. This appeared to work. . .
For some extra detail I created a cheap lightmap in the fragment shader by taking the dot product of N.L with itself ((N.L).(N.L)), modifying it with COMP_BIT_ATI (to reverse it so it was bright in the centre), and then modulating it with (N.L)*basemap.
While it looks substantially better than per vertex bumpmaping on a 4 vertex, 10.0x10.0 square, it doesn't look at all like the square I made up of 200 triangles (10 triangle strips, each triangle 1x1). Here's some screenshots:
Per Pixel Lighting
Edge of the Lightmap
Per Vertex Lighting, 200 triangles
First I needed to find out the position of the light relative to the texture. This value must be the same for each and every vertex that passes through the vertex shader regarding this polygon. To do this I simply multiplied the light vector by the vertex's tangent and saved that value as the x coordinate, then by the binormal and saved that as y, then the normal and saved that as z.
Next what I needed to do this was find out how texture coordinates relate to the geometry coordinates. The answer is the degree the texture is scaled to the polygon. The upper right corner of a texture is always (1.0, 1.0). If I have a polygon that is 10.0x10.0 units and the texture is stretched to fit that entire area, the scale is 10.0:1.
I multiplied the texture scale by the texture coordinate at that particular vertex and then added this result to the new light vector. This resulting vector, the light position as a texture coordinate, gave me a value that was the same for each and every vertex. I sent it off to the fragment shader.
In the fragment shader I subtracted this point from the texture coordinate to the find light vector and scaled it up by 2. I then found the dot product with it and the tangent map (scaled and biased) (N.L), and modulated it with the base map ((N.L)*basemap). The problem here was that the light was reversed, as if the ambient light was bright and the "light" I was moving around actually emitted darkness. To fix this I used the COMP_BIT_ATI modifier on N.L when I was modulating it with the base map. This appeared to work. . .
For some extra detail I created a cheap lightmap in the fragment shader by taking the dot product of N.L with itself ((N.L).(N.L)), modifying it with COMP_BIT_ATI (to reverse it so it was bright in the centre), and then modulating it with (N.L)*basemap.
While it looks substantially better than per vertex bumpmaping on a 4 vertex, 10.0x10.0 square, it doesn't look at all like the square I made up of 200 triangles (10 triangle strips, each triangle 1x1). Here's some screenshots:
Per Pixel Lighting
Edge of the Lightmap
Per Vertex Lighting, 200 triangles