凹凸纹理基本概念
凹凸纹理是用来做什么的?
纹理除了可以用来进行颜色映射外,另一种常见的应用就是进行凹凸映射
凹凸映射的目的是使用一张纹理来修改模型表面的法线,让我们不需要增加顶点,就可以让模型看起来有凹凸效果。
原理:
光照的计算会利用法线参与计算。使用凹凸纹理的法线参与计算,可以呈现出更丰富的视觉效果。
作用:
凹凸纹理最大的作用就是让模型可以在不添加顶点(不增加面)的情况下通过凹凸映射将凹凸纹理中的法线信息映射到模型中,让模型看起来拥有更多的细节,是一种视觉上的“欺骗”技术。
纹理贴图类型
高度纹理贴图
高度纹理贴图 简称高度图
他存储了模型表面上每个点的高度信息,通常使用灰度图像(RGB值相同)来表示。
其中不同的灰度值表示不同的高度(较亮区域通常对应较高的点,较暗的区域对应较低的点)。
它主要用于模拟物体表面的位移。
存储规则:
图片中每一个像素点的RGB值都是相同的,表示高度值。A值通常为1。
高度值范围一般为0到1,0代表最低、1代表最高。
优点:
可以通过高度图很明确的知道模型表面的凹凸情况
缺点:
无法在Shader中直接得到模型表面点的法线信息(需要通过计算得到,会额外增加性能开销)。
所以在使用凹凸纹理时,通常会使用法线纹理贴图。
法线纹理贴图
法线纹理贴图一般简称法线贴图或法线纹理
它存储了模型表面上每个点的法线方向。
存储规则:
图片中的RGB值分别存储法线的X、Y、Z分量值,取值在[0,1]之间
A值可以存储其他信息 如材质光滑度等。
优点:
从法线贴图中取出的数据便是法线信息,可以直接简单处理后就参与光照计算,性能表现更好
缺点:
无法直观的看出模型表面的凹凸情况
法线纹理贴图读取分量数据的规则
由于法线XYZ分量范围在[-1,1]之间
而像素RGB分量范围在[0,1]之间
因此我们需要做一个映射计算
存储图片时:
像素分量 = (法线分量 + 1) / 2
因此当我们取出像素分量使用时需要进行逆运算
读取数据时:
法线分量 = 像素分量 * 2 - 1
两种法线纹理贴图的存储方式
法线纹理贴图中主要存储法线信息,
而法线信息其实就是个方向向量,而方向向量就得有相对坐标系
因此,法线贴图的存储方式按相对坐标系有两种方式:
- 基于模型空间的法线纹理
- 基于切线空间的法线纹理
基于模型空间的法线纹理
模型数据中自带的法线数据,就是定义在模型空间中的,因此最直接的存储法线贴图数据的方式 就是存储基于模型空间下的法线信息。
由于模型空间中每个点存储的法线方向是各式各样的(因为原点是模型的原点)
比如:
法线(0,1,0)映射到像素后是 (0.5,1.0.5) 绿色
法线(0,-1,0)映射到像素后是 (0.5,0,0.5) 紫色
因此基于模型空间的法线纹理一般是五颜六色的
这种法线纹理贴图数据取出来直接参与Shader计算即可
基于切线空间的法线纹理
虽然基于模型空间的法线纹理贴图看起来很符合计算需求
但是在实际开发时,美术同学给到我们的法线贴图一般都是基于切线空间的
每个顶点都有自己的切线空间
在切线空间下,原点为顶点本身
X轴:顶点切线
Z轴:法线方向(顶点的原法线)
Y轴:X和Z的叉乘结果,也被称为副切线
切线空间下的法线纹理贴图是蓝色的原因
在切线空间下,如果该顶点的法线不变化(不需要“凹凸感”)那么它的坐标是(0,0,1)
因为在切线空间下,Z轴就是原法线方向
因此:
法线(0,0,1)映射到像素后是 (0.5,0.5,1) 浅蓝色
这个浅蓝色就是 切线空间下法线贴图 存在大片蓝色的原因
因为大部分顶点的法线和模型本身法线是一致的 只有凹凸部分的颜色才会有些许差异
这种法线纹理贴图数据取出来后需要进行坐标空间转换 再参与Shader计算
为什么要使用切线空间下的法线纹理贴图
- 可以用于不同模型(如果模型空间下法线,不能用于其他模型)
- 方便处理模型变形
- 可以复用,例如(一个砖块,6个面贴图都是一样的,可以只用一张法线贴图即可用于6个面计算)
- 可以压缩(可以只存储两个轴的分量)
- 方便制作UV动画(UV坐标改变可以实现凹凸移动效果,如果是模型空间下法线贴图表现会有问题 等等)
总结
凹凸纹理是用来做什么的?
通过高度纹理或法线纹理在不添加顶点(不增加面)的情况下让模型看起来同样充满细节(凹凸感) 原理:计算“假”凹凸面时,使用“真”凹凸面的法线参与计算
高度纹理贴图
RGB都存储高度值,表现为一张灰度图,由于需要更多额外计算,我们一般不使用
法线纹理贴图
RGB分别存储法线的XYZ值,有相对模型空间(彩色)和切线空间(蓝色)两种法线贴图
为什么要使用切线空间下的法线纹理贴图
切线空间法线贴图虽然要产生额外计算,但是能让法线贴图更加的通用,灵活