背景
根据切线空间的理论,可以得到TBN矩阵用于将点从世界空间变化到切线空间。使用法线纹理时,可以将光照变量变换到切线空间(使用 T B N − 1 TBN^{-1} TBN−1)也可以将切线空间采样到的法线变换到世界空间(使用 T B N TBN TBN)。使用第一种方法的优势是可以把原本在Fragment Shader(fs)中的计算移到Vertex Shader(vs)中进行计算,这里做一下简单的推导。
推导
每个顶点有其各自的光照变量,这里以viewDir,从顶点到相机的向量为例。同时三个顶点共用一个TBN矩阵
如果是在fs中进行计算,上述的变量在经过传递时会被进行透视校正插值,这里不考虑具体的系数计算方法,假设系数为 α , β , γ \alpha, \beta, \gamma α,β,γ.
那么,fs中的viewDir为:
v i e w D i r p = α ⋅ v i e w D i r A + β ⋅ v i e w D i r B + γ ⋅ v i e w D i r C viewDir_p = \alpha\cdot viewDir_A + \beta \cdot viewDir_B + \gamma \cdot viewDir_C viewDirp=α⋅viewDirA+β⋅viewDirB+γ⋅viewDirC
T B N − 1 ⋅ v i e w D i r p = α ⋅ T B N − 1 ⋅ v i e w D i r A + β ⋅ T B N − 1 ⋅ v i e w D i r B + γ ⋅ T B N − 1 ⋅ v i e w D i r C TBN^{-1} \cdot viewDir_p = \alpha\cdot TBN^{-1} \cdot viewDir_A + \beta \cdot TBN^{-1} \cdot viewDir_B + \gamma\cdot TBN^{-1} \cdot viewDir_C TBN−1⋅viewDirp=α⋅TBN−1⋅viewDirA+β⋅TBN−1⋅viewDirB+γ⋅TBN−1⋅viewDirC
而在vs中计算:
v i e w D i r A ′ = T B N − 1 ⋅ v i e w D i r A v i e w D i r B ′ = T B N − 1 ⋅ v i e w D i r B v i e w D i r C ′ = T B N − 1 ⋅ v i e w D i r C viewDir_A'= TBN^{-1} \cdot viewDir_A \\ viewDir_B'= TBN^{-1} \cdot viewDir_B \\ viewDir_C'= TBN^{-1} \cdot viewDir_C viewDirA′=TBN−1⋅viewDirAviewDirB′=TBN−1⋅viewDirBviewDirC′=TBN−1⋅viewDirC
从而在fs中我们会得到:
v i e w D i r p ′ = α ⋅ v i e w D i r A ′ + β ⋅ v i e w D i r B ′ + γ ⋅ v i e w D i r C ′ = α ⋅ T B N − 1 ⋅ v i e w D i r A + β ⋅ T B N − 1 ⋅ v i e w D i r B + γ ⋅ T B N − 1 ⋅ v i e w D i r C viewDir_p' = \alpha\cdot viewDir_A' + \beta \cdot viewDir_B' + \gamma \cdot viewDir_C' \\ = \alpha\cdot TBN^{-1} \cdot viewDir_A + \beta \cdot TBN^{-1} \cdot viewDir_B + \gamma\cdot TBN^{-1} \cdot viewDir_C viewDirp′=α⋅viewDirA′+β⋅viewDirB′+γ⋅viewDirC′=α⋅TBN−1⋅viewDirA+β⋅TBN−1⋅viewDirB+γ⋅TBN−1⋅viewDirC