美文网首页OpenGL
OpenGL 渲染技巧

OpenGL 渲染技巧

作者: 一尾风影 | 来源:发表于2019-05-16 16:24 被阅读40次

    OpenGL 渲染技巧

    提示: 这个挺重要的.在我们公司项目中这些代码还是经常看到.

    1

    当我们观察空间任意一个不透明的物体时,只能看到物体朝向我们的部分表面.其余被遮挡的部分我们是看不到的.但是如果把这些不应该看到的面/线不做处理时,就会表示不清,很混乱.并且会产生二义性.

    简单说,在旋转的过程中,因为绘制的顺序错乱导致的. 怎么解决?

    油画法

    “画家算法”表示头脑简单的画家首先绘制距离较远的场景,然后用绘制距离较近的场景覆盖较远的部分。画家算法首先将场景中的多边形根据深度进行排序,然后按照顺序进行描绘。这种方法通常会将不可见的部分覆盖,这样就可以解决可见性问题。

    思考:

    • 重复部分,反复绘制是否影响性能?
      15579944317570.jpg
    • 图形重叠,无法分清先后顺序,如何解决?
      15579944433592.jpg

    画家算法无法处理相互重叠的多边形在有些场合下,画家算法可能无法解决可见性问题。在这个例子中,多边形 A、B、C 互相重叠,我们无法确定哪一个多边形在上面,哪一个在下面,我们也无法确定两个多边形什么时候在三维空间中交叉。在这种情况下必须用一些方法对这些多边形进行切分、排序。

    正背面剔除法

    背面剔除,顾名思义,就是在渲染的时候,将背对着观察者的面片丢弃,只将正面朝向观察者(观察者能看到的)面片进行计算。

    举个例子:我们显示的立方体盒子,不管从哪个角度看,我们最多只能看到3个面,有时甚至都只能看到一个面,那么,为什么我们还要对其他看不见的面进行渲染计算呢?将看不见的面剔除,我们最少可以节省50%的CPU和GPU资源。

    其实问题就是如何判断是正面/背面.我们采用的方法是:定义一个顶点绕序来标识成正面,这样,OpenGL在渲染的时候如果看到这个面的顶点绕序不是正面绕序,那就判定其实背面,把它丢弃

    15579945892386.jpg
    • 左侧三角形顶点顺序为: 1—> 2—> 3 ; 右侧三角形的顶点顺序为: 1—> 2—> 3 .
    • 当观察者在右侧时,则右边的三角形方向为逆时针方向则为正面,而左侧的三角形为顺时针则为.面
    • 当观察者在左侧时,则左边的三角形为逆时针方向判定为正面,而右侧的三角形为顺时针判定为背面.

    正面和背面是有三角形的顶点定义顺序和观察者方向共同决定的.随着观察者的角度方向的改变,正面背面也会跟着改变

    //开启表面剔除(默认背面剔除)  
    void glEnable(GL_CULL_FACE);
    
    //关闭表面剔除(默认背面剔除)  
    void glDisable(GL_CULL_FACE);
    
    //用户选择剔除那个面(正面/背面) 
    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
    
    

    深度测试

    在绘制3D场景的时候,需要确定哪些部分对观察者可见,哪些对观察者不可见。OpenGL使用的是Z-buffer方法,也叫深度缓冲区Depth-buffer。

    深度: 深度其实就是该像素点在3D世界中距离摄像机的距离,Z值;深度缓存区,就是一块内存区域,专门存储着每个像素点(绘制在屏幕上的)深度值.深度值(Z值)越大,则离摄像机就越远.

    在不使用深度测试的时候,如果我们先绘制一个距离比较近的物理,再绘制距离较远的物理,则距离远的位图因为后绘制,会把距离近的物体覆盖掉. 有了深度缓冲区后,绘制物体的顺序就不那么重要的. 实际上,只要存在深度缓冲区,OpenGL 都会把像素的深度值写入到缓冲区中. 除非调用 glDepthMask(GL_FALSE).来禁止写入.

    默认情况下,深度缓冲是关闭的,使用时需要显示启用

    深度缓冲区(Detph buffer)同颜色缓冲区(color buffer)是对应的,颜色缓冲区存储的像素的颜色信息,而深度缓冲区存储像素的深度信息。在决定是否绘制一个物体的表面时,首先将表面对应像素的深度值与当前深度缓冲区中的值进行比较,如果大于等于深度缓冲区中值,则丢弃这部分;否则利用这个像素对应的深度值和颜色值,分别更新深度缓冲区和颜色缓冲区。这一过程称之为深度测试(Depth Testing)。

    深度值一般由16位,24位或者32位值表示,通常是24位。位数越高的话,深度的精确度越好。深度值的范围在[0,1]之间,值越小表示越靠近观察者,值越大表示远离观察者。

    //开启深度测试
    glEnable(GL_DEPTH_TEST);
    
    //关闭深度测试
    glDisable(GL_DEPTH_TEST);
    
    //紧张深度缓存区写入
    void glDepthMask(GLBool value);
    value : GL_TURE 开启深度缓冲区写入; GL_FALSE 关闭深度缓冲区写入
    

    感谢胖C老师.

    相关文章

      网友评论

        本文标题:OpenGL 渲染技巧

        本文链接:https://www.haomeiwen.com/subject/uxgiaqtx.html