内容引自《RealTimeRendering3rd》在计算机图形学中,纹理贴图是使用图像、函数或其他数据源来改变物体表面外观的技术。例如,可以将一幅砖墙的彩色图像应
内容引用自《Real Time Rendering 3rd》
在计算机图形学中,纹理贴图是一种使用图像、函数或其他数据源来改变物体表面外观的技术。 例如,可以将砖墙的颜色图像应用于多边形,而无需精确表示砖墙的几何图形。 观察此多边形时,此彩色图像出现在多边形所在的位置。 只要观察者没有接近该墙,他们就不会注意到其中的几何细节的不足(例如,事实上砖和砂浆的图像显示在平滑的表面上的事实)。 这样将图像和物体表面组合在一起,可以在建模、存储空间和速度方面节省很多资源。
1 .纹理流水线纹理是一种“建模”物体表面属性的高效技术。 图像纹理中的像素通常称为纹理,以区别于屏幕上的像素。 通过将“投影方程”(projector function )应用于空间中的点,可以获得一系列与纹理相关的数值,称为“参数空间值”(parameter-spacevalues )。 此外,在该过程中,通过使用一个或多个映射函数来映射(pararace ),也称为纹理映射
UV mapping使2D图像上的各点正确对应于3D模型物体的表面,在点与点之间的间隙位置进行图像的平滑插值处理。
上图中介绍的纹理管线概述如下。
第一步。 通过将“投影函数”(projector function )应用于空间中的点,可以获得一系列有关纹理的数值,称为“参数空间值”(parameter-space values )。 第二步。 在使用这些新值访问纹理之前,可以使用一个或多个映射函数corresponder function将参数空间值parameter-space values转化为纹理空间。 第三步。 这些“纹理空间值”(texture-space locations )可用于从纹理中检索“合适的颜色值”(obtain value )。 步骤4。 使用值转换函数value transform function对搜索结果进行值转换,最后使用新值更改材质和着色法线等曲面特性。 具体例子:找到点(例如-2.3、7.1、88.2 )在物体空间中的位置) x、y、z ),并对该位置应用投影函数。 此投影函数通常将向量(x,y,z )转换为二元向量(u,v )。 本示例中使用的投影函数是一种类似于投影仪的正交投影,用于将有光泽的砖墙图像投影到多边形曲面上。 想想砖墙的一侧吧。 实际上,此投影过程是将砖墙平面上的点转换为值域介于0和1之间的一对(u,v )值。 如图所示,(0.32,0.29 )是由此投影函数获得的uv值。 另一方面,由于我们图像的分辨率为256 x 256,所以256分别乘以(0. 32,0.29 ),去掉小数点,得到纹理坐标(81,74 )。 通过该纹理坐标,可以在纹理图上找到与坐标相对应的色值,因此,接下来,平铺图像上的像素位置将找到[ 81,74 ]点,从而获得颜色[0. 9,0.8,0.7 ]。 由于原始砖墙的颜色太暗,因此使用值转换函数将每个向量乘以1.1将产生——种颜色的纹理管线处理值(0.99、0.88、0.77 )。
1.1“投影函数”(projector function )的作用是将空间中的三维点转换为纹理坐标,获取曲面的位置并将其投影到参数空间中。
在美术建模中,投影结果通常存储在模型的顶点数据中。
各种常见投影的不同点:
球面投影。 球面投影将点投影到位于点中心的虚拟球体上,方法与Blinn和Newell中的环境映射方法相同。 圆柱投影。 与球体投影类似,圆柱体投影计算纹理坐标u,而另一个纹理坐标v计算沿圆柱体轴的距离。 这种投影方法适用于具有自然轴的物体。 例如,如果旋转表面,且表面接近垂直于圆柱轴线,则会发生变形。 平面投影(The planar projection )。 平面投影类似于x射线滑动投影,它沿一个方向投影,并将纹理应用于物体的所有表面。 通常,此方法使用正交投影将纹理贴图应用于人物。 它将模型视为纸娃娃,并在模型前后粘贴不同的纹理。
1.2映射函数的作用是将参数空间坐标映射为纹理空间位置
已知图像出现在物体表面的(u,v )位置,uv值的正常范围在(0,1 )的范围内。 超过该值域的纹理可以由映射函数(The Corresponder Function )来确定其显示方法。
Warapping Mode图之间的拼接模式
在OpenGL中,这种映射函数被称为“封装模式”,并且在直接3d中,这种函数被称为“寻址模式” 最常见的映射
射函数有以下几种: 重复寻址模式,wrap (DirectX), repeat (OpenGL)。图像在表面上重复出现。如果纹理坐标超过1,那么整数部分将会被舍弃,直接使用小数部分进行采样。这样的结果是纹理将会不断重复。镜像寻址模式,mirror。图像在物体表面上不断重复,但每次重复时对图像进行镜像或者反转。夹取寻址模式,clamp (DirectX) ,clamp to edge (OpenGL)。夹取纹理寻址模式将纹理坐标夹取在[0.0,1.0]之间,也就是说,在[0.0,1.0]之间就是把纹理复制一遍,然后对于[0.0,1.0]之外的内容,将边缘的内容沿着u轴和v轴进行延伸。边框颜色寻址模式,border (DirectX) ,clamp to border (OpenGL)。边框颜色寻址模式就是在[0.0,1.0]之间绘制纹理,然后[0.0,1.0]之外的内容就用边框颜色填充。
重复寻址模式(wrap):
假设我们要创建一个正方形图元,并将纹理坐标声明为(0.0,0.0)、(0.0,3.0)、(3.0,3.0)和(3.0,0.0)。这时,如果我们设置了重复寻址模式,就可以使纹理在U、V方向都重复三次。
镜像寻址模式(mirror):
在我们创建一个正方形图元,为坐标为(0.0,0.0)、(0.0,3.0)、(3.0,3.0)和(3.0,0.0)。我们设置镜像纹理寻址模式,纹理在U、V方向都重复了三次,并且每一行、每一列都与相邻的行和列成镜像关系。
夹取寻址模式(clamp to edge):
创建一个正方形图元,纹理地址分配为(0.0,0.0)、(0.0,3.0)、(3.0,3.0)和(3.0,0.0)。这时,设置夹取纹理寻址模式,纹理将只使用一次,并且最顶一行和最后一列上的像素颜色会一直延伸到图元的最顶端和最右段。
边框颜色寻址模式(clamp to border):
创建一个正方形图元,纹理地址分配为(0.0,0.0)、(0.0,3.0)、(3.0,3.0)和(3.0,0.0)。这时,设置夹取纹理寻址模式,纹理将只使用一次,并且在纹理坐标超过范围的地方使用一个任意的颜色,也就是边界颜色。
1.3
FilterMode 纹理的采样方式
当一个比较小的贴图,贴到一个比较大的3D模型上,就会存在一个问题,3D模型上的点,不会正好对应贴图上的像素,3D模型上的点可能就会落在贴图上像素点与像素点之间。
如果选择Point模式,就会选择贴图对应3D模型上的点,距离最近的一个贴图像素点,来插值采样,纹理像素看起来就会一块块的,形似马赛克。
如果选择Bilinear模式,就会选择贴图对应3D模型上的点,周围的四个贴图像素点,来插值采样,纹理像素看起来就会过渡的更加自然。
如果选择Trilinear模式,还会在Mip map(多级渐远纹理)之间进行混合,如果纹理没有采用Mip map技术,那么Trilinear得到结果跟Bilinear是一样的。
Point:点过滤 - 纹理像素变得块状紧密,
Bilinear:双线性插值
Trilinear:三线插值 - 用于Mip map,对不同的Mip层进行插值,使其过渡的更自然
1.4 UV map(UV贴图,纹理映射)
将2D图像上的每一点精确对应到3D模型物体表面,在点与点之间的间隙位置进行图像光滑插值处理,这就是UV mapping。UV坐标是以左下角为(0,0),右上角为(1,1)
2. Mip maps(多级渐远纹理)
Mip maps是一个逐渐缩小的图像列表,用于优化实时3D引擎的性能。远离相机的物体使用较小的Texture版本。使用Mip maps需要使用33%以上的内存,但不使用它会导致巨大的性能损失。
缺点:运行时占用更多内存,且增加包的容量。因为Mip maps会根据摄像机远近不同而生成对应的八个贴图,运行会加载到内存中。
优点:优化显存带宽,用来减少渲染。因为可以根据距离摄像机远近,选择适合的贴图来渲染。
一般不需要距离摄像机靠近清晰,否则模糊的这种效果,取消勾选Generate Mip Maps选项。
勾选Mip maps,对处理锯齿和闪烁的很有用。
3. Cubemap(天空盒)
Cubemap是六个方形纹理表示对环境的反射集合。六个方形形成围绕物体的假想立方体的面。通常用于捕捉物体的反射和周围环境。例如,天空盒(Skybox)和环境反射(Reflection Probe),可用于模拟不同光滑度平面的反射。
Unity两种创建方式:
从纹理导入创建,Texture Type为Default,Texture Shape为Cube,Unity会自动将纹理转化为Cubemap。Unity支持用六个单独的纹理,创建Cubemap。选择Assets> Create> Legacy> Cubemap。
最好,采用从纹理导入创建Cubemap,这样可以压缩立方体贴图纹理数据,进行边缘修正和光照反射计算,同时还支持HDR。
4. 纹理压缩(Texture Compression)
直接解决内存、带宽问题和缓存问题的一个解决方案是固定速率纹理压缩(Fixed-rateTexture Compression)。通过硬件解码压缩纹理,纹理可以需要更少的纹理内存,从而增加有效的高速缓存大小。至少这样的纹理使用起来更高效,因为他们在访问时消耗更少的内存带宽。
有多种图像压缩方法用于图像文件格式,如JPEG和PNG,但在硬件上对其实现解码会非常昂贵。
ETC
对于OpenGL ES,选择了一种称为ETC(Ericsson texture compression,ETC)的压缩算法。即快速解码,随机访问,无间接查找,速率固定。ETC算法将4×4纹素的块编码为64位,即每个纹理元素4位。
ETC主要有两种方法:ETC1和改进后的ETC2。
基本思想如下图所示。
ETC算法对像素块的颜色(color)进行编码,然后修改每像素的亮度(luminance)以创建最终的纹理颜色。
当前移动平台主流压缩格式的总结:
格式GPU支持描述图片要求PVRTC RGBA/RGBPowerVRIOS平台都支持,支持每个像素2位或者4位的纹理,包含或者不包含alpha通道都可以;PVRTC 2-bpp把一个8×4的像素单元组压成一个64位的数据块,压缩效果比较差;PVRTC 4-bpp把一个4×4的像素单元组压成一个64位的数据块。游戏中使用4位压缩更多。尺寸为2的N次幂,并且宽高相同。ETC1 RGB 4Bit支持Opnegl ES2.0的GPUOpenGL ES2.0版本支持,移动GPU均支持的一个格式,遗憾的是不支持Alpha通道。ETC1把一个4x4的像素单元组压成一个64位的数据块。游戏开发中采用最多的格式,不过麻烦的是需要对Alpha通道进行单独存储。尺寸为2的N次幂,长宽可不同ETC2 ARGB/RGB 4bit支持Opnegl ES3.0的GPUOpenGL ES 3.0以上才支持,补全了ETC1不支持Alpha通道,支持更高质量的压缩。尺寸为4的倍数
ASTC
RGBA/RGB
iOS(A8以上)从IOS9(A8架构)Apple 手机开始支持ASTC压缩格式 ,相对于PVRTC2/4而言,ASTC(4X4)的压缩比会增加到0.25,不过显示效果也会好很多,而且不需要把图片设置为正方形。长宽可不同RGB是一种颜色模型,其中红色,绿色和蓝色以各种方式加在一起,以再现各种颜色。RGBA是具有Alpha通道的RGB版本,支持混合和不透明度更改。
在不同移动GPU平台下选择GPU支持的压缩纹理,就可以在不需要CPU解压的情况下直接被GPU采样,节省CPU内存和带宽,也可以节省存储的体积。如果目标平台不支持设置的压缩格式,纹理将解压为RGBA32或者RGB24,浪费CPU时间和内存。
在实际开发中,一般iOS选择RGBA ASTC 4* 4 block,Android选择RGBA ETC 2 8bits。
5. Normal Map(法线贴图)
凹凸贴图是指计算机图形学中在三维环境中通过纹理方法来产生表面凹凸不平的视觉效果。后来的Normal Mapping,Parallax Mapping,Parallax Occulision Mapping,Relief Mapping等等,均是基于同样的思想,只是考虑得越来越全面,效果也越来越逼真。
关键思想是访问纹理来修改表面的法线,而不是改变光照方程中的颜色分量。物体表面的几何法线保持不变,我们修改的只是照明方程中使用的法线值。
5.1 凹凸贴图 Bump Mapping
凹凸贴图是指计算机图形学中在三维环境中通过纹理方法来产生表面凹凸不平的视觉效果。它主要的原理是通过改变表面光照方程的法线,而不是表面的几何法线,或对每个待渲染的像素在计算照明之前都要加上一个从高度图中找到的扰动,来模拟凹凸不平的视觉特征,如褶皱、波浪等等。
Blinn于1978年提出了凹凸贴图方法。使用凹凸贴图,是为了给光滑的平面,在不增加顶点的情况下,增加一些凹凸的变化。他的原理是通过法向量的变化,来产生光影的变化,从而产生凹凸感。实际上并没有顶点(即Geometry)的变化。
表示凹凸效果的另一种方法是使用高度图来修改表面法线的方向。每个单色纹理值代表一个高度,所以在纹理中,白色表示高高度区域,黑色是低高度的区域(反之亦然)。
5.2 法线贴图 Normal Mapping 法线贴图(Normal mapping)是凸凹贴图(Bump mapping)技术的一种应用,法线贴图有时也称为“Dot3(仿立体)凸凹纹理贴图”。凸凹与纹理贴图通常是在现有的模型法线添加扰动不同,法线贴图要完全更新法线。与凸凹贴图类似的是,它也是用来在不增加多边形的情况下在浓淡效果中添加细节。但是凸凹贴图通常根据一个单独的灰度图像通道进行计算,而法线贴图的数据源图像通常是从更加细致版本的物体得到的多通道图像,即红、绿、蓝通道都是作为一个单独的颜色对待。
简单来说,Normal Map直接将正确的Normal值保存到一张纹理中去,那么在使用的时候直接从贴图中取即可。
5.3 视差贴图 Parallax Mapping
视差贴图Parallax Mapping,又称为 Offset Mapping,以及virtual displacement mapping,于2001年由yxdzs引入,由Welsh进行了改进和推广。视差贴图是一种改进的Bump Mapping技术,相较于普通的凹凸贴图,视差贴图技术得到凹凸效果得会更具真实感(如石墙的纹理将有更明显的深度)。视差贴图是通过替换渲染多边形上的顶点处的纹理坐标来实现的,而这个替换依赖于一个关于切线空间中的视角(相对于表面法线的角度)和在该点上的高度图的方程。简单来说,Parallax Mapping利用Height Map进行了近似的Texture Offset。
5.4 浮雕贴图 Relief Mapping
我们知道,Parallax Mapping是针对Normal Mapping的改进,利用HeightMap进行了近似的Texture Offset。而Relief Mapping是精确的Texture Offset,所以表现力上应该是比较完美的。相较于视差贴图(左),浮雕贴图(右)可以实现更深的凹凸深度。
相较于Parallax Mapping,浮雕贴图(Relief Mapping)可以实现更深的凹凸深度。浮雕贴图方法不仅更容易提供更深的深度,还可以做出自阴影和闭塞效果,当然算法也稍稍有点复杂,具体细节可以参考这篇中文文献:http://www.ixueshu.com/document/3dc4369a761ca0d6318947a18e7f9386.html,而如果要用一句话概括Relief Mapping,将会是:“在Shader里做光线追踪”。