This commit is contained in:
Mouse
2018-06-15 10:54:03 +08:00
parent 17c667471c
commit c857b0675c

View File

@@ -1,6 +1,6 @@
# 渲染Rendering
在本章中我们将学习用OpenGL渲染场景时所要做的事情。如果你已经习惯了OpenGL的旧版本就是习惯使用固定管线,你可能会跳过这一章,不想知道为什么它需要这么复杂。让我给你一个建议吧。它其实更简单,更灵活你只需要给它一个机会。现代OpenGL让你只需考虑一个问题,这可以让你以更合理的方式组织代码和开发。
在本章中我们将学习用OpenGL渲染场景时所要做的事情。如果你已经习惯了OpenGL的旧版本习惯使用固定管线,你可能会跳过这一章,不想知道为什么它需要这么复杂。它其实更简单,更灵活你只需要给它一个表现的机会。现代OpenGL让你只需考虑一个问题这可以让你以更合理的方式组织代码和开发。
将三维表示映射到二维屏幕的一系列步骤被称为图形管线(`Graphics Pipeline`。OpenGL最初的版本使用了一个被称为固定管线`Fixed-function Pipeline`的模型。该模型在绘制过程中定义了一组固定的操作步骤。程序员被每一步可用的函数集约束可以使用的效果和进行的操作受到API本身例如“设置雾”或“添加光照”的限制但是这些功能的实现是固定的并且不能改变。
@@ -18,7 +18,7 @@ OpenGL 2.0 引入了可编程管线(`Programmable Pipeline`)的概念。在
几何处理(`Geometry Processing`)阶段将由顶点着色器变化的顶点连接成三角形。它考虑到顶点储存的顺序,并使用不同的模型对它们进行分组。为什么是三角形?三角形(`Triangle`)就是显卡的基本工作单元。它是一个简单的几何形状,可以组合和变换,以构建复杂的三维场景。这个阶段还可以使用特定的着色器来对顶点进行分组。
光栅化(`Rasterization`)阶段接收之前阶段生成的三角形,剪辑们,并将它们转换成像素大小的片元。
光栅化(`Rasterization`)阶段接收此前生成的三角形,剪辑们,并将它们转换成像素大小的片元。
这些片元将在片元处理(`Fragment Processing`)阶段被片元着色器(`Fragment Shader`)使用,以生成像素写入到帧缓冲区的最终颜色。帧缓冲区(`Framebuffer`)是图形管线的最终输出。它储存了每个像素应该被绘制到屏幕上的值。
@@ -56,7 +56,7 @@ void main()
第二行指定此着色器的输入格式。OpenGL缓冲区中的数据可以是我们想要的任何东西也就是说语言不会强迫你传递预定义语义的任何特定数据结构。从着色器的角度来看它希望接收带有数据的缓冲区。它可以是一个坐标一个有一些附加信息的坐标或者我们想要的任何东西。顶点着色器只接收浮点数组。当我们填充缓冲区时我们定义要由着色器处理的缓冲块。
首先,我们需要把这些块变成对我们有意义的东西。现在我们要求从位置0开始我们期望接收由三个属性X、Y、Z组成的向量。
首先,我们需要把这些块变成对我们有意义的东西。现在我们规定从位置0开始我们期望接收由三个属性X、Y、Z组成的向量。
着色器有个主代码块就像任何C语言程序一样这是示例是非常简单的。它只是将接收到的坐标不经任何变换返回到`gl_Position`。你现在可能想知道为什么三个属性的向量被转换成四个属性的向量(`vec4`)。这是因为`gl_Position`仅接受`vec4`类型的数据,因为它是齐次坐标(`Homogeneous Coordinates`)。也就是说,它希望接收到形似(X, Y, Z, W)的东西其中W代表一个额外的维度。为什么还要添加另一个维度在之后的章节中你会看到我们需要做的大部分操作都是基于向量和矩阵的。如果没有额外的维度一些操作不能组合。例如我们不能把旋转和变换操作组合起来。如果你想学习更多有关于这方面的知识这个额外的维度允许我们组合仿射和线性变换。你可以通过阅读《3D Math Primer for Graphics and Game development》作者是Fletcher Dunn 和 Ian Parberry来更多地了解这一点。