文章目录
前言
前面章节讲解了颜色混合和深度测试相关的内容,这一节咱们补充一下面片剔除(Cull)相关的内容。
正文
为什么需要面片剔除?
当我们加载一个模型文件时,其中包含许多面片,常用的面片类型就是四边形和三角形。当从摄像机视角观察时,肯定只能看到正对着摄像机的内容,背对着摄像机的内容肯定不可见,而实现类似功能的方法就叫做面片剔除,更常见的说法就是:背面剔除。如下示意图:
什么是面片剔除?
我们常说背面剔除,但是究竟什么是背面?也就是说,我们需要定义一个面片的背面规则。剔除说法也是类似,其实也涉及到两个方面,究竟是剔除背面还是剔除正面。只要满足这两个要求,就可以将目标面片去掉,也就剔除了!
实现面片剔除常用实现?
我们都知道,如果按照之前的章节的投影矩阵的推导,咱们将坐标变换到NDC坐标系之后,其实是形成左手系,这也是OpenGL的类似实现方式,如下:
也就是说,实际的z轴的指向朝屏幕里,-z轴指向朝屏幕外。咱们可以先记住这个固定不变的结论!
叉乘判定:
既然NDC坐标系已经是左手系,那叉乘的手法已经变成使用左手的规则了,这里给出以下两个案例:
案例1: 顺序顶点0,1,2
这里咱们用左手示意叉乘 a ⃗ × b ⃗ \vec a \times \vec b a×b 我们发现朝屏幕里,也就是说朝NDC坐标系的正z方向
案例2: 顺序顶点0,1,2
这里咱们用左手示意叉乘 a ⃗ × b ⃗ \vec a \times \vec b a×b 我们发现朝屏幕外,也就是说朝NDC坐标系的负z方向。
剔除规则:
常见的有四种面片剔除规则,如下:
- (1)设顺时针为面片正面,剔除正面
- (2)设逆时针为面片正面,剔除正面
- (3)设顺时针为面片正面,剔除背面
- (4)设逆时针为面片正面,剔除背面
规则(1):顺时针为正面,剔除正面
这里贴一下顺时针的三角形,方便示意:
假设 a ⃗ 和 b ⃗ \vec a 和 \vec b a和b 都是三维向量,那么通过 c ⃗ = a ⃗ × b ⃗ \vec c = \vec a \times \vec b c=a×b, 通过 c ⃗ \vec c c 的z分量正负,就可以判定是朝屏幕里还是屏幕外。
如果这里要求正面且顺时针为正面,也就是说剔除顺时针的情况,从而推导出剔除 c ⃗ \vec c c 朝屏幕外的情况,也就是满足 c . z < 0 c.z < 0 c.z<0 的情况进行剔除!
规则(2):逆时针为正面,剔除正面
类似规则(1)可得,满足 c . z > 0 c.z > 0 c.z>0 的情况进行剔除
规则(3):顺时针为正面,剔除背面
剔除背面且顺时针为正面,也就是剔除逆时针的情况,同理可得,当满足 c . z > 0 c.z > 0 c.z>0 进行剔除!
规则(4):逆时针为正面,剔除背面
剔除背面且逆时针为正面,也就是剔除顺时针的情况,同理可得,当满足 c . z < 0 c.z < 0 c.z<0 进行剔除!
总结:
以三角面片为例,给出顺序顶点A、B、C,记 a ⃗ = B − A = A B ⃗ \vec a = B - A = \vec {AB} a=B−A=AB , b ⃗ = C − A = A C ⃗ \vec b = C - A = \vec {AC} b=C−A=AC, c ⃗ = a ⃗ × b ⃗ \vec c = \vec a \times \ \vec b c=a× b 。
以NDC左手系为例,通过判定 c . z c.z c.z 正负进行判定是否剔除!
当通过 c . z > 0 c.z > 0 c.z>0 进行剔除时,有两种情况:
- 逆时针为正面,剔除正面
- 顺时针为正面,剔除背面
当通过 c . z < 0 c.z < 0 c.z<0 进行剔除时,有两种情况:
- 顺时针为正面,剔除正面
- 逆时针为正面,剔除背面
结尾:喜欢的小伙伴可以点点关注+赞哦
希望对各位小伙伴能够有所帮助哦,永远在学习的道路上伴你而行, 我是航火火,火一般的男人!