OpenGL渲染管线流程
MVP坐标的转换 模型在变换的过程中一定要遵循 平移 旋转 缩放的顺序,否则将会影响场景中的最终顺序
图元装配,图元是指一些基本的几何实体,点GL_POINTS,直线 GL_LINES,三角形GL_TRANGLES
图元装配的输入来自顶点着色器的输出,最后输出到光栅化阶段,其中包括三个阶段,裁剪、透视分割和视口变换。在图元装配过程,顶点经历不同的坐标系统,首先以本地坐标空间输入到OpenGL ES,在顶点着色器执行之后,顶点进入裁剪坐标空间,这一坐标变换通过顶点着色器中定义的uniform变量完成,随后经过透视分割进入规范化设备坐标空间,最后经过视口变换进入窗口坐标空间。
裁剪有一个裁剪体或者叫视景体,通过坐标(Xc,Yc,Zc,Wc)指定,由上、下、左、右、远、近共六个平面组成,位于裁剪体之外的图元将被裁剪抛弃,避免处理不必要的图元。需要注意的是,三角形、直线的裁剪在硬件中的执行代价可能很高,部分在x和y平面之外的图元不一定需要裁剪,通过渲染到一个大于glViewport指定的视口尺寸的视口,x和y平面中的裁剪变成剪裁操作Scissor,GPU可以高效地实施剪裁,这个更大的视口区域被称作保护带区域。
透视分割取得裁剪坐标(Xc,Yc,Zc,Wc)指定的点,并将其投影到视口上,每个坐标除以Wc也就是(Xc/Wc,Yc/Wc,Zc/Wc,Wc/Wc),得到规范化的设备坐标(Xd,Yd,Zd),其值位于-1.0到1.0之间,包括边界值。
视口是一个二维矩形窗口区域,是所有OpenGL ES渲染操作最终显示的地方,在视口变换阶段,坐标(Xd,Yd)根据视口的大小将被转换为真正的窗口坐标,Zd根据glDepthRangef指定的near和far深度值将被转换为窗口的Z值。视口变换调用如下的glViewport完成,x和y指定左下角坐标,单位是像素,初始值为(0,0),width和height指定宽和高,初始值为eglCreateWindowSurface中指定的EGLNativeWindowType的值
模型变换 观察变换 投影变换 视口变换
渲染管线主要分为三个阶段:
1.应用程序阶段:主要是CPU与内存打交道,例如碰撞检测,计算好的数据(顶点坐标、法向量、纹理坐标、纹理)就会通过数据总线传给图形硬件 。
2.几何阶段:主要负责顶点坐标变换、光照、裁剪、投影以及屏幕映射,在该阶段的末端得到了经过变换和投影之后的顶点坐标、颜色、以及纹理坐标。简而言之,几何阶段的主要工作就是“变换三维顶点坐标”和“光照计算”。
》顶点变换(Vertex Transformation)或坐标系变换,包括:
Object space,模型坐标;
World space,世界坐标;
Eye space,视点坐标(这里进行视锥裁剪);
Clip and Project space,视景体裁剪空间坐标(也叫屏幕坐标,在这里进行 投影、剪裁、映射的过程)。
eye space坐标转换到project and clip space坐标的过程其实就是一个投影、剪裁、映射的过程。
(1),用透视变换矩阵把顶点从视锥体变换到CVV中;
(2),在CVV内进行剪裁;
(3),屏幕映射:将经过前两步得到的坐标映射到屏幕坐标系上。
3.光栅阶段:
》图元装配(Primitive Assembly)。
》光栅化和插值(Rasterization and Interpolation)。
(三维模型经过了顶点变换已经投影到了二维平面上,而且被装配成图源了,但是屏幕是一个一个细细小小的像素格子组成的,对于一个图片,电脑是怎么知道应该把它搞到哪几个像素上去显示的呢?这就是光栅化。说白了就是,把想看见的图片,搞成像素能显示的。光栅化工作告诉了显卡,哪个格子是你这个图形应该画上的,哪个不是)
》像素操作(Pixel Operation)也叫光栅操作,包括:像素所有权测试->裁剪测试->alpha测试->模板测试->深度测试->混合->抖动显示->逻辑操作
》帧缓冲区(Frame Buffer)包括颜色缓冲器,深度缓冲区,模板缓冲区等,而在像素操作阶段的一些测试直接影响是否会将当前像素的信息更新到帧缓冲区。