图形学基础
深度测试
本节Reference:https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/01%20Depth%20testing/
计算流程:深度缓冲是在片段着色器运行之后(以及模板测试(Stencil Testing)运行之后)在屏幕空间中运行的。
接口
- glEnable(GL_DEPTH_TEST);
- glClear(GL_DEPTH_BUFFER_BIT);
- glDepthMask(false);
- glDepthFunc(GL_LESS);
深度值精度问题
-
线性变换
这不是实际的透视投影对z值的变换公式。 -
非线性变换
透视投影矩阵对z的变换公式,可以根据举证变换公式推导。具体变换如下图所示,可见其接近近平面时变化较快,精度也相对较高,远平面附件则精度较低,这也符合我们希望的在较远处不需要记录太精确的深度值。
深度冲突解决方法
- 手动移动深度很接近的物体,例如给一个offset偏移;
- 使用更高精度记录深度值,比如使用两个float记录;
- 尽可能将近平面设置的远一些,因为近平面如果设置较近,则精度记录教精确,发生深度冲突的可能性就更大;
模板测试
接口
- glEnable(GL_STENCIL_TEST);
- glClear(GL_STENCIL_BUFFER_BIT);
- glStencilMask(0x00);// 0xff
- glStencilFunc(func:GL_LESS测试函数,ref设置用于与模板缓冲比较的值,mask掩码用于在比较之前和ref进行与运算);
- glStencilOp((GLenum sfail, GLenum dpfail, GLenum dppass)
用途(高亮物体轮廓)
- 开启深度测试,关闭模板测试,正常绘制地板
- 开启模板测试,gl_stencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);glStencilMask(0xff);glStencilFunc(GL_AlWAYS,1,0xff);绘制BOX;
- box放大一点点,禁止模板写入(可读取)和深度测试,glStencilMask(0x00);glStencilFunc(GL_NOT_EQUAL,1,0xff);
面剔除
- glEnable(GL_CULL_FACE) 开启面剔除(一般不会把视角放到物体内部的话可以开启这个,比如地球球体可以开启因为视角不会钻到地下)
- glCullFace(GL_FRONT)默认配置,前向面剔除
- glFrontFace(GL_CCW)默认配置,逆时针为前向面(这个和数据定义有关,一般数据准备都是逆时针顺序定义三角面片的)
混合
利用blend的普通混合
- 将不透明物体先绘制,然后将半透明物体进行排序,按照从远到近的顺序进行逐步绘制;每次绘制时,根据colorBuffer上结果结合混合公式得到当前DrawCall的绘制结果;