深度测试
glDepthMask(GL_FALSE):禁止深度缓冲的写入,对某些透明对象的渲染可能会使用到。先启用深度写入不透明物体,然后静止写入来渲染透明物体;
MVP变换中的深度值:深度z的变换是非线性的,这样近处的物体深度精度很高,而远除的物体精度降低。
片段着色器内建gl_FragCoord向量的x和y分量代表了片段的屏幕空间坐标(其中(0, 0)位于左下角),z分量它包含了片段的深度值(0.0到1.0)。
z-buffer fighting:在两个平面或者三角形非常紧密地平行排列在一起时会发生,深度缓冲没有足够的精度来决定两个形状哪个在前面。
模版测试
GLfloat 与 float:
typedef float GLfloat;
通常GLfloat就是float的别名,但是使用GLfloat可以确保在对float有不同定义的硬件或平台上,float的数据类型大小保持一致。
模版测试实现描边
这种描边效果类似外边缘描边,常用于表示物体处与“被选中”的状态,一般不是我们经常在卡通渲染中看到的那种边缘描边。
注:每个glfw窗口都有独立的OpenGL上下文,在ImGui的窗口中操作渲染窗口的OpenGL上下文需要切换上下文环境。
这里的描边会随着模型原理相机而变细,为了更合理需要保证模型描边粗细基本是固定的。相关方法网上已经有很多了,具体内容就是在裁剪空间(clip space)下,将 模型的顶点的xy 沿 法线在xy平面下的单位向量与模型顶点w分量的乘积 偏移【偏移量提前乘以w,原因是在裁剪阶段之后会对顶点的 x,y,z 分量除以 w,将坐标转换为归一化设备坐标(NDC)】
唯一要注意一下的就是,法线在非均匀变换下不能直接用顶点的变换矩阵,否则无法得到正确的法线。
还有一件事,MVP变化都需要处理还是只处理MV变换即可?目前我是MVP都处理了,也是没有问题的。
面剔除实现描边
同样是先渲染模型,然后对顶点沿法线方向偏移一定距离后渲染,再对顶点偏移后的模型剔除朝向相机的面 glCullFace(GL_FRONT),就实现了一个最简单的模型描边。
当然,这种简单粗暴的方法效果可能并不好,比如在上图中模型裙边的四个面,每个面都有自己独立的顶点,结果在沿法线偏移后模型就完全变形了。