Light doesn't work without bump map

Started by
25 comments, last by Medo Mex 10 years, 9 months ago

@Pink Horror: Check out my shader above, when I apply bump map it DOES look very well.

When I remove the bump map I don't see the light, I tried to move the terrain upwards, now I get to see the light, I also get to see the light when I set large amount of "point light radius".

I guess the light get positioned incorrectly when I don't use bump map.

In Vertex Shader, I'm transforming the normal as the following:


OUT.Normal = mul(IN.Normal, (float3x3)worldInverseTransposeMatrix);

Why are you computing this normal?

Advertisement

@Pink Horror: I think I should transform it in the vertex shader? Correct me if I'm wrong.

Of course you need to transform the normal because it depends on object orientation.

Can you create minimal project, zip it and share a link here so it will be easier to help you.

@belfegor: I created a new project, in this project I have a plane and a box

When I set:

Light position to (XYZ: 0.0f, 0.0f, 0.0f)

Plane position to (XYZ: 0.0f, 0.0f, 0.0f)

Light range: 5000.0f

I don't see the light

BUT, when I move the light up, I start to see the light:

Light position to (XYZ: 0.0f, 10.0f, 0.0f)

Plane position to (XYZ: 0.0f, 0.0f, 0.0f)

Light range: 5000.0f

Project: http://www.2shared.com/file/F-SF9SLo/Light_Problem_Sample.html

EDIT:

Another problem I noticed now, when I apply bump map, the light get positioned incorrectly.

I do that by replacing float3 n = normalize(IN.Normal); to normalize(tex2D(normalMap, IN.UV).rgb * 2.0f - 1.0f); and passing a bump map texture to the shader.

Try the project from attachment.

edit: Forgat to note about camera controls: w-s-a-d movement, left mouse press and move to rotate.

@belfegor: When I apply bump map, the light change its position to invalid position.

I modified your project to support bump mapping and I can notice the problem:

[attachment=17043:Terrain modified.rar]

After running the program hold 'B' to enable bump mapping and see that the light position is not the same.

You can't just stitch normal map texture and be done, you need tangent and binormal vectors in mesh VB to have bump mapping! Try this now.

@belfegor: I'm using Panda Exporter in 3Ds Max, it's not exporting the mesh with tangent and binormal...

Well you can always compute them, with something similar to this:


/// <summary>
        /// Given the 3 vertices (position and texture coordinate) and the
        /// face normal of a triangle calculate and return the triangle's
        /// tangent vector. This method is designed to work with XNA's default
        /// right handed coordinate system and clockwise triangle winding order.
        /// Undefined behavior will result if any other coordinate system
        /// and/or winding order is used. The handedness of the local tangent
        /// space coordinate system is stored in the tangent's w component.
        /// </summary>
        /// <param name="pos1">Triangle vertex 1 position</param>
        /// <param name="pos2">Triangle vertex 2 position</param>
        /// <param name="pos3">Triangle vertex 3 position</param>
        /// <param name="texCoord1">Triangle vertex 1 texture coordinate</param>
        /// <param name="texCoord2">Triangle vertex 2 texture coordinate</param>
        /// <param name="texCoord3">Triangle vertex 3 texture coordinate</param>
        /// <param name="normal">Triangle face normal</param>
        /// <param name="tangent">Calculated tangent vector</param>
        public static void CalcTangent(ref Vector3 pos1,
                                       ref Vector3 pos2,
                                       ref Vector3 pos3,
                                       ref Vector2 texCoord1,
                                       ref Vector2 texCoord2,
                                       ref Vector2 texCoord3,
                                       ref Vector3 normal,                                       
                                       out Vector4 tangent)
        {
            // Create 2 vectors in object space.
            // edge1 is the vector from vertex positions pos1 to pos3.
            // edge2 is the vector from vertex positions pos1 to pos2.
            Vector3 edge1 = pos3 - pos1;
            Vector3 edge2 = pos2 - pos1;
            
            edge1.Normalize();
            edge2.Normalize();

            // Create 2 vectors in tangent (texture) space that point in the
            // same direction as edge1 and edge2 (in object space).
            // texEdge1 is the vector from texture coordinates texCoord1 to texCoord3.
            // texEdge2 is the vector from texture coordinates texCoord1 to texCoord2.
            Vector2 texEdge1 = texCoord3 - texCoord1;
            Vector2 texEdge2 = texCoord2 - texCoord1;

            texEdge1.Normalize();
            texEdge2.Normalize();

            // These 2 sets of vectors form the following system of equations:
            //
            //  edge1 = (texEdge1.x * tangent) + (texEdge1.y * bitangent)
            //  edge2 = (texEdge2.x * tangent) + (texEdge2.y * bitangent)
            //
            // Using matrix notation this system looks like:
            //
            //  [ edge1 ]     [ texEdge1.x  texEdge1.y ]  [ tangent   ]
            //  [       ]  =  [                        ]  [           ]
            //  [ edge2 ]     [ texEdge2.x  texEdge2.y ]  [ bitangent ]
            //
            // The solution is:
            //
            //  [ tangent   ]        1     [ texEdge2.y  -texEdge1.y ]  [ edge1 ]
            //  [           ]  =  -------  [                         ]  [       ]
            //  [ bitangent ]      det A   [-texEdge2.x   texEdge1.x ]  [ edge2 ]
            //
            //  where:
            //        [ texEdge1.x  texEdge1.y ]
            //    A = [                        ]
            //        [ texEdge2.x  texEdge2.y ]
            //
            //    det A = (texEdge1.x * texEdge2.y) - (texEdge1.y * texEdge2.x)
            //
            // From this solution the tangent space basis vectors are:
            //
            //    tangent = (1 / det A) * ( texEdge2.y * edge1 - texEdge1.y * edge2)
            //  bitangent = (1 / det A) * (-texEdge2.x * edge1 + texEdge1.x * edge2)
            //     normal = cross(tangent, bitangent)

            Vector3 t;
            Vector3 b;
            float det = (texEdge1.X * texEdge2.Y) - (texEdge1.Y * texEdge2.X);

            if ((float)Math.Abs(det) < 1e-6f)    // almost equal to zero
            {
                t = Vector3.UnitX;
                b = Vector3.UnitY;
            }
            else
            {
                det = 1.0f / det;

                t.X = (texEdge2.Y * edge1.X - texEdge1.Y * edge2.X) * det;
                t.Y = (texEdge2.Y * edge1.Y - texEdge1.Y * edge2.Y) * det;
                t.Z = (texEdge2.Y * edge1.Z - texEdge1.Y * edge2.Z) * det;

                b.X = (-texEdge2.X * edge1.X + texEdge1.X * edge2.X) * det;
                b.Y = (-texEdge2.X * edge1.Y + texEdge1.X * edge2.Y) * det;
                b.Z = (-texEdge2.X * edge1.Z + texEdge1.X * edge2.Z) * det;

                t.Normalize();
                b.Normalize();
            }

            // Calculate the handedness of the local tangent space.
            // The bitangent vector is the cross product between the triangle face
            // normal vector and the calculated tangent vector. The resulting bitangent
            // vector should be the same as the bitangent vector calculated from the
            // set of linear equations above. If they point in different directions
            // then we need to invert the cross product calculated bitangent vector. We
            // store this scalar multiplier in the tangent vector's 'w' component so
            // that the correct bitangent vector can be generated in the normal mapping
            // shader's vertex shader.

            Vector3 bitangent = Vector3.Cross(normal, t);
            float handedness = (Vector3.Dot(bitangent, b) < 0.0f) ? -1.0f : 1.0f;

            tangent.X = t.X;
            tangent.Y = t.Y;
            tangent.Z = t.Z;
            tangent.W = handedness;
        }

foe each vertex in your mesh, figure out the other two vertices that make up the triangle using the index array, and call this method.

@belfegor: I'm using Panda Exporter in 3Ds Max, it's not exporting the mesh with tangent and binormal...

You can calculate them as DwarvesH showed or use D3DXComputeTangentFrame as i have written in the demo since you didn't spot it.

This topic is closed to new replies.

Advertisement