GAMES101学习记录02 【Rasterization(光栅化)】


1.三角形光栅化

把三维世界中的图像映射到二维屏幕上

实时(超过三十帧每秒)计算机图形学应用

Curves and Meshes(曲线和网格)

定义视锥的两个参数:Vertical Field of View(垂直可视角度)和aspect ratio(长宽比)



 2.反走样(Antialiasing)

走样类型:jaggies(锯齿)、moire(摩尔纹)、wagon wheel effect(车轮效应):人眼观察高速转动的车轮的时候视觉上会感觉有倒转的现象。

走样产生的原因主要是由于采样频率不适用于当前采样对象导致走样

反走样的主要方法:

(1)使用好一点的显示屏,提高采样频率,走样就会缓解(不现实)

(2)先对图片模糊之后在采样可以缓解锯齿状走样

实际效果图

(3)削减高频信号

时域上的乘积等于频域上的卷积

 (a)\cdot (c)=(e)等价于(b)*(d)=(f)

采样在频域图中的表示就是将连续的信号通过一定的采样频率复制连续信号到频域图中,形成多个一样的峰。

 

Dense sampling就是采样频率高的时候频域图

Sparse sampling就是采样频率低的时候频域图 

 

将分布在“峰”两侧的高频信号给模糊处理掉,这样在相对低的频率采样也不会出现信号重叠的问题实现了反走样。

(4)MSAA

在像素中再细分一些采样点,之后通过这些采样点计算一个像素内颜色占比,通过颜色占比就可以计算出给像素的颜色值



  3.深度缓冲(Z-Buffering)

(1).画家算法(Painter’s Algorithm):因为是对n个三角形先后顺序排序,使用快速排序,时间复杂度O(nlogn)(传统算法)

先从远处开始采样,之后一步一步将近处的物体采样入画幅,覆盖先前远处已经采样的像素。

画家算法的缺点:在现实生活中有些场景判断不了几个物体是否在前在后

(2).Z-Buffer算法:画幅中每个像素点代表离相机距离最近物体所表现的像素。

在渲染过程中生成两个buffer:frame buffer(存储颜色值)和z-buffer(存储深度)

 

 伪代码图

 

 算法可视化

Z-Buffer算法复杂度O(n):将n个三角形往里填,每个三角形假设像素数量近似为一个常数。可以理解每个像素寻找最小值的过程,并不是排序的过程,所以算法复杂度就是O(n)。



 4.shading(着色)

定义:将一种材质应用到一个对象上去

Blinn-Phong Reflectance Model

 v就是观测方向;n是法线向量;l是光线到物体表面观测点的连线方向;表面材质的反射率、颜色...

 着色不考虑其他物体,所以没有阴影

Blinn-Phong模型

 

漫反射光强度的计算公式,主要是由漫反射因数(颜色)、到达物体表面的光点光源能量、物体能量接受率决定。max(0,n\cdot l)含义:n点乘l只有在钝角时候为负数,那个时候就没有意义了,所以如果n点乘l为负数,一律视为0。

漫反射的光强度与观测角度没有任何关系,所以漫反射反射的光强度四面八方的强度是一样的。

Blinn-Phong模型判断是否能看到高光(就是光线直接反射入人眼的就是高光)使用的是n和h的夹角(夹角越小,看到的光线强度就越接近于高光),计算半程向量公式为如图所示(相比于Phong模型那种直接求反射向量R和观察角度v之间夹角的方法,Blinn-Phong模型计算更加简单)

注:L_{s}=k_{s}(I/r^{2})max(0,cos\alpha )^{p}中的p指数变量是为了让接近1的值更加接近1,与1差值大的值相差更多,减少对高光判断的宽容度(只有n和h特别接近的时候才能算作高光)

将环境光,漫反射光,高光的像素合称为一张图片就是Blinn-Phong反射

着色频率 

 上图的三个小球是同一个模型的不同着色方式展现,第一种是对一个立方体面计算反射光强度后同一着色(Flat shading);第二种对每一个顶点求法线之后对每个顶点着色,每三个顶点围成一个三角形,对三角形内部使用插值方式让着色更加平滑(Gouraud shading);第三种在任意三个定点围成的三角形区域内的像素点计算法线方向,之后着色(Phong shading)。

注:在上述第二种着色方案中要实现求顶点的法线方法如下:因为模型是由很多三角形构成的,所以顶点周围必定存在多个三角形如下图所示

,所以求顶点的法线可以看作是求这四个三角形的法线的平均,公式:N_{v}=\frac{\sum _{i}N_{i}}{\left \| \sum _{i}N_{i} \right \|}就可以求出法线向量。

图形管线(Graphics Pipeline)

 

 从点到显示器生成图像的流程图,GPU的计算过程:读入三维点->将三维点通过投影变换成为一系列二维点->将点连线成为三角形->三角形光栅化->为每个像素点着色->将所有三角形拼接在一起

纹理映射(Texture Mapping) 

 

纹理映射主要是通过uv坐标系,如右图所示,每个三角形的坐标在uv坐标系中都有具体的表示,而uv坐标系上的三角形又可以和3d模型上的三角形一一对应起来,就可以完成纹理映射工作。 

 

重心坐标(Braycentric Coordinates

1.重心坐标定义:是在一个三角形中的一个三维坐标系(\alpha ,\beta ,\gamma )

如果一个点在三角形内坐标系为(x,y)如下图所示

(\alpha ,\beta ,\gamma )的求法:\left\{\begin{matrix} (x,y)=\alpha A+\beta B+\gamma C\\ \alpha +\beta +\gamma =1 \end{matrix}\right.,这个就是一个三角形的重心坐标系求法 

如果(x,y)是三角形的重心点那么满足下面的公式

 


1.重心坐标的应用

知道重心坐标(\alpha ,\beta ,\gamma )之后,可以根据A,B,C三点的属性值V_{A},V_{B},V_{C}算出在三角形内的坐标点(x,y)的属性V,公式如下

V=\alpha V_{A}+\beta V_{B}+\gamma V_{C}

这里的V_{A},V_{B},V_{C}可以表示各种属性

注:在三维空间的属性应该现在三维空间求重心坐标之后投影回二维坐标。而不是先投影再求二维坐标系中的重心坐标。(由于中心坐标会在投影过程中产生变化)

 

应用渲染

对于每一个像素点(x,y)可以通过重心坐标插值出来一个(u,v)值,通过(u,v)值就可以计算出该点所对应纹理颜色,之后将像素点用求出来的纹理颜色填充

 

纹理放大

如果纹素太小,就意味着相邻的像素之间获得的uv值可能一样形成很多肉眼可见的小方格导致画质下降如下图所示

 所以为了避免这样的现象就会采用双线性插值(Bilinear Interpolation)

一般来说,通过求取下图(红点为像素点(pixel),黑点为纹素点(texel))中的红点所需要表达的颜色就是看距离最近的texel点是什么颜色就表现什么颜色,但是当纹理点间距很大的时候就会导致人眼看到的会有块状的形式,这时候引入双线性插值

 v0,v1是两个端点,x为v1,v2线段中的一个点,线性插值的公式为:

lerp(x,v_{0},v_{1})=v_{0}+x(v_{1}-v_{0})

双线性插值计算步骤如下:

1.双线性插值的x轴方向的计算公式为

\left\{\begin{matrix} u_{0}=lerp(s,u_{00},u_{10})\\ u_{1}=lerp(s,u_{01},u_{11}) \end{matrix}\right.     其中u1是u01和u11之间的线性插值,u0是u00和u10之间的线性插值

2.计算u0和u1在y轴上的线性插值即可,公式如下

f(x,y)=lerp(t,u_{0},u_{1})

得出的f(x,y)就是插值权重结果,由此再去求该像素点的uv值即可

纹素过大会导致的问题

导致的现象如下图的右图所示所

 原因:如下图所示,从左往右代表从近处向远处,在图中正方形的方阵是由一个一个texel组成的,平行四边形的阴影区域其实就是代表一个像素大小,越远像素覆盖的texel的个数越多。在图中可以看到近处的像素覆盖的纹理数较少,左侧第一个覆盖一个texel,第二个覆盖4个texel。越往远处,一个像素点覆盖的texel个数越多。

        所以在远处的一个像素就可以覆盖很多个texel这样显然是会出现失真的情况

解决方法:Mipmap范围查询

下图表示mipmap中的层数,最低层分辨率最高,比如一张图片原始分辨率为128*128,那么第0层的分辨率就是128*128,之后第1层的分辨率就会下降到64*64,以此类推。可以理解成第0层的2*2个像素就是第1层的1个像素、第0层的4*4个像素就是第2层的1个像素

mipmap每层所存储的像素值如下图所示

计算需要查询的层数D是通过公式D=log_{2}L来确定的,L的计算公式如图所示

 具体在图上的表现形式如下图

:)(这个纯属个人理解,有错误请指正)例如,假定经过估算,一个像素覆盖了4*4个texel点(每个texel都有自己的纹理值最后组成texture),即L=4,那么D就等于2,也就是说在mipmap第二层的对应位置的texel值就是这4*4个原始texel的平均值,也就是这个像素可以以mipmap第二层的texel值为自身添加纹理。通过查询一个mipmap中保存的texel值其实就是完成了对应区域查询。

经过计算之后可以用不同颜色表示要在mimap中的哪一层进行范围查询,但是这种查询是不连续的,如果计算出来的结果是D=1.8的情况也会有误差。 

 遇到D=1.8这种类似情况可以使用插值的办法,如下图所示,1.计算出原始D向下取整和原始D向下取整+1这两层中双线性插值之后的结果,2.这两个结果再次做一次线性插值的出来的结果就是层与层之间的渲染值

 

 各向异性过滤(Anisotropic Filtering)

mipmap的缺陷在于在远处会出现overblur的现象,原因在于插值本身的近似性以及mipmap只能查询正方形区域内的平均值。

 

因此出现了各向异性过滤的方法,如下图所示与mipmap不同的是各向异性的在预先存储处理图像信息的过程中存储了图像水平或者竖直压缩之后的图像,而mipmap仅仅只是记录了关于对角线等比例缩放的图像信息。也就意味着在各向异性过滤中可以不单单区域查询正方形的区域还可以查询长方形的区域,比如在一张竖直方向上被压缩2倍的图像中的一个像素对应原图像中就是两个竖直排列的像素点,呈现长条形状。并且从下图可以看出各向异性过滤需要存储额外的数据量是原始图像的3倍,而mipmap只需要额外的1/3倍来存储新的信息。

注意:对于斜长条形的区域,各向异性过滤还是无法准确给出解,例如下面右图图中左上角白色斜长条形展现出来的情况。

此时可以使用EWA过滤,如图所示,任何不规则的图像都是可以通过拆分成很多不同圆形去覆盖不规则形状。使用多个圆型区域多次查询肯定会带来计算量上的大幅提升。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值