OpenGL的简单理解

2022-10-12  本文已影响0人  小沛2016

最近一段时间重新学了一下OpenGL ES,记录一下,感觉最近两年记忆力不如从前了。

常见的图形渲染方案

状态机

OpenGL 是一个状态机。

什么是状态机呢?

状态机中有几个术语:state(状态) 、transition(转移) 、action(动作) 、transition condition(转移条件) 。

state(状态) :比如电扇可以划分为关、一档、二档、三档等状态。

transition(转移) :一个状态接收一个输入执行了某些动作到达了另外一个状态的过程就是一个transition(转移)。定义transition(转移)就是在定义状态机的转移流程。

transition condition(转移条件) :也叫做Event(事件),在某一状态下,只有达到了transition condition(转移条件),才会按照状态机的转移流程转移到下一状态,并执行相应的动作。

action(动作):在状态机的运转过程中会有很多种动作。如:进入动作(entry action)[在进入状态时进行]、退出动作(exit action)[在退出状态时进行]、转移动作[在进行特定转移时进行]。

OpenGL是状态机的理解

OpenGL 的状态通常被称为 OpenGL 上下文(Context)。我们通常使用如下途径去更改 OpenGL 状态:设置选项,操作缓冲。最后,我们使用当前 OpenGL 上下文来渲染。

假设当我们想告诉 OpenGL 去画线段而不是三角形的时候,我们通过改变一些上下文变量来改变 OpenGL 状态,从而告诉 OpenGL 如何去绘图。一旦我们改变了 OpenGL 的状态为线段绘制模式,下一个绘制命令就会画出线段而不是三角形。

当使用 OpenGL 的时候,我们会遇到一些状态设置函数(State-changing Function),这类函数将会改变上下文。以及状态使用函数(State-using Function),这类函数会根据当前 OpenGL 的状态执行一些操作。

渲染管线

一个一个状态的切换以及在不同状态中的渲染逻辑和数据处理构成了 OpenGL 的渲染管线。

理解渲染管线之前可以先从一道面试题入手

问:假设有一千万个球,你如何渲染?

首先看所有球的位置,看是否重合,然后再看要渲染的角度,因为太多球了,如果你观察的距离很近,那可能只需渲染寥寥几个球,而且可能会出现一球蔽目的情况

然后我们再回忆一下小时候画画的经历

首先,我们都是把轮廓勾勒出来,然后再细化,最后上色

其实渲染流程也是如此

顶点着色器 → 图元装配 → 几何着色器 → 光栅化 → 片段着色器 → 测试与混合

OpenGL 主要有三种着色器:顶点着色器、几何着色器、片段着色器,其中顶点着色器和片段着色器为开发者必须提供,几何着色器为可选提供。

为什么要使用几何着色器?
由于几何着色器可以在顶点发送到下一着色阶段之前对他们随意变换,所以他的作用就是将一个图元变换为另一个完全不同的图元,或者修改图元的位置

image.png

上图中每个方格表示一个片段,片段上的数值表示当前片段的深度,R 则表示深度无限,加号表示 2 个图形叠加一起,则由下面部分的图可知,当 2 个图形叠加在一起的时候,同一个位置的片段总是显示深度较小的那一个。
模板缓冲区是用于控制屏幕需要显示的内容,屏幕大小决定了模板缓冲区大小;模板测试基于模板缓冲区,从而让我们完成想要的效果。模板测试类似于与运算:

image.png

上图可以看出,模板就是每个片段位置有 0 也有 1,然后和缓冲中的图像数据对应片段进行类似与运算,也类似与拿一个遮罩罩住,只留下 1 的对应片段显示出来。
混合则是计算带有透明度的片段的最终颜色,在这个阶段会与显示在它背后的片段的颜色按照透明度进行叠加行成新的颜色,通俗讲就是形成透明物体的效果。

image.png

由图可以看出,通过混合,右边的窗户既有部分自己的颜色,又有窗户里面物体的部分颜色,就是两者透明度按照比例叠加的结果。

于是走完整个渲染管线流程,我们的渲染工作就算是告一段落了。

再来回顾一下这条渲染管线做了哪些事情:

首先我们传入了图形的顶点数据,然后 OpenGL 内部会按照指定的图元类型自动将顶点连成图形,然后再将图形内的区域切成一个个小片段,然后给每个小片段自由上色,最后把被挡住的或者我们不想显示的区域的下片段丢弃,并且对有透明度的片段进行前后片段颜色的混合。

【参考资料】
https://mp.weixin.qq.com/s/XNiDto9ABfTCCpptDktHng

上一篇下一篇

猜你喜欢

热点阅读