前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android OpenGL 介绍和工作流程(十)

Android OpenGL 介绍和工作流程(十)

原创
作者头像
PengJie
修改2021-01-11 09:58:20
2.1K0
修改2021-01-11 09:58:20
举报

OpenGL是什么?

简单来说OpenGL API是一套接口,通过这套接口我们可以在那些支持OpenGL的机器上对图形硬件设备特性进行访问,例如在电脑屏幕或手机屏幕上进行图形绘制。也就是说OpenGL一个进行图形开发的规范,而它的实现是硬件设备厂商提供的,而这些实现通常被称为“驱动”,它们负责将OpenGL定义的API命令翻译为硬件指令。

OpenGL ES是什么?

OpenGL ES (OpenGL for Embedded Systems)是 OpenGL 的子集,在 OpenGL 的基础之上裁剪掉了一些非必要的部分,针对手机、PDA 和游戏主机等嵌入式设备而设计。

OpenGL绘制过程

其实在OpenGL中,所有物体都是在一个3D空间里的,但是屏幕都是2D像素数组,所以OpenGL会把3D坐标转变为适应屏幕的2D像素。而这个从3D往2D坐标系变化的工作称为OpenGL的图形渲染管道。

图形渲染管道的工作过程如上图所示,主要分成两个部分。第一部分把你的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素。这个过程可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。所有这些阶段都是高度专门化的(它们都有一个特定的函数),并且很容易并行执行。正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。这些小程序叫做着色器(Shader)。

1.我们分析一下这个工作过程,开始是以数组的形式传递3个3D坐标作为图形渲染管线的输入,用来表示一个三角形,这个数组叫做顶点数据;顶点数据是一系列顶点的集合。一个顶点Vertex是一个3D坐标的数据的集合。而顶点数据是用顶点属性表示的,它可以包含任何我们常用数据,比如顶点的位置和颜色

我们可以观察上图,在OpenGL中的物体是有重多的顶点表示的三角形共同构成。这时候我们也许会有一个疑问为什么OpenGL选择使用三角形构建物体?

是因为OpenGL本质上就是绘制三角形的图形第三方库,而三角形正好是基本图元。而不是绘制不了矩形,只是显卡本身绘制三角形会轻松很多,而要把矩形作为OpenGL的基本图元将会消耗更多的性能。

2.顶点着色器(Vertex Shader),它把一个单独的顶点作为输入。顶点着色器主要的目的是把3D坐标转为另一种3D坐标,同时顶点着色器允许我们对顶点属性进行一些基本处理。

3.图元装配阶段将顶点着色器输出的所有顶点作为输入(如果是GL_POINTS,那么就是一个顶点),并所有的点装配成指定图元的形状。

4.几何着色器把图元形式的一系列顶点的集合作为输入,它可以通过产生新顶点构造出新的(或是其它的)图元来生成其他形状。

5.光栅化阶段(Rasterization Stage),这里它会把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素,用来提升执行效率 。

6.片段着色器的主要目的是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色。

7.Alpha测试和混合(Blending)阶段,检测片段的对应的深度值,用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查alpha值(alpha值定义了一个物体的透明度)并对物体进行混合(Blend)。所以,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个三角形的时候最后的像素颜色也可能完全不同。

OpenGL坐标系变换的过程

之前我们已经提到在OpenGL中,所有物体都是在一个3D空间里的,但是屏幕都是2D像素数组,所以OpenGL会把3D坐标转变为适应屏幕的2D像素。坐标变换的目标,简单来说,就是把一个3D空间中的对象最终投射到2D的屏幕上去。这也正是计算机图形学(computer graphics)所要解决的其中一个基础问题。当我们观察3D世界的时候,是通过一块2D的屏幕,我们真正看到的实际是3D世界在屏幕上的一个投影。坐标变换就是要解决在给定的观察视角下,3D世界的每个点最终对应到屏幕上的哪个像素上去。当然,对于一个3D对象的坐标变换,实际中是通过对它的每一个顶点(vertex)来执行相同的变换得到的。最终每个顶点变换到2D屏幕上,再经过后面的光栅化(rasterization)的过程,整个3D对象就对应到了屏幕的像素上,我们看到的效果就相当于透过一个2D屏幕「看到了」3D空间的物体(3D对象)。

下面的图展示了整个坐标变换的过程:

我们先来简略地了解一下图中各个过程:

1.首先,一个3D对象的模型被创建出来之后,是以本地坐标(local coordinates)来表达的,坐标原点(0, 0, 0)一般位于3D对象的中心。不同的3D对象对应各自不同的本地坐标系(local space)。

2.3D对象的本地坐标经过一个model变换,就变换到成了世界坐标。不同的对象经过各自的model变换之后,就都位于同一个世界坐标系中了,它们的世界坐标就能表达各自的相对位置。一般来说,model变换又包含三种可能的变换:缩放、旋转、平移。在计算机图形学中,一个变换通常使用矩阵乘法来计算完成,因此这里的model变换相当于给本地坐标左乘一个model矩阵,就得到了世界坐标。后边将要介绍的view变换和投影变换,也都对应着一个矩阵乘法。

3.在同一个世界坐标系内的各个3D对象共同组成了一个场景(scene),对于这个场景,我们可以从不同的角度去观察。当观察角度不同的时候,我们眼中看到的也不同。为了表达这个观察视角,我们会再建立一个相机坐标系观察空间view space。从世界坐标系到相机坐标系的转换,我们称之为view变换。当我们用相机这个词的时候,相机相当于眼睛,执行一个view变换,就相当于我们把眼睛调整到了我们想要的一个观察视角上。

4.对相机坐标执行一个投影变换(projection),就变换成了裁剪坐标(clip coordinates)。在裁剪坐标系下,x、y、z各个坐标轴上会指定一个可见范围,坐标超过可见范围的顶点(vertex)就会被裁剪掉,这样,3D场景中超出指定范围的部分最终就不会被绘制,我们也就看不到这些部分了。这个投影变换,是从3D变换到2D的关键步骤。之所以会有这么一步,是因为我们总是通过一个屏幕来观察3D场景,类似于透过一扇窗户观察窗外的景色,屏幕不是无限大的,因此一定存在某些观察视角,我们看不到场景的全部。看不到的场景部分,就是通过这一步被裁剪掉的,这也是「裁剪」这一词的来历;另一方面,把3D场景投射到2D屏幕上,也主要是由这一步起的作用。

5.剪裁坐标(clip coordinates)经过一个特殊的perspective division的过程,就变换成了NDC坐标(Normalized Device Coordinates)。由于这个过程在OpenGL ES中是自动进行的,我们不需要针对它来编程,因此我们经常把它和投影变换放在一起来理解。我们可以不太严谨地暂且认为,相机坐标经过了一个投影变换,就直接得到NDC了。NDC是什么呢?它才是真正的由OpenGL ES来定义的坐标。在NDC的定义中,x、y、z各个坐标都在[-1,1]之间。因此,NDC定义了一个边长为2的立方体,每个边从-1到1,NDC中的每个坐标都位于这个立方体内(落在立方体外的顶点在前一步已经被裁剪掉了)。值得注意的是,虽然NDC包含x、y、z三个坐标轴,但它主要表达了顶点在xOy平面内的位置,x和y坐标它们最终会对应到屏幕的像素位置上去。而z坐标只是为了表明深度关系,谁在前谁在后,因此z坐标只是相对大小有意义,z的绝对数值是多大并不具有现实的意义。

6.NDC坐标每个维度的取值范围都是[-1,1],但屏幕坐标并不是这样,而是大小不一。以分辨率720x1280的屏幕为例,它的x取值范围是[0, 720],y的取值范围是[0,1280]。这样NDC坐标就需要一个变换,才能变换到屏幕坐标,这个变换被称为视口变换。在OpenGL ES中,这个变换也是自动完成的,但需要我们通过glViewport接口来指定绘制屏幕的大小。这里还需要注意的一点是,屏幕坐标与屏幕的像素还不一样。屏幕坐标是屏幕上任意一个点的精确位置,简单来说就是可以是任意小数,但像素的位置只能是整数了。这里的视口变换是从NDC坐标变换到屏幕坐标,还没有到最终的像素位置。再从屏幕坐标对应到像素位置,是后面的光栅化完成的。

小结

整个OpenGL绘制技术是基于图形渲染管道的,我们只有掌握了图形渲染管道的工作流程,了解我们在编码过程中,需要进行的设置和操作,同时掌握对象顶点坐标在OpenGL各坐标系变换规则,才能踏入OpenGL的开发门槛。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OpenGL是什么?
  • OpenGL ES是什么?
  • OpenGL绘制过程
  • OpenGL坐标系变换的过程
  • 小结
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档