Normal Map

Loading the model with the normal map is a really interesting implementation. Here is a preview and the embedded WebGL implementation is down below.
notion image

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.
[0°,360°)[0,255][0\degree, 360\degree) \to [0, 255]
However, when we get the value in Vertex Shader. We usually get for range [0, 1]. Here is the formula.
normal=color21normal = color\cdot2 - 1
In addition, this will give us a domain and range of:
[0,1]3[1,1]3[0, 1]^3 \to [-1, 1]^3
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.
notion image
We will figure out that the Edge of two sides of triangle can represent by a linear equation:
E1=ΔtangentE1Tworld+ΔbitangentE1BworldE2=ΔtangentE2Tworld+ΔbitangentE2BworldE1 = \Delta tangentE1 \cdot T_{world} + \Delta bitangentE1\cdot B_{world}\\E2 = \Delta tangentE2 \cdot T_{world} + \Delta bitangentE2\cdot B_{world}
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.