跳转至内容

GLSL 编程/OpenGL ES 2.0 管道

来自 Wikibooks,开放书籍,开放世界

OpenGL ES 2.0 管道对于 OpenGL ES 2.0 和 WebGL 中的 GLSL 着色器非常重要。它也与 OpenGL 2.0 管道非常相似,只是缺少了在 OpenGL 的较新版本中被弃用的许多功能。因此,OpenGL ES 2.0 管道不仅对于使用 OpenGL ES 2.0 进行移动图形编程和使用 WebGL 进行基于 Web 的 3D 图形编程的程序员来说高度相关,而且也是学习使用 OpenGL 进行基于桌面的 3D 图形编程(包括 Blender、Unity 和 Torque 3D 等游戏引擎中的 3D 图形)的很好起点。

OpenGL 管道中的并行性

[编辑 | 编辑源代码]

GPU 是高度并行的处理器。这是它们性能的主要原因。事实上,它们实现了两种并行性:垂直并行和水平并行。

福特汽车流水线,1913 年。
  • **垂直并行**描述了在管道不同**阶段**的并行处理。这个概念在福特汽车公司的流水线发展中也至关重要:许多工人可以在相当简单的任务上并行工作。这使得大规模生产(因此也使得大规模消费)成为可能。在 GPU 处理单元的背景下,简单任务对应于不太复杂的处理单元,这节省了成本和功耗。
贝尔飞机公司装配厂,有多条并行装配线,约 1944 年。
  • **水平并行**描述了在**多个管道**中处理工作的可能性。这允许比单个管道中的垂直并行实现更多的并行。同样,这个概念也应用于福特汽车公司和许多其他行业。在 GPU 的背景下,图形管道的水平并行是实现现代 GPU 性能的重要特征。

下图显示了垂直并行(用方框表示的阶段处理)和水平并行(用方框之间的多个箭头表示的每个阶段的多个处理单元)的说明。


顶点数据 例如,由 3D 建模工具提供的三角形网格
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 许多顶点并行处理
顶点着色器 一个小的 GLSL 程序应用于每个顶点
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
图元装配 设置图元,例如三角形、线和点
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 许多图元并行处理
光栅化 对图元(例如三角形)覆盖的所有像素进行数据插值
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 许多片段(对应于像素)并行处理
片段着色器 一个小的 GLSL 程序应用于每个片段(即覆盖的像素)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
每个片段的操作 对每个片段(即覆盖的像素)进行可配置操作
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 许多片段的结果并行写入帧缓冲区
帧缓冲区 存储计算的片段颜色的像素数组


在下图中,任何两个阶段之间只有一个箭头。但是,应该理解,GPU 通常使用大规模的水平并行来实现图形管道。只有 OpenGL 的软件实现,例如 Mesa 3D (参见维基百科条目),通常实现单个管道。

可编程和固定功能阶段

[编辑 | 编辑源代码]

OpenGL ES 1.x 和核心 OpenGL 1.x 的管道是可配置的固定功能管道,即没有包含程序的可能性。在 OpenGL(ES)2.0 中,管道的两个阶段(顶点着色器和片段着色器阶段)是可编程的,即在这些阶段中应用了用 GLSL 编写的微小程序(着色器)。在下图中,可编程阶段用绿色方框表示,固定功能阶段用灰色方框表示,数据用蓝色方框表示。


顶点数据 例如,由 3D 建模工具提供的三角形网格
顶点着色器 一个小的 GLSL 程序应用于每个顶点
图元装配 设置图元,例如三角形、线和点
光栅化 对图元覆盖的所有像素进行数据(例如颜色)插值
片段着色器 一个小的 GLSL 程序应用于每个片段(即覆盖的像素)
每个片段的操作 对每个片段(即覆盖的像素)进行可配置操作
帧缓冲区 存储计算的片段颜色的像素数组


顶点着色器和片段着色器阶段将在特定平台教程中进行更详细的讨论。光栅化阶段在“光栅化”部分中讨论,每个片段的操作在“每个片段的操作”部分中讨论。

图元装配阶段主要包括将图元裁剪到视锥体(屏幕上可见的空间部分)以及可选地剔除正面和/或背面图元。这些可能性将在特定平台教程中进行更详细的讨论。

数据流

[编辑 | 编辑源代码]

为了编程 GLSL 顶点和片段着色器,理解每个着色器的输入和输出非常重要。为此,理解数据如何在 OpenGL 管道的所有阶段之间传递也很有用。这在下图中说明


顶点数据
属性(通常是位置、颜色、法线向量和纹理坐标)
顶点着色器 制服(常量);(可选的纹理数据,但在大多数 OpenGL ES 2.0 实现中没有)
变化量(在顶点),顶点位置和点大小
图元装配
变化量(在顶点),顶点位置和点大小
光栅化
变化量(现在在像素上插值),片段坐标,点坐标,正面标志
片段着色器 制服(常量)和纹理数据(图像)
片段颜色和片段深度
每个片段的操作
片段颜色和片段深度
帧缓冲区


**属性**(或顶点属性,或属性变量)是根据顶点数据定义的。属性中的顶点位置位于对象坐标中,即这是在 3D 建模工具中指定的 位置。

**制服**(或制服变量)对于渲染特定图元(例如三角形)时执行的所有顶点着色器和所有片段着色器具有相同的值。但是,它们可以针对其他图元进行更改。通常,顶点变换、光源和材质的规范等作为制服指定。

**变化量**(或变化量变量)必须由顶点着色器和片段着色器一致地定义(即顶点着色器必须定义与片段着色器相同的变化量变量)。通常,变化量定义用于颜色、法线向量和/或纹理坐标。

**纹理数据**包括一个制服采样器,它指定纹理采样单元,而纹理采样单元反过来指定从中获取颜色的纹理图像。

其他数据将在特定平台的教程中描述。

进一步阅读

[编辑 | 编辑源代码]

OpenGL ES 2.0 管道在“OpenGL ES 2.0.x 规范”和“OpenGL ES 着色语言 1.0.x 规范”中进行了全面详细的定义,这些规范可在“Khronos OpenGL ES API 注册表”中获得。

Addison-Wesley 出版了 Aaftab Munshi、Dan Ginsburg 和 Dave Shreiner 撰写的《OpenGL ES 2.0 编程指南》一书的第 1 章,其中对 OpenGL ES 2.0 管道进行了更易于理解的描述(参见其网站)。


< GLSL 编程

除非另有说明,否则本页面上的所有示例源代码均归属公共领域。
华夏公益教科书