Games101 图形学入门笔记

纹理的应用

使用采样的像素位置, 然后通过三角形每个顶点上的UV过渡得到这个像素点的UV值,然后通过UV在纹理上的采样得到这个点的color值,然后应用到我们着色模型的KB的比如是高光系数,就可以把这个贴图给贴到我们这个物体上了

演示图片

双线性插值

比如有一张纹理很小,然后要渲染的像素密度很高,模型的精度也很高,那去到纹理里面取值的时候就会不足,也就是纹素(纹素就是纹理上的一个像素,像一张512x512的图就有512x512个纹素),那我们去纹素中取值的时候会出现小数的情况,我们现在的做法就是四舍五入,那就会出现取得色值重复的情况,就会出现图一中小格子状的问题,像马赛克一样,我们想让它像后面两张图一样的效果的话,就需要用到双线性插值去做这个事

演示图片

首先线性插值就是值x在v0到v1这个范围之间的结果,就是v0 + x(v1 - v0),所以我们通过这个线性插值怎么去解决之前的问题呢,已知下面红点就是我们得到的当前纹素的位置,因为他不是整数的,图过小的原因,他不会正好在纹素中心点,那我们可通过这个红点位置x,y和他周围四个像素取到一个s和t的距离,然后已知那四个像素的黑点就是纹素的颜色值,我们只需要通过s插值u00点颜色到u10点颜色得到一个u0的值,相同逻辑能得到水平的另一个u1的值,然后再竖直通过t插值u0,u1得到最终红点处的颜色值,这两种插值方式的处理就叫做双线性插值

演示图片

点查询和范围查询问题

前面图片过小然后运用双线性插值的方法就是解决点查询问题的案例,假设现在有个纹理非常大,然后渲染在小的模型上,会出现一些其他的问题如下面第二张图右边。会出现近处锯齿,远处摩尔纹的问题,也就是走样,问题就是近处和远处的像素点在纹理上采样的范围太大,采样的值就不准确了,那我们当然可以使用抗锯齿去解决这个问题,但是太过消耗,我们可以假设能不能不做采样,直接得到这个最终的平均值呢,这个就叫范围查询,当然这个只是范围查询的其中一种,查询平均值,怎么做呢,就是MipMap

演示图片

演示图片

演示图片

MipMap

演示图片

演示图片

**MipMap范围查询的做法:首先要算出像素在纹理上对应的近似范围,就是拿当前像素的右边和上方的像素点映射到纹理上,然后算这个点在纹理上跟另外两个点连成边的最大值,可通过三角形求出L1和L2这两条边长,这里求出边长以后我们认为这个就是这个范围正方形的边长,然后我们假设我们图示4x4的,我们算出来要取的正方形区域是2x2,那我们就会发现在原始图mipmap为第一层的时候,那我们就是要拿这个正方形区域为1x1的时候的那个纹理上对应的值就是平均值,所以第多少层就等于L的log2,也就是2的多少次幂 **

演示图片

三线性插值

如果在场景中运用mipmap等级时,由近到远应用不同等级mipmap时,会出现中间既不是第一级也不是第二级的情况时我们需要应用两级之间的插值色值,那就需要运用三线性插值来做这个事情,现在两级内部做完双线性插值得到两个结果以后再用这两个值插值得到两层之间的结果,这种就叫做三线性插值,这样的话就能用三线性插值解决我们从最前面的图片过小要用双线性插值去过渡值和我们现在过大要取多级mipmap等级的两个问题了,不管是内部要按整数型还是小数型取纹素,还是多级之间去插值就都可以了

演示图片

各项异性过滤

如上图因为mipmap只是等比压缩几倍,各向异性相当于生成了对应宽和高不同比例的图,这样就能不光支持正方形查询了,可以支持矩形范围的查询,因为一个像素映射到纹理上的范围可能是不规则的

演示图片

首先纹理我们在GPU层可以把它看做就是一组数据,在GPU对纹理的作用就是 一块内存+范围查询(滤波),不简简单单是一张图的概念,所以如果这样理解的话,纹理就可以干非常非常多的事情了

演示图片

环境光贴图

记录了周围环境所看见的光的样子到贴图上,这个贴图上记录了从当前位置向四面八方看去所看到的东西,然后我们在做一个物体的渲染的时候,就可以把这个贴图的环境光信息对应到物体反射上去,就出出现有图的茶壶上的效果,但是在此个应用上我们假设周围的光只有一个方向,没有位置距离等消息,认为这个光是无限远的

演示图片

可用球形的物体去记录周围环境光的信息,然后再把表面展开成一张贴图

演示图片

展开后就是这样一幅图,但是有一些问题,就是图的上面和下面会有一些扭曲,因为球形导致上方和下方无法达到均匀的分布,所以为了解决这个问题,我们就用Cube Map来解决这个问题

演示图片

Cube Map

我们假设在球外面包裹一个立方体,球原本记录的位置与球心如果做一条向量,如果穿过立方体上某一点了,我们把环境光信息记录到这个点上,那就相当于用立方体来记录环境光信息而又不是破环之前球形记录的方式,这样的话就会得到六张贴图分别对应不同的方向

演示图片

演示图片

法线/凹凸贴图

**总览:如果我们想不通过改变这个几何形体的情况下表现表面凹凸不平的效果,我们可以通过改变这个着色点的法线的方式来做到,因为法线的不同会导致受到光线后的明暗不同,在视觉上就会给我们产生凹凸不平的效果,在图形学上有两种贴图(法线/凹凸贴图)来做到这种效果,他们的最终都是改变这个点上的法线,只是方式不同,一个是改变顶点的相对位移,一个是只是改变法线向量,那也就是说这两张贴图存储的数据不同,一个是具体的偏移值,一个是法线向量 **

演示图片

Bump Mapping

凹凸贴图:简单来说就是我们知道了这个点的相对偏移以后怎么算出他的新的法线方向,这就是凹凸贴图的重点

演示图片

我们已知当前点的法线是垂直与当前点的,那点p的向量n当前就是(0,1),然后我们使用差分方法算出这个点导数(dp),通过这个点和下一个点的高度差算出来的,也就是第二行的公式,从而得到这个点的切线(1,dp),我们可以通过切线得到这个点新的法线,我们看到这个法线是垂直与切线的,所以新的法线就是(-dp,1)的单位向量,这是在一维空间下的推导

演示图片

在三维空间下,会通过u,v的偏移来去算出分别对应的导数 du,dv,那新的法线向量其实就是(-du,-dv,1),但是这个是相对于本地坐标系(TBN)的向量,我们需要把他从切线空间坐标系转换到世界坐标系去,就需要一个矩阵的变换这个就需要去作业3的FAQ里去看具体的推导,然后原理就是这个原理,通过导数的计算得到切线以后再逆时针偏转90度得到的法线

演示图片

位移贴图 简单来说跟凹凸的思路都是一样的,区别就是位移贴图是真的把顶点给移动到具体的位置,真的改变了顶点,那他的效果肯定是会更好,下图左边是凹凸贴图,右边是位移贴图,但是位移贴图有一个代价,就是要求模型三角形足够细致,因为纹理的每个纹素对应的就是每个顶点,所以模型的顶点数要跟的上纹理的大小,不然会出现走样问题,如果想用低面的模型依然使用这个位移贴图,DX有一个曲面细分的东西可以做到这个,知道概念就行

演示图片

噪声函数和3D模型渲染

通过记录3维空间中的噪声值,然后在3维空间中这个着色点可以使用一个噪声函数对这个噪声值进行一些处理从而得到右边图中的效果,而不是直接读取2维纹理值的这个概念

演示图片

纹理还可以记录一些预计算好了的值,比如下图中存储了环境光遮蔽的阴影信息,可以直接预计算好然后生成一张纹理,渲染时直接取就可以了

演示图片

三维纹理和体积渲染

演示图片