纹理是什么?
纹理的概念
一种可供着色器读写的结构化存储形式
任何图片都可以作为纹理
(但纹理就是图片并不正确,因为纹理并不一定是图片,处理包含具体储存的信息以外,还会包含纹理采样的一些设置)
纹理为何重要?
因为纹理很划算
牺牲几何细节 = 建模工作量 ⬇⬇
存储空间 ⬇
读取速度 ⬆
纹理管线
纹理管线的工作流程
模型空间位置=>投影函数=>纹理映射=>纹理坐标=>通讯函数=>新纹理坐标=>纹理采样(避免依赖纹理读取)=>纹理值
投影函数:获取要渲染的位置,将它从模型空间投影到纹理坐标空间中,转化成纹理坐标,也就是UV坐标(这里的投影与摄像机投影是完全不同的,这里是纹理投影。投影函数通常在建模流程中俗称“展UV”的阶段使用,将投影的结构存储在顶点数据中,一般情况下我们是不会用到这个东西的)
纹理采样设置之wrap Mode(包装模式)
决定UV值在[0,1]以外的表现
OpenGL--“包装模式”(Wrapping Model)
Directx--“纹理寻址模式”(Texture Addressing Mode)
Wrap Mode包装模式
Repeat:重复
Mirror:在重复的同时加镜像或反转的效果(左右镜像,上下反转)
Clamp:超出范围坐标的颜色值在该设置下为图形的边缘
Border:使用一个定值给超出范围的部分进行填充
纹理采样设置之Filter Mode(过滤设置)
放大Magnification
Falter Mode滤波模式
【最近邻nearest neighbor】滤波
最近邻:取最临近的1个像素,
a) 由于多个像素可能取到同一个临近像素,会造成像素化
b) 省消耗
【Bilinear双线性】滤波
双线性插值:取最临近的4个像素
【Trilinear立方卷积】滤波
立方卷积:不仅取最临近的4个像素,还有它们的变化率
Quilez光滑曲线
光滑曲线插值:在纹理坐标输入双线性插值之前额外处理,2和3的折中
兰索思插值:8×8像素
纹理缩小导致的颜色丢失和闪烁情况
MipMap多级渐远纹理
Mipmap:金字塔,上一层是下一层4个像素的均值
a) 占用内存只增加三分之一
b) 过度模糊
MipMap:如何选择正确的Level
各向异性过滤Anisotropic Filtering
积分图 Summed-Area Table
unity/UE4对于异性过滤后纹理内存的问题
为什么在Unity/UE4上,开启各向异性过滤之后纹理内存不是3倍而仅仅是1/3而已呢?
优化与纹理应用
CPU渲染优化常见方式 — 纹理图集/数组
GPU渲染优化常见方式 — 纹理压缩
减少了资源在CPU中进行解压缩的过程
减小了包体大小,减少了数据量级,减轻了带宽计算的压力
内存的使用效率更高
Cubemap立方体贴图
使用三维纹理坐标对立方体映射进行采样
根据OPENGL
+x代表右,-x代表左
+y代表上,-y代表下
+z代表后,-z代表前
假设这个矢量是(-3.2,5.1,-8.4),那我们就用-z面,坐标(-3.2/8.4,5.1/8.4),再转化为[0,1]的范围,所以最后用来索引纹理的坐标就是((-3.2/8.4+1)/2,(5.1/8.4+1)/2)。
凹凸贴图 Bump Mapping
在不增加顶点的情况下
通过改变几何体表面各点的法线
使本来是平的东西看起来有凹凸的效果
整个过程我们并没有真正改变顶点的高度
而是定义了一个虚拟的高度
位移贴图 Displacement Mapping
凹凸贴图是模拟,虚假的移动
而位移贴图是真的把顶点作了位置的移动
作业
Filter Mode :
1、最近邻:取最临近的像素
2、双线性插值:取2x2线性插值
3、立方卷积:取4x4,加变化率
4、光滑曲线:效果介于2、3之间
纹理优化方式和原理:
1、CPU优化:纹理图集、纹理数组,减少DrawCall
2、GPU优化:纹理压缩,降低带宽