一、问题场景:
在 3D 图形的渲染过程中,我们是需要来决定哪部分是要对观察者 可见/不可见 的,对于不可见的部分,我们就没有渲染的必要了,要及早丢弃掉他们。例子:一间草屋,我们站在门前的时候,草屋的背后我们是看不到的,那么就不要渲染它了。否则就会出现下图中的场景(我们绘制一个立体图形后 对其进行旋转操作查看时,背面我们本应是看不到的面也被看到了),叫做“隐藏面消除”(Hidden surface elimination)。

背面为什么黑色呢?光源着色器,想象一下我们在太阳光下,光打下来,朝阳和背阳的两个场景下,是不是一面亮一面暗呢。
二、解决方案
1:油画算法
先绘制画面中距离观察者远的物体,再绘制较近的物体。由远及近,如下图,远的会被近物遮住。

但是如果是下面这种场景,油画算法就无法解决了:

这种每个面都要看到部分的场景怎么办呢?
2、正背面剔除(Face Culling)
背景:
想象一个 3D 图形,从任何一个?向去观察,我们最多可以看到?个?? 最多3面。从?个?方体的任意位置和?向上看,最多不可能看到多于3个面。那么,为何还要多余的去绘制那些根本看不到的3个面呢? 如果能以某种?式去丢弃这部分数据, OpenGL 在渲染的性能就可以提高超过 50% 呢。
问题分析:
如何知道某个?在观察者的视口中不会出现? 任何平?都有2个面:正?/背面。这意味着我们在一个时刻只能看到一?。
OpenGL 可以做到检查所有正面朝向观察者的面 并渲染它们,?丢弃背?朝向的面,这样可以节约片元着??的性能。
OpenGL 如何知道我们绘制的图形哪是正面呢?可通过分析顶点数据的顺序。
分析顶点数据:
1)正背面区分:OpenGL 中 按逆时针进行顶点相连的三角形面为 正面,顺时针相连的三角形面为 背面 -- 规则如此

2)立方体的正背面

眼睛在右侧时,右边顶点按逆时针顺序,为正面,左侧为顺时针背面;眼睛在左侧时,则左侧为正面。
归结:
正面和背面是由三角形的顶点定义顺序鹅观察者方向共同决定的,随着观察者观察角度的改变,正背面也会跟着改变。
解决操作:
a、开启表面剔除(默认背面剔除)
void glEnable(GL_CULL_FACE);
b、关闭表?剔除(默认背面剔除)
void glDisable(GL_CULL_FACE);
c、用户选择剔除哪个面(正面/背面)
void glCullFace(GLenum mode); // mode参数为: GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,默认GL_BACK ?户指定旋转顺序哪个为正面
void glFrontFace(GLenum mode); // mode参数为: GL_CW、GL_CCW,默认值:GL_CCW
例子,剔除正面的实现
(1) glCullFace(GL_BACK);
glFrontFace(GL_CW);
(2) glCullFace(GL_FRONT);
我们对背面进行剔除后,图形好像正常了,但是,旋转到一定角度,发现:

这又是怎么回事儿呢?
3、Z-buffer 方法(深度缓冲区Depth-buffer)
待续...
OpenGL 四 - 001、OpenGL 立体图形渲染 - 深度缓冲区
原文:https://www.cnblogs.com/zhangying-domy/p/13276529.html