法线贴图
法线贴图是使用一张纹理来存储模型表面顶点的法线, 该纹理就叫做法线贴图
通过光照与法线贴图存储的法线计算光照效果,实现模型表面的凹凸质感
也就是使用法线贴图存储的法线计算漫反射与高光的效果,实现凹凸质感
凹凸通过模型表面的明暗效果来实现的凹凸效果
法线贴图分类
切线空间法线贴图:Tangent-Space-Normal Map
模型空间法线贴图:Object-Space-Normal Map
切线空间
对于每一个模型的顶点,都有自己的切线空间
每个顶点都有顶点数据,包含顶点的坐标,法线,切线,纹理坐标,顶点颜色
法线:float3
切线:float4
w:-1或1
当前顶点的切线空间的原点就是该顶点的位置,z轴正方向就是顶点的法线方向,x轴方向就是顶点的切线方向,y轴就是垂直于z轴与x轴的,y轴可以通过法线与切线叉乘得到向量(副切线或副法线),方向由切线的w确定
法线贴图的颜色问题
模型空间
模型空间下的所有顶点的法线使用的是同一个坐标系,法线的值什么情况都可能出现,最终映射到颜色上就是彩色的
切线空间
切线空间的所有顶点的法线使用的都是自己的切线坐标系,切线坐标系的Z轴就是顶法实际的法线方向,法线贴图中存储的法线在没有扰动的情况下,大多都与实际的法线方向接近的,法线贴图存储的法与Z轴的方向接近,那么颜色就偏蓝色
法线贴图与颜色映射
颜色RGB取值范围:0到1
法线XYZ取值范围:认为法线都是单位向量,-1到1
颜色的RGB分量不能存储负值,需要公式来映射
映射公式
ColorNormal:纹理存储的法线,0到1
TangentNormal:实际切线空间的法线,-1到1
ColorNormal = (TangentNormal + 1) / 2
TangentNormal = ColorNormal * 2 - 1
在Shader中,同法线贴图获取每个顶点颜色(纹理采样),颜色就是的ColorNormal, 通过映射公式获取实际切线空间下的法线TangentNormal
通过顶点的UV坐标通过tex2D函数进行纹理采样获取颜色,通过颜色的色值反向映射切线空间下的法线
切线空间的法线存储的内容
一般切线空间的法线贴图只存储xy值,需要同xy值计算得到z值,扰动值对于xy值扰动,扰动后再计算z值
法线都是单位向量
模长为1
x^2 + y^2 + z^2 = 1^2
z = sqrt(1 - x^2 - y^2),sqrt开方
x值与y值变大,z值就变小了,法线的方向就偏离了实际Z轴
扰动就是增大xy值或减小xy值
做乘法运算
扰动的取值一般是[-1.5, 1.5]
x^2 + y^2必须是 <= 1的,否则z值计算不出来
统一空间问题
计算光照效果是,法线或切换与光照方向、观察方向要在同一个空间下
从法线贴图中得到的法线是切线空间下
两种统一
统一到世界空间下计算
统一到切线空间下计算
统一到切线空间计算
切线空间
法线方向
切线方向
副法线或副切线
float3x3(tangent.xyz, binormal, normal)
空间转换矩阵
从模型空间到切线空间的矩阵
tangent.xyz:切线的xyz
binormal:副法线
normal:法线