US3S2L4——凹凸纹理基本概念
US3S2L4——凹凸纹理基本概念
纹理知识回顾
单张纹理是模型的“皮”,它决定了模型的颜色表现,
在建模时通过纹理隐射技术将顶点和纹理图片建立联系,在模型数据中记录顶点对应的UV坐标,
进行Shader开发时,利用UV坐标即可从纹理图片中取出对应位置的颜色给片元“上色”
凹凸纹理
纹理 除了可以用来进行 颜色映射 外,另外一种常见的应用就是进行 凹凸映射
凹凸映射的目的是使用一张纹理来修改模型表面的法线,让我们不需要增加顶点,而让模型看起来有凹凸效果。
原理:光照的计算都会利用法线参与计算,决定最终的颜色表现效果。
那么在 计算 “假” 凹凸面时,使用“真”凹凸面的法线 参与计算,呈现出来的效果可以以假乱真
左图是真实凹凸表面的光线,右图是不使用真凹凸表面的光线,
想要在非凹凸面上体现凹凸感,就需要通过法线改变光线方向,通过光照模拟出凹凸感
凹凸纹理最大的作用就是让模型可以 在不添加顶点(不增加面)的情况下
让模型看起来同样充满细节(凹凸感),是一种视觉上的“欺骗”技术
下图就是在凹凸纹理的运用,通过一张凹凸纹理改变光照效果,让模型的表面看起来凹凸不平
要进行凹凸映射,目前有两种主流方式:
-
高度纹理贴图:RGB都存储高度值,表现为一张灰度图,由于需要更多额外计算,我们一般不使用
-
法线纹理贴图:RGB分别存储法线的XYZ值,有相对模型空间(彩色)和切线空间(蓝色)两种法线贴图
切线空间法线贴图虽然要产生额外计算,但是能让法线贴图更加的通用,灵活,因此纹理贴图常使用 切线空间法线贴图
通过高度纹理 或 法线纹理在不添加顶点(不增加面)的情况下让模型看起来同样充满细节(凹凸感)
原理:计算 “假” 凹凸面时,使用 “真” 凹凸面的法线参与计算
高度纹理贴图
高度纹理贴图一般简称高度图,它存储了模型表面上每个点的高度信息。
通常它使用灰度图像,其中不同灰度值表示不同高度。
较亮区域通常对应较高的点,较暗的区域对应较低的点。
它主要用于模拟物体表面的位移。
存储规则:图片中的某一个像素点的 RGB 值是相同的,都表示高度值,A值一般情况下为1。高度值范围一般为0~1,0代表最低,1代表最高
- 优点:可以通过高度图很明确的知道模型表面的凹凸情况(通过观察黑白程度来决定凹凸情况)
- 缺点:无法在 Shader 中直接得到模型表面点的法线信息,而是需要通过额外的计算得到,因此会增加性能消耗,所以我们几乎很少使用它。
我们在使用凹凸纹理时,一般都会使用法线纹理贴图
法线纹理贴图
法线纹理贴图一般简称法线贴图 或 法线纹理,它存储了模型表面上每个点的法线方向。
存储规则:图片中的 RGB 值分别存储法线的X、Y、Z分量值,A值可以用于存储其他信息,比如材质光滑度等。
- 优点:从法线贴图中取出的数据便是法线信息,可以直接简单处理后就参与光照计算,性能表现更好
- 缺点:我们无法直观的看出模型表面的凹凸情况
由于法线纹理贴图是我们之后实现“凹凸感”的主要方式,因此我们需要更详细的了解它的存储规则
- 读取分量数据的规则
- 两种法线纹理贴图的存储方式
法线纹理贴图读取分量数据的规则
由于法线方向 XYZ 分量范围在 之间,而像素颜色 RGB 分量范围在 之间,因此我们需要做一个映射计算
存储图片时:
因此当我们取出像素分量使用时需要进行逆运算
读取数据时:
两种法线纹理贴图的存储方式
法线纹理贴图中主要存储法线信息,而法线信息其实就是个方向向量,而方向向量就得有相对坐标系
因此,法线贴图的存储方式按相对坐标系有两种方式:
- 基于模型空间的法线纹理
- 基于切线空间的法线纹理
基于模型空间的法线纹理
模型数据中自带的法线数据,是定义在模型空间中的,因此最直接的存储法线贴图数据的方式,就是存储基于模型空间下的法线信息。
注意:模型数据中的法线数据是 “真” 数据,也就是基于模型的真实存在的面得到的法线信息
法线贴图中对的法线数据是 “假” 数据,是通过人为添加或修改的法线数据,原本模型的面上不存在这些人为添加法线对应的凹凸面
如下图所示,由于模型空间中每个点存储的法线方向是各式各样的,比如:
- 法线 映射到像素后 是 绿色
- 法线 映射到像素后 是 紫色
因此,基于模型空间的法线纹理一般是五颜六色的,这种法线纹理贴图数据取出来直接参与 Shader 计算即可
对于不需要变形的静态物体来说非常有用,因为法线方向不会随着物体的变化而变化。
基于切线空间的法线纹理
虽然基于模型空间的法线纹理贴图看起来很符合计算需求,但是在实际开发时,美术同学给到我们的法线贴图一般都是基于切线空间的
每个顶点都有自己的切线空间,它的 XYZ 轴 及 原点 代表的信息分别如下:
- 原点:顶点本身
- X 轴:顶点切线(通常指向纹理UV坐标的的U方向(水平方向))
- Z 轴:法线方向(顶点的原法线)
- Y 轴:X 和 Z 的叉乘结果,也被称为副切线
在切线空间下,如果该顶点的法线不变化(不需要“凹凸感”)
那么它的坐标是 ,因为在切线空间下,Z 轴就是原法线方向,因此:
法线 映射到像素后 是 也就是 浅蓝色
这个浅蓝色就是 切线空间下法线贴图 存在大片蓝色的原因,因为大部分顶点的法线和模型本身法线是一致的,只有凹凸部分的颜色才会有些许差异
这种法线纹理贴图数据取出来后需要进行坐标空间转换,再参与 Shader 计算
由于切线空间下的法线信息与模型的局部坐标系无关,所以可以在不同的物体上重复使用相同的纹理
使用切线空间下的法线纹理贴图的原因
之所以在实际开发时要使用切线空间下的法线贴图,原因有以下几点:
- 可以用于不同模型 —— 基于某个模型的模型空间的法线贴图只能适配在单一模型上,无法用于其他模型
- 方便处理模型变形 —— 基于顶点空间的法线贴图可以贴在不同或者变形模型的各种面上(因为切线空间的法线信息和模型的局部坐标系无关)
- 可以复用 —— 一个砖块,6个面贴图都是一样的,可以只用一张法线贴图即可用于6个面计算
- 可以压缩 —— 可以只存储两个轴的分量(Y 轴可通过 XZ 轴叉乘得到)
- 方便制作UV动画 —— UV坐标改变可以实现凹凸移动效果,如果是模型空间下法线贴图表现会有问题
等等