至此,渲染过程需要关注对象的形体绘制了。现在要论述从颜色的角度来看这些形体。很多因素决定了要渲染到屏幕上的像素的颜色。这些因素包括应用在三角形的材质、纹理、照在对象上的光,以及当前的雾效。
对象有四种基本的颜色属性——漫反射,环境光反射,镜面反射和放射:
n 散射颜色:对象的一个特定部分的基本颜色
n 环境色:颜色的亮度最低水平
n 镜面颜色:颜色的镜面发射(即反射的颜色)
n 点光源:一个特定点上发出的颜色
颜色信息保存在对象的顶点里。如果三角形的三个顶点有着同样的颜色,那么此三角形会有同样的颜色。如果顶点有不同的颜色,那么三角形的颜色会从一个顶点逐渐变化到另一个顶点的颜色。
决定三角形里给定像素的颜色的另一个因素是当前使用的着色类型。标准管线我们可以选择的有两个着色方法:平面和高洛德(Gouraud)。平面着色方法最快速,它使用多边形的第一个顶点的颜色值来为多边形着色。这个方法的缺点是每个多边形的轮廓相当明显。除非你想达到某种特殊效果,否则我建议不要使用平面着色。
首选的方法是高洛德着色。这种方法使用于每个顶点的颜色数据,以及顶点法线和光照数据,用以确定所使用的颜色。它还插值顶点之间的颜色。最终的效果是,物体的外观更光滑,更自然。因为着色由视频卡搞定,这正是我们想要的。
顶点着色,有时候也叫做材质着色,是给物体着色的一个方法。而另一个方法提供了更好的外观细节是纹理。纹理是这么一个过程,它把位图的一部分应用到每个三角形。位图上的图像提供了额外的细节。还有适用于预定的替代材质灯光和凹凸信息的纹理。这会使平坦的表面看起来有阴影和不规则。根据您的视频卡的功能,它可以合并多达8个纹理再传递给一个多边形。每个纹理也可能有多个mipmaps。 Mipmaps是一个给定的纹理在不同分辨率下的一系列版本。每个级别的mipmap的尺寸是它父亲的一半。如果mipmapping正在使用时,当多边形远离视点时会自动使用较小的纹理。
多重纹理通过使用纹理阶段(texture stages)实现。使用SetTexture方法为每个阶段设置一个纹理,并用阶段索引指定这个阶段(阶段索引从0开始)。纹理的混合操作也在每个纹理阶段使用SetTextureStageState方法设置。纹理混合操作指定每张纹理是怎样和前一阶段的相结合,从而产生传递给下一阶段或者渲染器的新纹理。第一个阶段的操作通常是指定第一张纹理怎样和多边形的材质颜色相结合。表3-2列出了纹理阶段的各种操作和一个阶段的描述。表3-3列出了每个阶段可以设置的状态。
表3-2:纹理阶段的操作
操作 | 描述 |
ADD | Adds the components of the two arguments |
ADDSIGNED | Adds the components of the two arguments and subtracts 0.5 |
ADDSIGNED2X | Functions the same as ADDSIGNED, with a 1 bit shift left |
ADDSMOOTH | Performs the operation (argument 1+argument 2)−(argument 1×argument 2) |
BLENDCURRENTALPHA | Blends arguments using the alpha from the previous stage |
BLENDDIFFUSEALPHA | Blends the arguments using alpha data from vertices |
BLENDFACTORALPHA | Blends arguments using a scalar alpha |
BLENDTEXTUREALPHA | Blends arguments using alpha data from this stage texture |
BLENDTEXTUREALPHAM | Blends arguments using a premultiplied alpha |
BUMPENVMAP | Performs per-pixel bump mapping without luminance |
BUMPENVMAPLUMINANCE | Performs per-pixel bump mapping with luminance |
DISABLE | Disables output from the texture stage |
DOTPRODUCT3 | Modulates all color channels including alpha |
LERP | Performs linear interpolation between two arguments proportioned by a third argument |
MODULATE | 将参数的每个成分相乘 |
MODULATE2X | 将参数的每个成分相乘,并将乘积左移1位,等同于乘以2的效果 |
MODULATE4X | 将参数的每个成分相乘,并将乘积左移2位,等同于乘以4的效果 |
MODULATEALPHA_ADDCOLOR | Modulates the color of the second argument with the alpha from the first argument |
MODULATECOLOR_ADDALPHA | Modulates color of the arguments and adds alpha from the first argument |
MODULATEINVALPHA_ADDCOLOR | Functions the same as MODULATEALPHA_ADDCOLOR, but uses inverse of alpha |
MODULATEINVCOLOR_ADDALPHA | Functions the same as MODULATECOLOR_ADDALPHA, but uses inverse of color |
MULTIPLYADD | Multiplies the second and third argument and adds in the first argument |
PREMODULATE | Modulates this texture stage with the next stage |
SELECTARG1 | Uses the first color or alpha argument as the output |
SELECTARG2 | Uses the second color or alpha argument as output |
SUBTRACT | Subtracts the components of argument 2 from argument 1 |
表3-3:纹理阶段状态
操作 | 描述 |
ADDRESSU | Specifies the addressing mode for the U coordinate (wrap, clamp, etc.) |
ADDRESSV | Specifies the addressing mode for the V coordinate (wrap, clamp, etc.) |
ADDRESSW | Selects the texture addressing method for the W coordinate |
ALPHAARG0 | Selects the setting for the third alpha argument for triadic operations |
ALPHAARG1 | Designates the first argument for the alpha operation |
ALPHAARG2 | Designates the second argument for the alpha operation |
ALPHAOP | Specifies that this stage is a texture-alpha blending operation |
BORDERCOLOR | Specifies the color to use for out-of-range texture coordinates |
BUMPENVLOFFSET | Indicates offset value for bump map luminance |
BUMPENVLSCALE | Indicates scale value for bump map luminance |
BUMPENVMAT00 | Specifies the [0] [0] coefficient for the bump mapping matrix |
BUMPENVMAT01 | Specifies the [0] [1] coefficient for the bump mapping matrix |
BUMPENVMAT10 | Specifies the [1] [0] coefficient for the bump mapping matrix |
BUMPENVMAT11 | Specifies the [1] [1] coefficient for the bump mapping matrix |
COLORARG0 | Selects the setting for the third color argument for triadic operations |
COLORARG1 | Designates the source for the first argument for the operation |
COLORARG2 | Designates the source for the second argument for the operation |
COLOROP | Specifies texture-color blending operation (values for which appear in Table 3–2) |
MAGFILTER | Specifies the type of filtering to use for texture magnification |
MAXANISOTROPY | Specifies the maximum level of anisotropy |
MAXMIPLEVEL | Specifies the highest level of mipmap that will be used |
MINFILTER | Specifies the type of filtering to use for texture minification |
MIPFILTER | Specifies the type of filtering to use between mipmap levels |
MIPMAPLODBIAS | Specifies a bias factor in selecting mipmap levels |
RESULTARG | Selects the destination for the stage’s operation (default is the next stage) |
TEXCOORDINDEX | Specifies which texture coordinates out of a possible eight sets to use |
TEXTURETRANSFORMFLAGS | Controls the transformation of texture coordinates for this stage |
存储在多边形每个顶点的纹理坐标决定了应用到多边形的纹理。纹理坐标存储在顶点的U和V变量里。可以认为U是纹理的X坐标,V是纹理的Y坐标。纹理坐标是在0.0和1.0之间的浮点值。使用这个范围,不管纹理的尺寸是16x16还是512x512都没有关系。由坐标定义的那一部分图像会应用到多边形上。还有过滤功能,可以指定图像怎么压缩和扩展以便匹配多边形的尺寸。通常让DirectX决定使用哪个过滤方法。如果缺省的方法会导致问题,我们便需要确定用个另外的什么方法(如果有)来达到更好的效果。
注意:注意到前文纹理的尺寸都是2的幂。这一点很重要。视频卡往往期望纹理尺寸总是2的幂。即使有些纹理操作似乎接受尺寸为奇数的纹理,仍然不建议你使用奇数尺寸的纹理。在操作的内部会调整纹理大小到2的幂。创建你的纹理为2的幂,并使之成为习惯,这样你会避开很多的麻烦。
尽管我们把纹理应用到多边形上了,但是仍然没有得到显示在屏幕上的最终颜色。现在我们需要考虑光照效果。环境光的颜色和强度,以及场景中定义的其他的灯光,根据不同的面法线和有向灯光的方向和像素的颜色相结合。
场景中可以定义三种类型的灯:点光源,方向灯,射灯:
n 点光源:从一个指定的位置辐射开来(像从电灯泡辐射的灯光)。
n 方向灯:从给定的方向的无限远处照射来(像太阳光)。
n 射灯:像汽车的前灯产生一个圆锥体的灯光。
对于这些灯,像定义顶点的漫反射、镜面和环境光颜色一样定义他们。照在表面上的灯光的颜色和表面的颜色叠加在一起,从而计算出最终颜色。
我们可能仍然没有为我们的像素计算出最终颜色。如果我们为场景定义了雾,这会对颜色值做一个最终调整。雾使物体的颜色褪色,否则由一个使用视点的距离的函数来计算雾的颜色值(Fog works by fading the color of objects from their otherwise calculated values to the fog color as a function of the distance from the viewpoint.)。过渡到雾颜色的精确比率依赖于雾效的最小和最大距离,以及雾的衰减公式。当我们为场景设置雾效时,这些属性要全部定义。你将在第七章学到灯光和雾的更多知识。