闫令琪:Games101 现代计算机图形学-作业Assignment03解析
本文目录
本次作业的核心任务是:
- 完成布林冯模型的shader
- 完成凹凸贴图的shader
对应的课程是第九讲、第八讲、第七讲。
1. 作业框架梳理
因为之前两次作业都是三角形,本次是有3D模型,作业框架在之前的基础上稍微增加了一些内容,其处理流程梳理如下:
a. 对3D模型的处理:
- 专门的读取obj文件的类,读取3D文件
- obj文件内部其实存储的是一个个三角形面,一个三角形的三个顶点作为一个元素,存到
TriangleList
数组里。 - 接下来的所有的处理都是对这个数组元素的遍历处理,也就是一个三角形一个三角形的处理
b. 对三角形的坐标变换处理
- 仅仅对三个顶点进行旋转、平移、缩放和摄像机坐标系平移,不进行透视变换,3D模型本身的形状不变,仅仅是变换位置,为了后续再三角形内插值使用。并且后续
shader
中的光的方向向量、视线的方向向量等都是需要基于真实坐标计算。 - 对顶点的坐标进行完整的坐标变换。该坐标目前仅在计算
bounding box
还有z-buffer
时有用; - 然后设置法线,其中法线不经过透视变换
- 对三个顶点设置颜色。这个颜色后续作用不大,会被贴图的颜色取代
c.shader设置
框架里列出了四种shader去完成,其中最重要的是布林冯shader还有凹凸贴图的shader。
- shader里需要接收的数据是需要渲染的像素点,它的法向量、颜色、真实3D坐标等,这些数据被封装到一个结构体
fragment_shader_payload
作为函数输入。 - 根据需要渲染的点的结构体里的数据,还有shader里给的灯光位置、强度,摄像机(即view坐标)可以求出布林冯模型所需要的各种向量,然后求出漫反射、高光、环境光三个分量,求和后返回颜色
d.光栅化
- 根据透视变换后的三角形三个顶点求出bounding box,简化计算
- 对bounding box的每个像素进行遍历,先进行插值的系数计算,求出
z
值,进行z-buffer
计算 - 对于需要绘制的像素点,利用上一步计算的插值系数,分别插值出颜色、法向量、UV坐标值、没有经过透视变换的真实3D坐标,初始化结构体
fragment_shader_payload
。 - 把
fragment_shader_payload
的数据传进shader
里,即可求出该点的颜色。 - 然后调用设置颜色的函数,渲染完成。
上面四个步骤中,前两个步骤不需要自己去做,第四个步骤前面的作业已经完成,因此本次作业的核心是完成shader的编写。
思考本流程,因为是对每一个三角形面都进行光栅化,因此貌似并不能并行?这只能cpu串行,那么怎么用gpu并行呢?希望以后来填这个坑。
2.布林冯shader的注意事项
具体的代码,该博客已经记录的比较完整GAMES101-现代计算机图形学学习笔记(作业03)。
此处记录一些自己犯过的易错点。
a.向量的具体含义
①图中所示的漫反射的光线向量、视线向量,一定注意,他们是跟光线、视线相反的方向!!都是物体表面指向光源和观测点。
②其次!这都是单位向量!!!后面求高光时要算半程向量,那个时候两个向量相加必须是单位向量。
③这个距离衰减,不能用向量l,因为它不能初始化。
b.不同分量中颜色
高光和环境光都是全局不变的颜色,物体的颜色影响最大的是漫反射。如果有贴图,就是把贴图的颜色归一化(/255)后赋值为漫反射的系数Kd。
c.代码框架中的观测点坐标疑错误
光栅化代码中所使用的view_pos
坐标其实在draw
函数里已经经过view
矩阵变换,也就是已经把相机移动原点了。所以按理说shader
中的观察点应该是原点,但是代码中还是给的相机的初始位置。
3.凹凸贴图
这部分其实课程中并没有详细讲述。bump_fragment_shader
是把最后求得的法向量当成颜色,displacement_fragment_shader
是在上面求出新的法向量的基础上应用了布林冯模型。
选择这两个shader
时,main
函数中都会默认读取凹凸贴图。
a.凹凸贴图为什么基本都是蓝色
凹凸向量是三个值,正好对应颜色RGB,所以可以放到一张图里。因为图里面只有UV坐标,跟3D模型怎么对应呢?
因为UV对应是物体的表面,也就是下图中所示的任意点都有一个表面坐标系称为TBN【tangant轴(T):切线轴;bitangent轴(B):副切线轴;及法线轴(N)】。
所以凹凸贴图里任意一(u,v)点的向量,都可以在物体表面放到该点的TBN坐标系中,凹凸贴图主要存储法向量,即N轴数据,所以在颜色空间中对应RGB中的B,也就是蓝色。
从这个图可以更好地表示,T轴和B轴,和贴图中的UV坐标轴方向是一致的。
b.贴图中的数据怎么映射到3D空间
shader数学基础之法线贴图切线空间这篇文章算是讲的还不错的。
Tutorial 13 : Normal Mapping这篇Opengl讲的也不错,但是……
感觉都跟代码框架里的对不上……
课程的BBS系统讨论区中,提供了一种快速计算TBN的方法。至少此方法计算的TBN三者是相互垂直的。作业框架里的三者都不是互相垂直的。
希望以后能填这个TBN的坑