Games101计算机图形学入门基础之三:着色

光照与基本着色模型

通用定义:引入明暗和颜色的不同
图形学中着色的定义:对不同的物体应用不同材质的过程
材质和着色:不同的材质就是不同的着色方法

Blinn-Phong反射模型
它是一个经验模型,并不完全符合真实世界中的光照现象。这种模型将看到的光线分为三部分高光、漫反射、环境光照
在这里插入图片描述
着色是针对点的,定义一些计算需要的信息
影响着色效果的部分信息
漫反射
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以漫反射的光照可以总结为以下一个理想公式:
在这里插入图片描述
镜面高光
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
故在布林冯模型中镜面高光可以总结成以下的公式:
反射各项参数变化时高光的变换:P(镜面指数)越大,高光的聚集点就越小, K s Ks Ks(镜面系数)越大镜面高光就越强。
在这里插入图片描述
环境光
环境光可以无限简化成一个 K a Ka Ka乘以光强的这样一个公式。
在这里插入图片描述
最后我们将所有的考虑因素都结合到一起就是一个完整的布林冯(Blinn-Phong)着色模型了:
在这里插入图片描述

常见的三种光照模型

(1)漫反射与Lambert光照模型
粗糙的物体表面向各个方向等强度地反射光,这种等同度地散射现象称为光的漫反射(Diffuse Reflection)。产生光的漫反射现象的物体表面称为理想漫反射体,也称为Lambert反射体。
对于暴露在环境光下的Lambert反射体,可以用以下公式表示某点处的漫发射光强:
Iad= KIa
其中Ia表示环境光强度,k(0<k<1)为材质对环境光的反射系数,Iad是漫发射体与环境光交互时反射的光强。
理想的环境光是无序的,但是表面光强还依赖于光线的入射方向,这种现象可以用Lambert定律进行数学上的量化。
Lambert定律:当方向光照射到理想反射体上时,漫反射光的光强与入射光方向和入射点便面法向量夹角的余弦成正比。Ild = K
IlCosa,其中Ild是漫反射体与方向光交互反射的光强,Il是方向光的光源强度,a是入射光线与定点法向量的夹角,k是材质的反射系数。
当入射角为零时,说明光线垂直于物体表面,漫反射光强最大;九十度时光线与物体表面平行,物体接收不到任何光线。
若N表示顶点单位法向量,L表示从顶点指向光源位置的单位向量(主意指向,不要弄反了),那么Cosa等价于N与L的点积。
即:
Ild = k
I*(N·L)
那么综合考虑环境光和方向光,Lambert光照模型可写为:
Idiff = Iad + Ild = kIa + kIl*(N·L)
(2)镜面反射与Phong光照模型
Lambert模型较好的表现了粗糙表面的光照现象,如墙壁,纸张等,但是在用于诸如金属等有光泽效果的材质上则会显得呆板,表现不出光泽,主要原因是Lambert光照模型没有考虑表现这些表面的镜面反射效果。
一个光滑物体被光照射时,可以早某个方向上看到很强的反射光,这是因为在接近镜面反射角的一个区域内,反射了入射光的全部或大部分光强,这种现象称为镜面发射。
故此,Phong Bui Tuong提出一个计算镜面反射光强的光照模型,称为Phong模型,认为镜面反射的光强与反射光线和视线的夹角相关。
Phong模型数学表达式:
Ispec = KsIl(V·R)^n
注:((V·R)n表示(V·R)的n次方即(V·R)n 。
Ks表示材质的镜面反射系数,n指高光指数,V表示从顶点到视点观察方向,R表示反射光方向。
高光指数n反映了物体表面的光泽程度。n越大,反射越集中,当偏离发射方向时,光线衰减的越厉害,只有当视线方向与反射光线非常接近时,才能看到镜面反射的高光现象。此时,镜面反射光将会在反射方向附近形成亮且小的光斑。n越小,表示物体表面越粗糙,反射光越分散,观察到的光斑区域越小,强度弱。
反射光方向向量R可以通过入射方向L(从顶点指向光源)和物体表面法向量L求出。
R+L = (2N·L)N

(3)BlinnPhong光照模型
BlinnPhong光照模型混合和了Lambert的漫反射和标准的高光,渲染有时比Phong高光更柔和、更平滑,此外它的处理速度相当快,因此成为许多CG软件中默认的光照渲染方法。
在Phong模型中,必须计算V·R的值,其中R为反射光线的单位向量,V为视线方向的单位向量,但是在BlinnPhong模型中,用N·H的值来取代V·R。BlinnPhong光照模型公式:
Ibp = Ks*Il(N·H)^n
其中N是入射点的单位法向量,H是“光入射方向L和视点方向V的中间向量”,通常也称为半角向量。注:半角向量被广泛运用于各类光照模型,因为其既含有各种信息价值(光线入射方向以及视点方向),而且计算快速方便。

着色频率

到这里我们已经理解了着色模型,这个时候我们考虑的是任何一个着色点shading point,那么下一步自然而然就是对所有点做一遍着色操作,那么整个场景的明亮程度就能看得见了。

着色频率可以大概分为对三角形着色(flat shading),对每个顶点着色(Gouraud shading),对每个像素着色(Phong shading [冯着色] )。
在这里插入图片描述
在这里插入图片描述

三角形着色比较好算因为只要算它的法线n就可以了,而顶点着色 (也叫高罗德着色) 的法线怎么算呢其实在虚幻引擎或其他建模软件中一般顶点中是已经记录好了定点的法线的,当然有很多方法可以计算定点的法线介绍一个简单但是实用的方法:平均加权(如下图)
在这里插入图片描述
求出了每个顶点的法线后那么我们怎么对像素着色呢,这就要利用到重心坐标做插值求每个像素的法向量。这个我们后面的纹理映射部分会详细介绍这个重心坐标。
了解完了着色频率以后,我们自然而然的就会思考一个问题什么时候用三角形着色什么时候用像素着色呢?这个问题就要看场景模型的精度了,我们知道三角面越来越多的话它的着色效果会越来愈好(如下图)。这里需要说的是像素着色不一定就比三角形着色效果好。这是因为如果模型的三角面特别多多于像素的时候显然是三角面着色好(现在有的模型都有数以十亿的三角面片而屏幕上的像素也就是不到4K-4096×2160)
在这里插入图片描述

渲染管线(实时渲染管线)

实时渲染管线 的前半部分即光栅化的过程:空间中的场景模型经过各种空间变换(Model, View, Projection transforms),把空间的物体转换到单位立方体里面来(cuboid to “canonical” cube [-1, 1]3,然后通过视口变化矩阵(Viewport transform matrix)把单位立方体映射到屏幕空间(Canonical Cube to Screen),此时我们需要把屏幕空间的三角形离散化成一个个像素。到这里我们就可以将一个三角形画在屏幕上了,但是有人就会问了实际场景中那么多不同空间三角形的组成,形状不同而且他们距离相机的距离是不一样的,那么如何把这些三角形画在屏幕上并且保证他们的遮挡关系是正确的(近处的物体要遮住远处的物体)。这个问题就涉及到可见性问题或者是遮挡问题了。这里我们解决的办法是深度测试(Z-Buffer Visibility Tests)。
在这里插入图片描述
在这里插入图片描述

纹理映射

上面我们介绍了Blinn-Phong Reflection Model这个光照模型,其中针对每个着色点( shading point)它本身有一些属性,这个属相可以简单理解为纹理映射来的(也可以简单的理解为Blinn-Phong 模型中的kd系数)。我们看下面场景中ball上不同的地方有不同的颜色,有的地方还有五角星。我们知道它们共用一套光照模型,只是它们的漫反射k_d系数不一样,那么我们自然而然的希望在物体的不同位置定义它们对应的不同属性,这里就引入了纹理映射。
在这里插入图片描述
纹理映射 (Texture Mapping) 是一种将物体空间坐标点转化为纹理坐标,进而从纹理上获取对应点的值,以增强着色细节的方法。纹理映射(纹理划管线——The Texturing pipeline)[4]有以下四个步骤:投影映射(Projector And Mapping)、变换函数(Corresponder Function)、纹理采样(Texture Sampling)(如下图)
在这里插入图片描述
(1)投影映射(Projector And Mapping)
主要包括Projector 和 UV Mapping两种方法,将矩形地图纹理均匀贴到球表面的投影函数称之为:Spherical 形式(如下图)
在这里插入图片描述
在这里插入图片描述物体上的三角形顶点如何映射到纹理上,这一工作交给美工去完成,我们默认已经知道了三角形映射到纹理上的位置

Projector 只适用于简单情况,对于更复杂的几何体贴图,往往需要用到 UV Mapping:用于将 3 维模型中的每个顶点与 2 维纹理坐标一一对应。 UV map 则需要建模师精心制作(如下图)
在这里插入图片描述
在实时渲染中,通常是将 uv 坐标保存在顶点信息中,在三角形内使用时,通过插值的方式得到每个片元(fragment)具体的 uv 坐标,再从纹理中采样获得对应的值(这样就可以获得三角形内部的平滑变化值)。

有人可能又会好奇怎么通过三个顶点的UV来插值呢?这就涉及到重心坐标(Barycentric Coordinates)

在顶点处线性插值——Using Barycentric Coordinates:

在这里插入图片描述
(2)变换函数(Corresponder Function)

在对 uv 进行合理变换之后,其范围都落到了 [0,1],再分别乘以纹理实际的宽高,可得到纹理坐标。比如 uv 坐标为 [0.25,0.3],纹理的宽高为 [256,256],那么相乘可得到 [64,76.8],出现了小数如何根据纹理坐标得到对应的纹理值?这就涉及到下面的纹理采样。
(3)纹理采样(Texture Sampling)
屏幕上的一个单元称之为像素(Pixel),而纹理上的一个单元称之为纹素(texel)。如果渲染物体的尺寸与纹理尺寸一致都是 512512,那么在获取每个 pixel 对应 texel 值时,刚好就能得到整数的纹理坐标,只需要每个 texel 逐个读取即可,不用考虑什么采样与重建[4]。
a、放大(Magnification)—双线性插值(Bilinear Interpolation)
但如果我们要渲染的一个模型是高清4K,而纹理贴图是256
256,那么这个时候纹理太小就会拉大(Texture Magnification ),这个时候如果采用最邻近法插值就会产生马赛克既视感。这是因为如果投影映射后非整数的像素点如果采用最临近的纹理值,由于模型像素点太多纹理纹素少,这个时候3*3的一个像素可能会对应同一个纹素,这个时候会产生一个马赛克既视感。
在这里插入图片描述
(b)缩小(Minification)——Mipmap
将高分辨率的纹理贴到低分辨率的模型上,就会产生锯齿(Jaggies)和摩尔纹(Moire)。这是为什么呢?这是因为近处像素覆盖纹理上的区域较小而远处像素覆盖的区域很大,一个像素对应一片很大的纹理范围的话自然而然的就说明纹理的信号变化过快而采样点只有一个,这就是典型的高频信号采样不足。
在这里插入图片描述
我们自然而然可以用MSAA和Supersampling来抗锯齿,但是代价太高了。那我们走另一条完全不一样的路径,我们知道产生锯齿的原因是我们采样了,如果我们不采样立刻就知道每个像素对应那片区域的纹理平均值是多少我们自然而然地解决了锯齿,这就涉及到Mipmap(我们知道点查询(Point Query)可以用双线性插值,而范围查询 Range Query的话可以采用Mipmap)。

这种方法很流行,其思想为:建立一系列不同尺寸的多级纹理,在纹理采样时,计算对应的细节级别,再用三线性插值 (Trilinear interpolation) 进行混合。首先是 Mipmap 的建立——Mipmap 中的多级纹理尺寸逐个减半,然后是Mipmap的使用——要使用 Mipmap,就要先确定用里面哪个级别的纹理去采样,也就是求出 d 值。

插值

重心坐标
在这里插入图片描述
三角形内部进行信息的插值计算,这会用到重心坐标。
插值:很多操作都是在顶点,但想要在内部做平滑的过度,需要进行插值计算。例如纹理坐标、颜色法线向量等等。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们当然想要一个更好的效果,这就要让像素对应的纹素值有一个平滑的过度,因此我们采用了双线性插值来优化它(Bilinear Interpolation)。什么是双线性插值呢?
了解双线性插值之前我们需要了解一下线性插值,如果我们要描述一个在(v0,v1)之间的点x,我们可以用lerp(x, v0, v1) = v0 + x(v1 − v0)来表示,这就是线性插值。双线性插值就是利用两次水平线性插值再来一次垂直线性插值(主要是考虑最邻近四个点的纹理值,也可以先两次垂直再来一次水平)。
在这里插入图片描述
双线性插值通常会给出很好的结果并且它的消耗成本不高,效果如下图:
在这里插入图片描述

纹理的应用

在当代GPU中,纹理=内存(储存信息)+对着部分内存进行范围查询(滤波),可以将其理解为一块数据。它可以保存在任意位置的任意信息
颜色
最简单易懂的应用。如前一节用纹理替换Blinn-Phong模型的漫反射系数Kd(三维),也就是它的颜色。
环境贴图(Environment Map)
当你站在一个位置向四面八方看的时候,四面八方的光会进入你的眼睛,就看到了物体,这里的光不管是直射光、反射光还是散射光等等,我们把它们记录下来,就形成了环境贴图。就是说用纹理来记录光是什么样的,但这里会假设光来自无限远,不包含光的深度意义。视频位置P10-07:50。
在这里插入图片描述
1.球环境贴图(Spherical Environment Map)
我们假设用一个球面来记录环境光信息(一个像镜子一样反射光的球),并将球面进行二维展开(例子:世界地图)。
在这里插入图片描述
球环境贴图例子,但很明显上部和下部出现了扭曲的现象,怎么解决这一问题呢?下面就有了Cube Map(立方体贴图)
在这里插入图片描述
在这里插入图片描述
法线贴图
法线贴图就是在原物体的凹凸表面的每个点上均作法线,通过RGB颜色通道来标记法线的方向,你可以把它理解成与原凹凸表面平行的另一个不同的表面,但实际上它又只是一个光滑的平面。对于视觉效果而言,它的效率比原有的凹凸表面更高,若在特定位置上应用光源,可以让细节程度较低的表面生成高细节程度的精确光照方向和反射效果。
在这里插入图片描述
例如,这个球如果做成这种凹凸不平的可能需要模型做很多面,但如果在法线贴图或者凹凸贴图(后面介绍凹凸贴图)上修改信息,就能改变在球面上的反射信息,也就是可以“欺骗”我们的眼睛,因为它原本模型不是这样的,只是看起来凹凸。
凹凸贴图
本质与法线贴图没什么不同,它记录了每个位置的相对高度(有一个基准面)信息,从而可以计算法线信息(与邻近位置的高度差值来计算,过程见视频)
位移贴图
凹凸贴图的更近一步,实际上移动顶点的位置,从而在视觉效果上形成移动的效果。
缺点:如果想让模型跟的上定义的移动速度,那么需要模型的三角形足够细,也就是顶点之间的距离要比单位次数移动的距离还要短。DX有个功能(dynamic tessellation)可以当需要的时候再去细分三角形。
三维纹理和三维噪声
没有实际上生成纹理图,而是采用定义在三维空间中的噪声函数(叫噪声的原因),对于任意一点,都能得到相应的噪声值。对这些噪声值进行一些计算,可以得到我们需要的样子。
在这里插入图片描述
在这里插入图片描述
着色信息的记录
提前计算好部分着色信息并且记录下来(例如阴影信息),在用到的时候直接贴上去,渲染就非常的迅速。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实时计算机图形是一门研究如何利用计算机来生成和处理图形科。它是计算机图形的一个重要分支,主要关注在实时的情况下生成和渲染图像。实时计算机图形是一门广泛应用于游戏开发、虚拟现实、计算机辅助设计、医图像处理和可视化等领域的科。 《实时计算机图形》是一本关于该科的PDF教材。该教材涵盖了实时计算机图形的基本理论和应用技术。它首先介绍了计算机图形基础知识,包括图像表示、几何变换、光照和着色等。然后,它详细讲解了实时计算机图形的核心概念和算法,如实时渲染、可见性算法、光照模型和纹理映射等。此外,该教材还介绍了近年来实时计算机图形的最新进展,如GPU编程、图形硬件加速和实时物理模拟等。 《实时计算机图形》的PDF教材具有以下优点:首先,它系统地介绍了实时计算机图形的基本概念和算法,对于初者来说非常友好。其次,该教材还提供了大量的实例和案例,帮助读者理解和应用所知识。此外,该教材还附带了习题和实践项目,可以帮助读者巩固所内容。最后,该教材还提供了进一步阅读的参考文献,方便读者深入习和研究相关领域。 总的来说,《实时计算机图形》的PDF教材是一本全面介绍实时计算机图形的优秀教材,适用于生、教师和研究人员参考和使用。它不仅可以帮助读者掌握实时计算机图形的基本理论和应用技术,还可以帮助读者了解最新的研究动态和发展趋势。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT学徒.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值