Loading the model with the normal map is a really interesting implementation. Here is a preview and the embedded WebGL implementation is down below.
Introduction
A normal map is a really special texture type. Rather than define a color or a signal value, it actually defines a vector to represent normal at that pixel point on the geometry. Normal mapping can give us the illusion that the plane has more detail.
Normal mapping involves an additional spatial variation: tangent space,
Mathematical
Thinking about vectors, usually, we first came out the domain is [0, 360), and map to the range [0, 255] we are able to use an image to represent it.
However, when we get the value in Vertex Shader. We usually get for range [0, 1]. Here is the formula.
In addition, this will give us a domain and range of:
Once we get the value of that vector, we need to map those vectors into model space.
The way for doing that is to generate a matrix with the base of the tangent space. And those data actually get from the combination of points and edges. To implement this, we define the horizontal and vertical directions on the normal texture as a tangent, and bitangent directions respectfully.
We will figure out that the Edge of two sides of triangle can represent by a linear equation:
Since the delta of E1 on a tangent is already given by texture coordinate, it should be fine.
We can solve T and B by slove this linear equation. Once we get T and B we could use the cross product to figure out normal.
once we got that, we can use N, T, and B as the base of tangent space in the world space. normalize them and construct them as a matrix, we can easily transform any vector in tangent space to world space.
Implementation
The texture size no matter regular or normal should be pow to 2 based on the WebGL support, And the texture file type should be PNG. You can use the texture here for convenience but also feel free to upload your texture.