GAMES101学习笔记(五):Texture 纹理(纹理映射、重心坐标、纹理贴图)
文章目录
- 纹理映射 Texture Mapping
- 插值 Interpolation
- 重心坐标 Barycentric Coordinates
- 应用纹理 Applying Textures
- 纹理太小的问题 - 插值
- 纹理过大的问题 - 多级渐远纹理Mipmap
- 各种纹理贴图
- 环境光贴图 Environment Map
- 凹凸贴图 Bump Mapping
- 位移贴图 Displacement mapping
- 程序纹理 Procedural textures
- 预计算着色 Precomputed Shading
- 体渲染 Solid modeling & Volume rendering
课程资源:GAMES101-现代计算机图形学入门-闫令琪
Lec9 学习笔记:
Lecture 09 :Shading 3 (Texture Mapping Cont.) ——着色(插值、高级纹理映射)
纹理映射 Texture Mapping
任何一个三维物体的表面都是二维的,展开的二维图像就是纹理(Texture)
纹理映射(Texture Mapping)的基本原理 是在三维物体表面和二维纹理图像之间建立起一种映射关系,将纹理图像中的颜色、图案等信息依照该映射关系赋予物体表面相应位置,以此增强物体渲染的真实感与细节丰富度。
具体而言,为物体表面的各个点设定纹理坐标(通常以二维的UV坐标来表示)如下图,
U坐标对应纹理图像的水平方向,取值范围一般是0到1,类比图像的横坐标;
V坐标对应纹理图像的垂直方向,取值范围同样通常为0到1,类似图像的纵坐标。
在图形渲染过程中,根据物体表面各点的纹理坐标去查找纹理图像中对应位置的像素颜色值,随后把获取到的这些颜色值应用到物体表面对应的点上,就好像给物体“穿上”了带有特定图案和颜色的“外衣”一样。
例如,要让一个简单的长方体模型呈现出木质纹理,就可以把一张木质纹理的图片通过合理的纹理映射,依据长方体表面各点的纹理坐标与纹理图像建立联系,使得长方体看起来像是用木头制作而成的。
纹理可以被多次使用
纹理本身设计可以无缝衔接:tilable,称之为tiled texture
- 纹理(Texture):本质上是二维的图像数据,其来源可以是各种常见格式存储的图片,像PNG、JPEG等格式的文件,经过适当的图形处理转换后,成为能够贴合到物体表面的素材,其中蕴含了各式各样的颜色、图案以及细节等视觉元素,能够极大地丰富物体的外观表现。
- 纹理坐标(Texture Coordinates):又称UV坐标,是专门定义在物体表面的二维坐标体系,其核心作用是明确物体表面的每个点在纹理图像中对应的具体位置。每个顶点都会附带一组UV坐标值,其中U方向用于定位纹理图像中的水平位置,V方向用于定位垂直位置,并且这两个坐标值大多限定在0到1的区间内,以确保准确地从纹理图像里获取相应像素的颜色信息并应用到物体表面。
- 纹理采样(Texture Sampling):在渲染阶段,基于物体表面各点的纹理坐标从纹理图像当中获取相应像素颜色值的操作即为纹理采样。由于实际应用中纹理坐标可能出现小数情况,或者因某些变换超出常规的0到1取值范围,所以需要运用特定的采样方式(例如最近邻采样、线性采样、双线性采样等)来确定最终获取的颜色值,进而保证纹理映射所呈现的视觉效果既合理又具有高质量。
插值 Interpolation
-
为什么我们需要插值? Why do we want to interpolation?
很多操作都是在顶点上完成,我们希望把在顶点上得到的结果,平滑过渡的应用在三角形内。 -
需要插值什么内容? What do we want to interpolation?
纹理坐标、颜色、法向量等等 -
怎样做插值?
使用重心坐标(Barycentric Coordinates)用来做三角形内的插值。
重心坐标 Barycentric Coordinates
三角形所在平面内的点,都可以表示成ABC三个顶点的坐标的线性组合。(需要满足α+β+γ=1,且非负)
这个线性组合的系数组成的坐标即重心坐标(α,β,γ)
详解重心坐标
重心会将三角形均等的分为3个等面积的三角形。
利用重心坐标插值的方法,投影前后的重心坐标可能会变化,所以需要在对应的阶段计算对应的重心坐标来做插值,不能随意复用
应用纹理 Applying Textures
怎样将纹理应用在渲染中
点上计算得到插值出来的UV坐标,然后在纹理上查询,之后根据需要应用(图中为简单应用,直接赋值)
但在实际工作中并没有这么简单,会有很多问题:纹理太小的问题,纹理太大的问题
纹理太小的问题 - 插值
纹理分辨率太小,多个pixel(像素)映射到了同一个texel(纹理像素,纹素)
这是相对简单的一种情况,解决方法是使用插值:
- 双线性插值 Bilinear Interpolation
取周围4个点做水平插值+竖直插值
双线性插值 - 双三次插值 Bicubic Interpolation
取周围16个点也是做竖直和水平的插值
双三次插值算法(bicubic interpolation)与图形学和计算方法的关系
纹理过大的问题 - 多级渐远纹理Mipmap
纹理分辨率过大时,一个pixel对应了多个texel → 采样频率不足导致走样(摩尔纹+锯齿)
这是相对复杂的一种情况,我们可以用处理走样的方法来处理,即使用超采样,提高采样频率,但这样的算法效率很低。
这里我们换一种思路:采样会引起走样,那么我们不采样,只得到一定范围的平均值。
这是一个算法中常见的问题——点查询与范围查询的问题(Point Query vs. Range Query):
- 点查询,给出一个点,得到一个点的值
- 范围查询,不采样,给出一个区域,得到区域的(平均)值
在图形渲染中,我们引入一种新的概念——Mipmap(多级渐远纹理)
Mipmap可以进行快速的范围查询,但是是近似的,并且只能正方形。
在渲染之前先生成一系列mipmap(也叫做图像金字塔)
也是一种空间换时间的方法,额外多花了1/3的存储空间。
单纯采用Mipmap会把远处的细节都模糊掉,这不是我们想要的效果。
-
各向异性过滤(Anisotropic Filtering)
各向异性的意思是,在不同的方向上它的表现各不相同。
各向异性过滤允许我们对长条的区域进行范围查询,但是不能用于斜着的区域。
生成各向异性过滤的图(Ripmaps)的开销是原本的三倍。 -
EWA过滤
把任意不规则的形状拆成很多不同的圆形,去覆盖这个形状
多次查询自然可以覆盖,但是耗时大
各种纹理贴图
在GPU的视角,纹理就是一块内存,可以在这片区域上做查询
环境光贴图 Environment Map
把来自各个方向的光照记录下来,只记录方向,假设环境光来自无限远,没有深度意义。
也就是说纹理可以用来表示环境光(Blinn-Phong光照模型)
- 球面环境映射 Spherical Environment Map
把环境光记录在球体表面上,存在拉伸和扭曲问题。 - 立方体贴图 Cube Map
把环境光记录在立方体的表面上,可以减少扭曲的程度。
问题也存在,球面可以很方便得到某一方向的光照,但是现在还要判断这个方向记在立方体的哪一个面上。
凹凸贴图 Bump Mapping
凹凸贴图记录了高度移动,不改变几何信息。
贴图作出人为的假的法线,由此得到假的着色效果,产生凹凸效果。
通过自定义的高度差,逐像素地扰动法线方向,法线方向一改,着色结果就会发生变化
凹凸贴图和法线贴图都是为了改变法线,凹凸贴图改变了点的高度后自己计算新法线。
位移贴图 Displacement mapping
与凹凸贴图的输入相同,但是位移贴图真正改变几何信息,对顶点做位移。
位移贴图更逼真,因为凹凸贴图在边界上会露馅,也无法处理阴影。
但位移贴图要求模型的三角形足够细致,且运算量更高。
DirectX有Dynamic的插值法,根据需要对模型做插值,看情况把模型变得细致
程序纹理 Procedural textures
之前我们对纹理的定义都是一张二维的图。实际上也存在三维的纹理,定义了空间中任意一点的值
对于这种纹理,并没有真正生成这个纹理的图
它们定义了三维空间的噪声函数,函数经过各种处理,可以变成需要的样子
预计算着色 Precomputed Shading
用空间换时间,先计算好环境光遮蔽贴图(Ambient occlusion texture map),然后再把纹理贴上
体渲染 Solid modeling & Volume rendering
三维纹理广泛应用到体渲染之中,比如核磁共振等扫描后,得到体积的信息,通过这些信息进行渲染得到结果。