PPT:https://sites.cs.ucsb.edu/~lingqi/teaching/resources/GAMES101_Lecture_09.pdf
一、重心坐标
重心坐标的作用:做三角形内部的插值
我们首先要搞清楚三个问题:
为什么要在三角形内部进行插值?
- 指定顶点的值
- 在三角形内部得到平滑的过渡
我们需要插入什么内容呢?
- 纹理坐标
- 颜色
- 正常顶点
- ......
如何插值?
- 通过重心坐标
什么是重心坐标?
重心坐标定义在三角形上
一个三角形ABC的顶点系(α,β,Γ)--表示三角形上的所有点的集合
该三角形内部的任意一个坐标(x, y)都可以用ABC点的坐标来表示
α,β,Γ的和必须为1,且均为非负数
那么A点的重心坐标是什么呢?
同时也可知道B的重心坐标为(0,1,0),C的重心坐标为(0,0,1)
除此之外,重心坐标还有另一种求法--几何观点--按照面积的比例来求
其中AA,BB,CC分别表示点A,B,C所对的三角形的面积
三角形的重心的重心坐标是什么?
三角形内部任意一点的求法公式(无需记忆):
顶点的线性插值
VA,VB,VC可以i是位置,纹理,坐标,颜色,法线,深度,材质属性等等
二、如何贴纹理
简单的纹理映射:扩散颜色
对于每一个光栅化的屏幕样本(x,y)(通常是像素的中心):
(u,v)=评估(x,y)的纹理坐标(使用重心坐标)
纹理颜色=纹理样本(u,v)
设置样本颜色为纹理颜色(通常是漫反射系数Kd,回想布林冯反射模型)
纹理放大
如果纹理太小了怎么办?
纹理放大的简单案例
当纹理放大时,会出现纹理分辨率不足,但是并不希望这样
取最近的点 双线性插值 双三次插值
纹理上的一个像素---纹理元素,或者称为纹素
双线性插值
想要知道纹理在红点上的值是多少,黑点指的是纹理采样点
按照之前的方法,会取红点最近的点的颜色,但是这样整个格子就都会是一种颜色了
所以我们使用双线性插值法,找红色点邻近的四个点
求红点与周围四个点的水平距离s和竖直距离t(s和t都是0到1的)
线性插值函数lerp(x, v0, v1)
第一次线性插值:水平方向上线性插值得到u0和u1
第二次线性插值:已知u0和u1,在竖直方向上线性插值得到红点
两次线性插值的顺序可以调换
线性插值后的红点综合考虑了周围四个点的颜色,求得了平均值,平滑过渡
如果纹太大了怎么办?
这是更复杂的情况
出现的问题(摩尔纹,走样,锯齿)
距离越远,一个像素覆盖的面积就更大
超级采样是如何抗锯齿的呢?会凑效吗?
- 会奏效,但是消耗太大了!
- 信号变化过快,采样频率跟不上
- 需要更高的采样频率
- 像素会在纹理上覆盖很大的一片区域
另外一种思路:
- 不采样会怎么样?
- 只需要知道一片范围内的平均值!
点查询VS范围查询
不同的像素由于远近的不同,有不同的覆盖范围
引入一个概念--MipMap
什么是MipMap?从一张图生成一系列图
纹理Level0--->分辨率缩小一半--->Level1
它的作用是--允许做范围查询(只能做近似正方形的范围查询)
它的存储是额外存储的三分之一
使用MipMap做近似地在一个正方形范围内做查询,进而得到这个区域内的平均值
如何知道查询区域的大小和形状?
- 任何一个像素都可以映射到纹理上的一个区域,如何得到这个区域?
取一个像素及其它邻接点的中心投射到纹理上(左图到右图)
然后做近似
以L为边长的正方形代替那个不规则图形,也就是左边这个像素在纹理上的映射
如何通过MipMap得到这个正方形区域的颜色呢?
由MipMap的原理可知,这个区域在每一层边长都会减半,面积和像素个数都变成原来的四分之一那么在第D层就只有一个像素,这个像素的颜色就是平均颜色
下图显示的就是每一层的颜色
但是这样好像不太连续,如果我想要知道层数之间(如1.8层)的颜色该怎么办呢?
用插值法(三线性插值),用第一层和第二层得到第1.8层
MipMap的局限性,远处的都糊掉了
各项异性过滤
MipMap只能做对角线上的变换(红色箭头),但是各项异性过滤可以只在水平方向或者竖直方向进行压缩
当进行绿色箭头的反变换时,一个压缩图的像素回到原图之后可能会变成一个长条矩形
所以可以对长条矩形(红色)做一个快速查询
但是对于绿色这样的映射图形就不行了,如何解决?
使用EWA过滤
将不规则的形状拆成很多圆形,每次查询只要查询一个圆形即可,经过多次查询,但是开销大