
0 回顾
在之前的课程中,我们讲了光栅化,这次要开始讲着色。
回顾一下我们学过的东西
- 我们有了一个模型,空间中有了一个摄像机 Model
- 通过变换可以让摄像机放在原点 View
- 三维空间的模型变换到屏幕上 Projection
- 通过采样进行光栅化 Rasterization 我们把这些三角形画在屏幕上后,不禁要问,这些像素的颜色是什么呢,这便是接下来要讲的着色。
我们把这些三角形画在屏幕上后,不禁要问,这些像素的颜色是什么呢,这便是接下来要讲的着色。
1 Shading: Definition 着色定义
- 引入明暗与不同颜色的过程称为着色在本课中定义是给物体应用材质的过程
2 Blinn-Phong Reflectance Model一种简单的着色模型
关于Blinn-Phong的着色模型 先前我在 LearnOpenGL学习笔记—光照02:Lighting Basis/Advanced Lighting中对其概念进行过阐述 当时也是用了闫老师的PPT和视频作为讲解材料,并做了简单实现(点光源为例) 所以此处不再赘述
3 Shading Frequencies 着色频率
- 着色频率
3.1 平面着色
- 平面着色
3.2 顶点着色
- 顶点着色每个顶点做一次Shading,对颜色值插值
3.3 像素着色
- 像素着色这里的Phong Shading指的是一种着色频率,之前说的Blinn-Phong是一种着色模型三角形三个顶点求出法线,在三角形内部的像素,对法线值做插值,对每个像素做Shading
3.4 对比
- 几何形体足够复杂的情况下,用简单的Shading方法也可以达到好的效果
3.5 顶点法线求法
- 顶点法线求法 一个顶点肯定被多个三角形共用,就用相邻的三角形面法线相加再求平均,通过判断面积比例加权平均的话效果会更好。
内部平滑过渡的法线做法——Barycentric interpolation 重心插值
法线记得归一化
4 Graphics (Real-time Rendering)Pipeline 实时渲染管线
关于这一部分我在LearnOpenGL学习笔记—入门03:Hello Triangle中对图形渲染管线的知识做了简单描述,并做了非常简单的实现(未用到材质以及光照)
LearnOpenGL学习笔记 这个系列也可以说是对实时渲染管线的一个探索和应用
下图为PPT中的示意图
- 当下的实时渲染
5 Texture Mapping 纹理映射
关于纹理映射的内容我在 LearnOpenGL学习笔记—入门05:Texture 做过阐述
- PPT中的示意图很好表示这个映射过程纹理本身设计可以无缝衔接:tilable,一种设计无缝衔接纹理的方法:Wang Tiling
6 Barycentric Coordinates 重心坐标插值
- 重心坐标插值
- 利用面积的计算确定系数
- 利用坐标的计算确定系数
- 利用中心坐标插值的方法,投影前后的重心坐标可能会变化,所以需要在对应的阶段计算对应的重心坐标来做插值,不能随意复用
- 进行插值
7 Applying Textures 纹理应用
- 点上计算得到插值出来的UV坐标,然后在纹理上查询,之后根据需要应用(图中为简单应用,直接赋值)
8 Texture Magnification 纹理过小(4K分辨率,256贴图)
纹理分辨率太小,多个pixel(像素)映射到了同一个texel(纹理像素)
- 解决方法→插值
8.1 Bilinear Interpolation 双线性插值
双线性插值:水平插值+竖直插值
lerp为linear Interpolation的缩写
下图为最近的四个点插值
- 找到目标点周围四点
- 红点离四个点左下角的垂直与水平距离
- 在u_01与u_11之间线性插值得到u_1,同理得到u_0然后再u_0与u_1间再次线性插值得到红点
8.2 Bicubic Interpolation 双三次插值
取周围16个点也是做竖直和水平的插值
每次用4个,做三次的插值,不是用线性的差值
双向三次插值运算量大,但是效果好
关于这个方法可以看看这位大神的介绍
双三次插值算法(bicubic interpolation)与图形学和计算方法的关系
双三次插值(BiCubic插值)
9 纹理过大的问题(256分辨率,4K贴图)
- 纹理过大时,一个pixel对应了多个texel → 采样频率不足导致 摩尔纹+锯齿(走样)远处地平面的一个像素,对应一个大块的纹理,简单的点采样不行
- 解决: 采样会引起走样,那么我们不采样,只得到一定范围的平均值。
这是点查询与范围查询的问题
9.1 Mipmap 多级渐远纹理
Mipmap 多级渐远纹理可以进行快速的范围查询,但是是近似的,并且只有方形关于Mipmap的内容我在 LearnOpenGL学习笔记—入门05:Texture 中的 纹理环绕方式/纹理过滤 这一部分做过阐述
-
以下为PPT中的示意图 关于计算Mipmap的示意图 首先我们要把像素覆盖的区域找出来,进行近似
-
考虑一个像素时,也考虑上周围的点 然后把它们的中心一起映射到UV上计算距离 于是可以用距离为边长的 虚线的正方形框 来近似 映射过来不规则的四边形 层数D约为相邻pixel的映射uv之间的距离取2的对数 D的作用举例 如果区域的大小是1×1 D=0 那么在最原始的等级的Mipmap上找 如果区域的大小是4×4 D=2 那么在第二等级的Mipmap上找,也就是在第二等级上,这个4×4会变成1×1,然后去第二等级上去查这个像素的值,那就是这个区域的平均值
-
单纯只是整数层之间,会有不连续的缝隙
9.2 Anisotropic Filtering 各向异性过滤
Mipmap会把远处的细节都模糊掉因为它只能查询方块的区域内,以及插值毕竟只是近似
- 解决三线性插值的方法就是各向异性过滤
- 方块的近似有时候太过勉强,如下图纹理映射后奇形怪状的
- Mipmap做的是方块的 也就是下图左上角的图,但是不方正的压缩做不了
- 各向异性过滤允许我们对长条的区域进行范围查询,但是对于斜着的区域,不行 生成各向异性过滤的图(Ripmaps)的开销是原本的三倍 各向异性的意思是,在不同的方向上它的表现各不相同 各向异性的几X是压缩几倍,也就是从左上角往右下角多几层
- EWA过滤,把任意不规则的形状拆成很多不同的圆形,去覆盖这个形状 多次查询自然可以覆盖,但是耗时大