Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0

管道 如前所属,本书讲解的API版本是OpenGL ES 3.0。本书的目标是,深入讲解OpenGL ES 3.0的技术细节,给出具体的例子来说明如何使用某个特性,并且讨论了各种性能优化技术。当您读完这本书,您应该可以对OpenGL ES 3.0API有一个很好的把握。您将可以轻松的写出让人新服的OpenGL ES 3.0的应用程序,并且您不必通过阅读多种OpenGL ES的规范来搞懂某个特性是如何工作的。 OpenGL ES 3.0实现了可编程着色图形管道。OpenGL ES 3.0规范包含两部分:OpenGL ES 3.0 API的规范和OpenGL ES 3.0 着色语言规范(OpenGL ES SL)。 下图1-1描述了OpenGL ES 3.0的图形管道。图中有阴影的模块代表OpenGL ES 3.0图形管道中可变成的阶段。下面将逐个介绍OpenGL ES 3.0图形管道的各个阶段。 Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0
文章图片
顶点着色器(Vertex Shader) 本节将给出顶点着色器的一个高层次的概述。顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)将在以后的章节中做详细的介绍。顶点着色器实现了一套用来操作顶点的通用的方法。 顶点着色器的输入如下:

  • 着色器程序(Shader Program) ——用来对顶点进行操作的顶点着色程序源代码或者可执行程序。
  • Attribute ——由顶点列表提供的每个顶点的数据。
  • Uniform —— 顶点着色器(或者片段着色器)使用的常亮。
  • Sampler(采样器) —— 一种特殊类型的Uniform,它代表了每个顶点着色器使用的纹理。
在OpenGL ES 2.0中顶点着色器的输出被乘坐Varying变量,但是在OpenGL ES3.0中被重命名为“顶点着色器输出变量(vertex shader output variables )”。在原始光栅化阶段,每个生成片段的顶点着色输出值被计算出来,这些被计算出的值将会被作为片段着色器的输入。用来计算每个片段上顶点着色输出值的机制被乘坐“差值( interpolation )”。此外,OpenGL还提供一个一个新的功能,叫做变换反馈( transform feedback )。变幻反馈允许将顶点着色器的输出值有选择的写入输出缓存中。例如,在第14章中,有一个在顶点着色器中实现粒子系统的程序实例。在这个程序中,变换反馈就被输出到了一个缓存对象中。顶点着色器的输入和输出如下图所示。 Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0
文章图片
顶点着色器可以用于传统的基于顶点的操作,如通过矩阵变换位置,计算光线方程来产生每顶点颜色,纹理坐标生成或转换。另外,由于顶点着色器可以由应用程序指定,所以可以在顶点着色器中使用自定义的数学方法,来实现传统固定管道中无法实现的新的变换,光照以及基于定点处理的特殊效果。 Example 1-1 展示了一个用OpenGL ES着色语言实现的顶点着色器。本书以后的章节中将非常消息的介绍顶点着色器,而此处给出这个例子,只是想让读者了解顶点着色器大概是个什么样子。在Example1-1的顶点着色器中,将位置(position)和颜色(color)作为输入,使用一个4*4的矩阵对位置做变换,然后输入变换后的位置和颜色。 着色器程序的第一行,提供了着色语言的版本。版本信息必须出现在着色器的第一行。本例子中的“#version 300 es” 表示OpenGL ES着色语言的版本是v3.00 。第二行,描述了一个Uniform变量u_mvpMatrix,他保存了模型视图和投影矩阵。第七和第八行描述了顶点着色器的输入。其中a_position是顶点的位置属性,a_color是顶点的颜色属性。第十二行,声明了一个输出变量v_color。这个变量作为顶点着色器的输出之一,保存了每个顶点的颜色。gl_Position是一个内建变量,它找着色器中被自定生命,并且,OpenGL ES要求顶点着色器必须将变换之后的顶点位置赋值给这个变量。一个顶点着色器(或者片段着色器)有唯一的一个程序入口叫做main方法。第13行到第17行描述了顶点着色器的main方法。第15行,我们从定点输入属性a_color读取丁点的颜色值,然后将它作为顶点着色器输出的颜色,保存在v_color中。第16行,将变幻之后的顶点位置保存在顶点着色器输出gl_Position中。 图元装配(Primitive Assembly ) OpenGL ES 3.0图形渲染管道中,在定点着色器之后的一个阶段是图元装配。图元指的是一个几何对象,例如三角形,直线或者点精灵。图元的每个顶点数据被发送给顶点着色器的不同copy。在图元组装阶段,这些被处理过的顶点数据又被传回给图元。 对于每个图元,必须要确定其是否处在透视锥内部(透视锥就是3D空间中在屏幕上可见的部分)。如果某个图元不是完全被包含在透视锥的内部,这个图元就需要被透视锥切割。如果图元是完全处在透视锥以外,那么这个图元将被抛弃。在透视锥对图元进行切割之后,顶点的坐标被转换成屏幕坐标。也可以根据指定渲染的方式是正面(face forward)还是反面(backward),舍弃不需要被渲染的部分图元。这个操作被称作消隐(Culling)。在完成了切割和消隐之后,图元被传送给渲染管道的下一个阶段——光栅化阶段。 光栅化(Rasterization) 下一个阶段,如Figure1-3所示,是光栅化阶段。在这个阶段相关的图元(如点精灵、直线和三角形)将被描绘。光栅化过程是要完成将图元转化成一组可以在之后的片段着色器上被处理的二维片段的过程。这些片段代表着可以被花到屏幕上的像素点。 Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0
文章图片
片段着色器(Fragment Shader) 片段着色器实现了一套操作片段的通用的编程方法。如Figure1-4所示,片段着色器是用来处理每一个在光栅化阶段生成的片段的。片段着色器的输入如下:
  • 着色器程序(Shader Program)—— 片段着色器的源代码或者可执行程序。它描述了着色器将对片段执行那些操作。
  • 输入变量——顶点着色器的输出变量,在光栅化阶段通过插值方法得到的每个插值单元,在此处被作为片段着色器的输入。
  • Uniform——片段着色器中需要使用的常量。
  • 采样(Samples)——特殊类型的Uniform,代表着片段着色器使用的纹理。
片段着色器可以抛弃片段,或者生成一个或多个被作为片段着色器输出的颜色值。 通常情况下,片段着色器只会产生一个颜色值,除非是需要向多个渲染目标进行渲染操作(参考第11章的多目标渲染相关的章节)。对于多目标渲染的情况,输出的每一个颜色值对应一个渲染目标。在OpenGL ES 3.0的图形渲染管道中,颜色、深度、模板、以及在光栅化阶段中生成的屏幕坐标被作为每个片段操作的输入。 Exeample1-2描述了一个简单的片段着色器。Exeample1-2的片段着色器和Exeample1-1的顶点着色器组合起来,就可以画出一个高氏着色(Gouraud-shaded)三角形。同样,我们会在本书的后面章节详细介绍片段着色器。我们此处给出找个例子只是让读者对片段着色器有个基本的了解。 Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0
文章图片
就像前面介绍的顶点着色器一样,第一行,给出了找色语言的版本,这个版本信息必须出现在着色器代码的第一行(#version 300 表示对应的OpenGL ES找色语言版本是v3.00)。第二行,设置了默认的精度限制符。精度限制符会在第四章“着色器和着色程序”中详细介绍。第四行描述了片段着色器的输入。OpenGL ES 要求顶点着色器中必须输出相同的一组变量,之后这组变量的值会在片段着色器中会被读入。第六行声明了片段着色器的输出变量。这个输出的颜色值会作为下一个阶段的输入。第七行至第十行,描述了片段着色器的main方法。此处,输出的颜色值被赋值为输入的颜色值。片段着色器的输入是在光栅化过程中被插值的数据,然后这些数据被传送给片段着色器。 逐个片段的处理(Per-Fragment Operations) 在片段着色器之后,是逐个片段的处理。光栅化过程中生成的坐标为(x,y)的片段,只能修改帧缓存(framebuffer)中坐标为(x,y)位置的想素。Figure1-5描述了OpenGL ES 3.0中逐个片段操作阶段。 Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0
文章图片
如Figure1-5所示,逐个片段处理阶段对每个片段执行的操作如下:
  • 像素归属测试(Pixel ownership test)—— 这个测试过程将决定帧缓存中位置为(x,y)的像素当前是否归OpenGL ES所有。这个测试中允许窗口系统来决定帧缓存中的像素是否属于当前OpenGL ES上下文。例如,如果用来显示OpenGL ES帧缓存的窗口被另一个窗口遮住了,窗口系统就可以决定被遮住的像素不属于OpenGL ES上下文。这样,这些遮住的像素就不会被显示。尽管像素所属测试是属于OpenGL ES的一部分,它却是OpenGL内部机制来实现的,而不是由开发者来控制的。
  • 剪裁测试(Scissor test)—— 剪裁测试用来确定坐标为(x,y)的点是否落在OpenGL ES的部分状态确定出的剪裁矩形内部。如果片段是在剪裁区域的外部,这个片段就会被丢弃。
  • 模板和深度测试(Stencil and depth测试)—— 模板和深度测试分表作用在片段的模板和深度值上。通过这些测试,可以确定是否要丢弃当前片段。
  • 混合(Blending)—— 混合是根据片段的颜色值和帧缓存中对应位置的颜色值进行混合,生成新的颜色的操作。
  • 抖动(Dithering)—— 通过使用抖动,可以最小化由于在帧缓存中使用有限精度导致的图像上的瑕疵。
逐个片段处理阶段最终操作,是在帧缓冲取(x,y)坐标确定的位置上写入该片段的颜色值、深度值、模板值,或者将该片段丢弃掉。如果在各种测试之后,没有丢弃该片段,那么,不管颜色、深度、模板相关的写入掩模(write mask)有没有被启用,对这些值的写入操作都会被执行。写入掩模可以更好的控制写入相关缓存的颜色、深度和模板值。例如,针对颜色缓存的写入掩模可以被设置成只有红色值可以写入到颜色缓存中。此外,OpenGL ES 3.0提供了一个从缓存区中读取像素值的接口。 注意: alpha测试和“逻辑操作”不在包含在逐个片段处理阶段中。在OpenGL ES 2.0和OpenGL ES 1.x中,这两个操作曾经是支持的。片段着色器可以丢弃片段,alpha测试等价的操作可以在顶点着色器中完成,所以alpha测试就没有存在的必要了。对于逻辑操作,在应用开发中是很少使用的,而且OpenGL ES的工作组也没有收到独立应用开发者针对OpenGL ES 2.0 中支持逻辑操作的需求。所以,这个功能也在OpenGL中被放弃了。 【Chapter|Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0】转载于:https://www.cnblogs.com/laomao-alex/p/4631357.html

    推荐阅读