跳转至

第 2 节:三维(3D)图形的要素

Elements of 3D Graphics

当我们转向3D图形时,我们发现最常见的方法与矢量图形(vector graphics)更相似,而不是光栅图形(raster graphics)。也就是说,图像的内容被指定为一组几何对象的列表。这种技术称为几何建模(geometric modeling)。起点是构建一个“人工3D世界”,作为在三维空间中排列的简单几何形状的集合。这些对象可以具有属性(attributes),结合世界的全局属性,确定对象的外观。通常,基本形状的范围非常有限,可能仅包括点、线段和三角形。如果一个更复杂的形状,例如多边形或球体,不被认为是基本形状,那么它可以被构建或近似为更基本的形状的集合。为了制作场景的二维图像,将场景从三维投影(projected)到二维。投影相当于对场景拍摄照片。让我们稍微详细地看一下它是如何工作的。

首先是几何...... 我们从一个空的3D空间或“世界”开始。当然,这个空间只在概念上存在,但将其视为真实并且能够在脑海中可视化是有用的。该空间需要一个坐标系(coordinate system),将空间中的每个点与三个数字相关联,通常称为点的x、y和z坐标。这个坐标系称为“世界坐标(world coordinates)”。

我们想要在世界中建立一个场景,由几何对象组成。例如,我们可以通过给出线段的两个端点的坐标来指定场景中的一条线段,通过给出三角形的三个顶点的坐标来指定一个三角形。我们要处理的最小的构建块,例如线段和三角形,称为几何基元(geometric primitives)。不同的图形系统提供不同的基元集合,但在许多情况下,只考虑非常基本的形状,例如线条和三角形。一个复杂的场景可能包含大量的基元,通过为每个单独的基元给出显式坐标来创建场景将非常困难。任何程序员应该立即猜到的解决方案是将基元组合成可重复使用的组件。例如,对于包含多辆汽车的场景,我们可以创建一个车轮的几何模型。一辆汽车可以建模为四个车轮以及其他组件模型的集合。然后我们可以在场景中使用几个汽车模型的副本。请注意,一旦设计了一个几何模型,它就可以作为更复杂模型中的组件使用。这被称为分层建模(hierarchical modeling)

假设我们已经用几何基元构建了一个车轮模型。当将该车轮移动到汽车模型中的位置时,所有基元的坐标都必须调整。那么通过构建车轮我们究竟获得了什么?关键在于车轮中的所有坐标都以相同的方式调整。也就是说,为了将车轮放置在汽车中,我们只需要指定一个应用于整个车轮的单一调整。所使用的“调整”类型称为几何变换(geometric transform)。几何变换用于调整几何对象的大小、方向和位置。当制作汽车模型时,我们建立一个车轮。然后我们对车轮模型应用四个不同的变换,以将四个车轮添加到汽车中。同样,我们可以通过对同一汽车模型应用不同的变换,向场景中添加几辆汽车。

三种最基本的几何变换称为缩放(scaling)旋转(rotation)平移(translation)。缩放变换用于设置对象的大小,即通过某个指定因子使其变大或变小。旋转变换用于设置对象的方向,通过围绕某个特定轴旋转一定角度来旋转对象。平移变换用于设置对象的位置,通过将其从原始位置移动一定量来平移它。在本书中,我们将首先在二维中遇到这些变换,因为它们更容易理解。但在3D图形中,它们变得真正重要。

When we turn to 3D graphics, we find that the most common approaches have more in common with vector graphics than with raster graphics. That is, the content of an image is specified as a list of geometric objects. The technique is referred to as geometric modeling. The starting point is to construct an "artificial 3D world" as a collection of simple geometric shapes, arranged in three-dimensional space. The objects can have attributes that, combined with global properties of the world, determine the appearance of the objects. Often, the range of basic shapes is very limited, perhaps including only points, line segments, and triangles. A more complex shape such as a polygon or sphere can be built or approximated as a collection of more basic shapes, if it is not itself considered to be basic. To make a two-dimensional image of the scene, the scene is projected from three dimensions down to two dimensions. Projection is the equivalent of taking a photograph of the scene. Let's look at how it all works in a little more detail.

First, the geometry.... We start with an empty 3D space or "world." Of course, this space exists only conceptually, but it's useful to think of it as real and to be able to visualize it in your mind. The space needs a coordinate system that associates each point in the space with three numbers, usually referred to as the x, y, and z coordinates of the point. This coordinate system is referred to as "world coordinates."

We want to build a scene inside the world, made up of geometric objects. For example, we can specify a line segment in the scene by giving the coordinates of its two endpoints, and we can specify a triangle by giving the coordinates of its three vertices. The smallest building blocks that we have to work with, such as line segments and triangles, are called geometric primitives. Different graphics systems make different sets of primitives available, but in many cases only very basic shapes such as lines and triangles are considered primitive. A complex scene can contain a large number of primitives, and it would be very difficult to create the scene by giving explicit coordinates for each individual primitive. The solution, as any programmer should immediately guess, is to chunk together primitives into reusable components. For example, for a scene that contains several automobiles, we might create a geometric model of a wheel. An automobile can be modeled as four wheels together with models of other components. And we could then use several copies of the automobile model in the scene. Note that once a geometric model has been designed, it can be used as a component in more complex models. This is referred to as hierarchical modeling.

Suppose that we have constructed a model of a wheel out of geometric primitives. When that wheel is moved into position in the model of an automobile, the coordinates of all of its primitives will have to be adjusted. So what exactly have we gained by building the wheel? The point is that all of the coordinates in the wheel are adjusted in the same way. That is, to place the wheel in the automobile, we just have to specify a single adjustment that is applied to the wheel as a whole. The type of "adjustment" that is used is called a geometric transform (or geometric transformation). A geometric transform is used to adjust the size, orientation, and position of a geometric object. When making a model of an automobile, we build one wheel. We then apply four different transforms to the wheel model to add four copies of the wheel to the automobile. Similarly, we can add several automobiles to a scene by applying different transforms to the same automobile model.

The three most basic kinds of geometric transform are called scaling, rotation, and translation. A scaling transform is used to set the size of an object, that is, to make it bigger or smaller by some specified factor. A rotation transform is used to set an object's orientation, by rotating it by some angle about some specific axis. A translation transform is used to set the position of an object, by displacing it by a given amount from its original position. In this book, we will meet these transformations first in two dimensions, where they are easier to understand. But it is in 3D graphics that they become truly essential.


接下来是外观... 单独的几何形状并不是很有趣。你必须能够设置它们的外观。这是通过给几何对象分配属性(attributes)来完成的。一个明显的属性是颜色,但实现逼真的外观远比简单地为每个基元指定一个颜色要复杂得多。在3D图形中,我们通常不谈论颜色,而是谈论材质(material)。这里的材质指的是确定表面固有视觉外观的属性。基本上,这意味着表面与击中表面的光线如何相互作用。材质属性可以包括基本颜色以及其他属性,如光泽度(shininess)、粗糙度(roughness)和透明度(transparency)。

最有用的材质属性之一是纹理(texture)。在最一般的术语中,纹理是一种在表面点与点之间变化材质属性的方式。纹理最常见的用途是允许不同点有不同的颜色。这通常是通过使用二维图像作为纹理来实现的。图像可以应用到表面上,使得图像看起来像是“绘制”在表面上。然而,纹理也可以指变化的值,比如透明度或“凹凸不平”。纹理允许我们在不使用大量几何基元的情况下为场景添加细节;而是使用较少数量的带有纹理的基元。

材质是对象的 固有属性 (intrinsic property),但对象的实际外观还取决于对象所处的环境。在现实世界中,除非环境中有一些光线,否则你看不到任何东西。在3D图形中也是如此:你必须在场景中添加 模拟光线(simulated lighting)。场景中可以有几个光源。每个光源都可以有自己的颜色、强度和方向或位置。然后,来自这些光源的光将与场景中对象的材质属性相互作用。图形系统中的光照支持可以从相当简单到非常复杂和计算密集的范围内。

Next, appearance.... Geometric shapes by themselves are not very interesting. You have to be able to set their appearance. This is done by assigning attributes to the geometric objects. An obvious attribute is color, but getting a realistic appearance turns out to be a lot more complicated than simply specifying a color for each primitive. In 3D graphics, instead of color, we usually talk about material. The term material here refers to the properties that determine the intrinsic visual appearance of a surface. Essentially, this means how the surface interacts with light that hits the surface. Material properties can include a basic color as well as other properties such as shininess, roughness, and transparency.

One of the most useful kinds of material property is a texture. In most general terms, a texture is a way of varying material properties from point-to-point on a surface. The most common use of texture is to allow different colors for different points. This is often done by using a 2D image as a texture. The image can be applied to a surface so that the image looks like it is "painted" onto the surface. However, texture can also refer to changing values for things like transparency or "bumpiness." Textures allow us to add detail to a scene without using a huge number of geometric primitives; instead, you can use a smaller number of textured primitives.

A material is an intrinsic property of an object, but the actual appearance of the object also depends on the environment in which the object is viewed. In the real world, you don't see anything unless there is some light in the environment. The same is true in 3D graphics: you have to add simulated lighting to a scene. There can be several sources of light in a scene. Each light source can have its own color, intensity, and direction or position. The light from those sources will then interact with the material properties of the objects in the scene. Support for lighting in a graphics system can range from fairly simple to very complex and computationally intensive.


最后,图像... 一般来说,3D图形的最终目标是生成3D世界的2D图像。从3D到2D的转换涉及视图(viewing)投影(projection)。当从不同的视角观察时,世界看起来不同。为了设置一个视角,我们需要指定观察者的位置和观察者的朝向。还需要指定一个“上(up)”方向,即在最终图像中将指向上方的方向。这可以被看作是将一个“虚拟相机”放置到场景中。一旦视图设置好了,从那个视角看到的世界可以投影到2D中。投影类似于使用相机拍照。

最终的3D图形步骤是将颜色分配给2D图像中的单个像素。这个过程称为光栅化(rasterization),而生成图像的整个过程被称为渲染(rendering)场景。

在许多情况下,最终的目标不是创建单个图像,而是创建一个动画(animation),其中包含一系列显示不同时刻世界的图像。在动画中,从序列中的一个图像到下一个图像有微小的变化。场景的几乎任何方面在动画期间都可以发生变化,包括基元的坐标、变换、材质属性和视图。例如,可以通过逐渐增加应用于对象的缩放变换中的比例因子来使对象在动画过程中增长。在动画期间改变视图可以使得效果看起来是在场景中移动或飞行。当然,计算所需的变化可能会很困难。有许多技术可以帮助进行计算。其中最重要的之一是使用“物理引擎(physics engine)”,它根据物理定律计算对象的运动和相互作用。(然而,本书不会介绍物理引擎。)

Finally, the image.... In general, the ultimate goal of 3D graphics is to produce 2D images of the 3D world. The transformation from 3D to 2D involves viewing and projection. The world looks different when seen from different points of view. To set up a point of view, we need to specify the position of the viewer and the direction that the viewer is looking. It is also necessary to specify an "up" direction, a direction that will be pointing upwards in the final image. This can be thought of as placing a "virtual camera" into the scene. Once the view is set up, the world as seen from that point of view can be projected into 2D. Projection is analogous to taking a picture with the camera.

The final step in 3D graphics is to assign colors to individual pixels in the 2D image. This process is called rasterization, and the whole process of producing an image is referred to as rendering the scene.

In many cases the ultimate goal is not to create a single image, but to create an animation, consisting of a sequence of images that show the world at different times. In an animation, there are small changes from one image in the sequence to the next. Almost any aspect of a scene can change during an animation, including coordinates of primitives, transformations, material properties, and the view. For example, an object can be made to grow over the course of an animation by gradually increasing the scale factor in a scaling transformation that is applied to the object. And changing the view during an animation can give the effect of moving or flying through the scene. Of course, it can be difficult to compute the necessary changes. There are many techniques to help with the computation. One of the most important is to use a "physics engine," which computes the motion and interaction of objects based on the laws of physics. (However, you won't learn about physics engines in this book.)