您的位置:首页 > 其它

[3D 图形学基础] 读书笔记(1) Part_I(Getting Started) - Introduction

2015-01-11 18:59 369 查看
开始读这本书大概有一个多月了吧,前学后忘,所有的知识点都是看我都是“仿佛你曾经明白过我们的样子喔”不做笔记真的是不行了,打算按照书的章节来写,期待我能早日从这本书毕业呢。

介绍一下这本书先:《Foundations of 3D Computer Graphics》, by Steven J. Gortler,http://www.3dgraphicsfoundations.com/,选择读这本书而不是其他许许多多叫得上名字来的图形学经典,因为它看起来非常适合入门,基础扎实,整本书的气质非常干净,印刷精良,插图优美,看着心情就会大好。

看一下封面~很清爽有木有~



以下是第一章,因为非常基础,感觉比在其他地方看到的解释都更好理解,所以基本是通篇翻译过来的,总共也就 4-5 页的样子。

Chapter_IIntroduction

1.1OpenGL

OpenGL 设计的目的是为了实现一系列特定的操作来绘制3D计算机图形,随着硬件越来越便宜,越来越多的功能也被加入到了图形硬件中,并通过 OpenGL API 暴露给用户。随后,通过写一种特定目的的小程序 - shader,用户完全控制图形计算的某个部分也变得可行了。shader
通过 API 来传递和编译,在 OpenGL 中,这些 shader 以 GLSL - 一种类 C 风格的语言来编写。两个可编程的主要部分分别是 vertex shader (顶点着色器) 和 fragment shader (片段着色器)。这两部分之所以开放给用户,一个是因为将这些灵活性提供给用户非常有用,还有一个是因为这部分计算可以通过 single instruction multiple data (SIMD) (单指令多数据结构)来并行完成。处理几何体上不同点的操作可以独立完成,而决定一个像素是否需要被显示也与其他像素完全无关。

在现代的 OpenGL 程序中,许多(并非所有)实际的 3D 图形是由 shader 完成的而非 OpenGL API 自身的一部分。从这个角度讲,OpenGL 更多是关于如何管理你的数据和你的 shader 而更少的关于 3D 计算机图形。随后我们会讲到实现
3D 计算机图形时 OpenGL 所主要进行的步骤,以及不同的 shader 在其中的作用。

在 OpenGL 中,几何体用一些三角面的集合来表示。一方面,三角面对 OpenGL 来说处理起来足够简单和有效率,另一方面,我们可以用三角面来接近非常复杂的 shape (形状、模型)。如果你的计算机图形程序使用更抽象的几何体表示方法,在 OpenGL
绘制它之前必须将它转换为三角面的集合。

简要来说,OpenGL 的计算决定了每个三角面上面每个 vertex(顶点)在屏幕上的位置,找出是哪些屏幕点(即像素),位于每个三角面上,随后再进行一些计算来决定该像素应有的颜色。现在我们更详细的来过一遍这个流程。

每个三角面由三个顶点组成。我们将一些数值数据关联在每个顶点上,这样的数据称为 attribute (属性)。最终,我们需要决定该顶点的位置(二维几何体用2个点而三维几何体用3个点来表示)。我们可以用其他属性来关联其他类型的数据,也会影响最终该顶点的外观。例如,我们也许会关联颜色(RGB)属性到每个顶点上。其他属性也许可以用来描述相关材质属性,例如,一个表面在该顶点有多亮。

将顶点数据从 CPU 转到 GPU开销非常高昂,因此通常要尽量减少该操作。有一种特定的
API 调用来将顶点数据传送给 OpenGL,即将数据存入 vertex buffer (顶点缓存)中。

一旦顶点数据传送给 OpenGL,我们可以在随后的任何时间发送 draw call (绘图调用)到 OpenGL。它会让 OpenGL 读取特定顶点缓存,并将三个一组的顶点绘制为三角面。

一旦给出 draw call 指令,每个顶点(即它的所有属性)都会分别被顶点 shader 处理。除了属性数据, shader 还会访问 uniform variables (统一变量)。这些变量由应用程序所设置,但你只能在 OpenGL draw call
之间设置它们,而不是对每个顶点设置它们。

顶点 shader 是你自己的程序,你可以在其中放任何你想要的内容。顶点 shader 最常见的应用是决定一个顶点最终在屏幕上的位置。例如,一个顶点在其属性中存有自身的 3D 位置数据。同时,还可能存在描述虚拟摄影机3D中位置在2D屏幕映射的统一变量。我们将在随后的章节2-6以及10中讲到这一类的具体计算。

一旦顶点 shader 计算出顶点在屏幕上的最终位置,它将这个值赋给一个保留的输出变量 gl_Position。这个变量的 x 和 y 坐标系被解释为绘图窗口中的位置。左下角为(-1,-1),右上角(1,1)。超出这个方块范围的值即在绘图区域之外。

顶点 shader 也可以输出其他的变量供片段 shader 随后用来决定三角面所覆盖的每个像素的颜色。这些输出被称为 varying variables (变化变量)因为,我们随后也会讲到,它的值在一个三角面中的不同像素间也会有变化。

一旦完成后,这些顶点及其变化变量会被三角面 assembler(装配器)收集,每三个分为一组。

OpenGL 的下一项工作是将每个三角面绘制在屏幕上。这一步称作 rasterization(光栅化)。它用三个顶点位置来放置每一个三角面。并随后计算屏幕上的哪些像素位于该三角面之内。对于每个像素,光栅化程序对于每个变化变量来计算插值。这表示每个变化变量的值,由三个相关的三角形顶点值混合而来。混合的比例与该像素到每个顶点的距离相关。我们将会在第13章讲到混合的具体方法。因为光栅化是一个非常专门并且经过高度优化的操作,这一步是不可编程的。

最终,对于每个像素这些插值数据被传递给片段 shader。片段 shader 是你用 GLSL 编写的另一个随后交给 OpenGL 处理的程序。片段 shader 的职能是通过传递给它的变化及统一变量来决定像素的颜色。这些由片段 shader 最终计算出的颜色被放置在
GPU 内存中叫做 framebuffer (帧缓存)的地方。帧缓存中的数据随后送去显示到它该在屏幕上出现的位置。

在 3D 图形中,我们通常通过计算一些模拟光线从一些材质表面反射方式的公式来决定像素的颜色。该计算也许会用到存储在变化变量中表示某一像素的材质和几何体属性的数据。它或许也会使用保存在统一变量中表示场景中光源位置和颜色的数据。通过改变片段
shader 中的程序, 我们可以模拟光线在不同类型材质上的反弹;这样可以给固定的几何体创建不同的表面变化。我们在14章中会更详细的讲这一过程。

作为颜色计算的一部分,我们也可以指示片段 shader 从存储的附属图像中获取颜色数据。这样的图像称为 texture(纹理)并由统一变量来指定。同时,叫做 texture coordinates (纹理坐标)的变化变量告诉片段 shader 怎样从纹理中获取适合的像素。使用这一过程称作
texture mapping (纹理映射),可以模拟将不同部分的图像粘合到每个三角面上。该过程可以用来给一个由很少三角面组成的简单几何体带来很高的视觉复杂度。(这里是在说法线贴图)随后在第15章会详细讲到。

当颜色被存入帧缓存时,一个称作 merging (合并)的步骤决定了一个从片段 shader 中输出的“新”颜色怎样和或许已经存在于帧缓存中的“旧”颜色混合。当 z-buffering (深度缓冲)被启用时,会进行一个测试,来决定一个刚刚由片段 shader
处理过的几何体点与另一个已经存在于帧缓存中的点相比距离视角更近还是更远。而帧缓存只在新的点更近时被更新。深度缓冲在从三维场景中创建图像时非常有用。我们在第11章中讨论深度缓冲。此外,OpenGL 也可以根据指示用不同比例将新旧两种颜色混合在一起。这个可以用在透明物体上。这一过程称作 alpha blending (透明混合)并在第16章中讨论。因为这个混合步骤涉及到读写共享的内存(帧缓存),这一步骤也是不可编程的,但可以由不同 API 调用来控制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: