Real-Time Rendering 4th Edition 实时渲染第四版 第六章 纹理的处理(Texturing)

“All it takes if for the rendered image to look right.” 我们需要做的就是让渲染出来的图像看起来正确而已
——Jim Blinn

一个表面的纹理包括它的外观和它所能带给人的感觉——试着去联想一下油画的纹理。在计算机图形学中,纹理处理(texturing,后续小节中将直接使用英文原文单词)是这样一个过程:先获取到表面,通过使用一些图像、函数或者其他某些数据来源来调整表面的外观表现。例如,在表现一面砖墙时,我们不是去极其细致得表现砖墙的几何结构(译者注:不是不能),而是通过应用一个彩色的砖墙的图像到一个长方形上(由两个三角形面组成)。当我们去观察这个长方形时,可以看到彩色图像出现在了长方形所在的位置。除非观察者靠得足够得近,否则他很难注意到几何细节的缺失的。

但是,仅仅这样处理的墙面并不足以令人感觉到真实可信,这其中的原因也不仅仅是几何细节的缺失。例如,如果砂浆应该是亚光的,而砖头是光亮的,观众会注意到两种材料的粗糙度是一样的。为了制造出一种更加可信的体验,这时可以利用另外一张图像纹理到表面上。但是这张纹理要做的不是去改变表面的颜色,而是去依照表面上的位置改变表面的粗糙度。现在砖块和砂浆从之前图像纹理中获得了颜色,从后面这张纹理中获得了粗糙度的值。

现在观察者可以看到所有的砖块都是光滑的而砂浆不是,但是同时也能注意到每个砖块的面都看起来太过于平整了。这并不是正常的现象,因为通常砖块表面都有一些不规则的地方。通过应用凹凸纹理映射(bump mapping,或者可以称为凹凸贴图)技术,砖块的法线可以随意改动变化,从而当他们进行渲染的时候,表面看起来就不是完全的光滑平整。这种纹理会使矩形的原始表面法线方向变得不那么规规矩矩,从而可以在计算照明时获得和之前不同的效果。

当我们从墙体侧面以一个极小的角度来观察时,凹凸的错觉瞬间就会没有了。砖块应该相较于砂浆更加得突出,甚至在某些观察的角度下可能会发生一些遮挡。即便是从正视视角观察,砖块也应该会在砂浆上产生阴影。视差纹理映射(parallax mapping,或者可以称为视差贴图)技术中使用了一张纹理来在渲染时令一个平整的表面发生变形(译者注:看起来产生变形,本质上并没有,和后面的displacement mapping有相似但也有本质上的不同),同时视差遮挡纹理映射(parallax occlusion mapping)技术将光线投射到高度场纹理上,从而提高真实感。位移纹理映射(displacement mapping)技术是真正得通过修改构成模型的三角形的高度来让表面发生位移。图6.1中展示了一个关于颜色纹理处理和凹凸纹理映射的例子。

在这里插入图片描述
图 6.1. 纹理处理。颜色和凹凸贴图被直接应用到这条鱼上,从而增加了其视觉层面的细节。(图像由Elinor Quittner提供)

这些就是可以利用纹理以及越来越多的精巧的算法可以解决的问题的类型。在本章节中主要会涉及到纹理技术的各种细节。首先,我们会展现纹理处理的通用框架。然后,我们会集中精力于使用图像来制作表面纹理,这也是实时渲染中最受欢迎的一种纹理使用方式。然后会简短得讨论一下程序化纹理,并且解释一些使用纹理来影响表面效果的通用的方法。

6.1 The Texturing Pipeline(纹理处理管线)

texturing是一种有效模拟表面材料和表面处理变化的技术。要理解这种技术,可以从每个着色的单独像素上入手,看看其上到底发生了什么。前面章节也看到过,着色的计算中其实考虑到了材质和光的颜色,以及一些其他因素。透明度也是影响采样的因素之一。texturing则是通过改变着色方程中用到的值来发挥作用。这些值一般是基于其原本在表面上的位置而进行调整。因此,对于之前提到的那个砖墙的例子,原本表面上任意一个点的颜色都依据其在表面上的位置被替换为砖墙图片上对应的颜色。图像纹理上的像素被称为是纹素(texel),以此来和屏幕上的像素来作区分。粗糙度纹理改变了粗糙度值,而凹凸问题改变了着色法线的方向。这些共同影响着着色方程的结果。

texturing可以用一个通用化过的纹理管线来描述。这里可能会瞬间引入许多术语,但是请铭记于心:管线的每个部分都会详细得进行描述。

空间中的某个位置是texturing过程的起始点。这个位置可以是在世界空间内的,但是更加普遍的是在模型空间的参考系里,从而当模型移动时,纹理遍会随之一起移动。引用Kershaw的术语,空间中的这个点应用投影仪(projector)函数,随之得到一组数字,称为是纹理坐标(texture coordinate),即可以通过使用这些值来对纹理进行访问。这个过程被称为是映射(mapping),进而演变成纹理映射(texturing mapping)。有些时候纹理图片本身会被称为是纹理贴图(texture map),当然严格意义上讲其实并不正确。

在使用这些值去访问纹理之前,可以使用一个或多个对应器(corresponder)函数可用于将纹理坐标转换到纹理空间。然后这些纹理空间中的位置可以用来获取纹理上对应的值,即它们可以是一个图像纹理的数组索引,从而可以检索到其上的每一个像素。然后,检索到的数值可能会再次被一个数值转换函数所转换,最后这些新的数值被用来修改表面的某些属性,如材料或阴影法线。图6.2详细得展示了一个单独的纹理的应用过程。管线看起来复杂的原因是,在其中每个步骤都为用户提供了有用的控制手段。应该注意的是,并非所有的步骤都需要在全部时间都激活。

在这里插入图片描述
图 6.2. 单独纹理的通用纹理管线。

图6.3展示了使用这个管线,当一个三角形有一个砖墙纹理并在其表面生成一个采样点时,所经历的过程。在物体的局部坐标系下可以确定该一个具体的坐标 ( x , y , z ) (x,y,z) (x,y,z),我们这里假设为 ( − 2.3 , 7.1 , 88.2 ) (-2.3,7.1,88.2) (2.3,7.1,88.2)。然后对这个位置坐标应用一个投影仪函数。类似于世界地图(可以理解为是三维物体投影到了二维),投影仪函数是将 ( x , y , z ) (x,y,z) (x,y,z)向量变成了二元向量 ( u , v ) (u,v) (u,v)。这个例子中使用的投影函数就等同于正交投影(参考2.3.1小节),就像是投影仪一样,将砖墙的图像投射到三角形表面上。再回到墙面上,其表面上的点的位置可以转换为一组范围在0到1之间的值。假设得到的值为 ( 0.32 , 0.29 ) (0.32,0.29) (0.32,0.29)。这些纹理坐标要用来寻找这个位置上对应的图像的颜色是什么。假设我们的砖块纹理的分辨率为 256 × 256 256 \times 256 256×256,所以对应器函数将 ( u , v ) (u,v) (u,v)分别乘以256,得到 ( 81.92 , 74.24 ) (81.92,74.24) (81.92,74.24)。忽略掉分数部分,可以在砖墙图片上找到像素 ( 81 , 74 ) (81,74) (81,74),对应的颜色值为 ( 0.9 , 0.8 , 0.7 ) (0.9,0.8,0.7) (0.9,0.8,0.7)。纹理颜色是在sRGB的颜色空间内,因此如果想要在着色方程中使用该颜色,需要把他转换为线性空间,得到 ( 0.787 , 0.604 , 0.448 ) (0.787,0.604,0.448) (0.787,0.604,0.448)(参考5.6小节)。
在这里插入图片描述
图 6.3. 砖墙的管线。

6.1.1 The Projector Function(投影仪函数)

纹理处理中的第一个步骤就是获取表面位置并且将它投影到纹理坐标空间中,通常是一个二维 ( u , v ) (u,v) (u,v)空间。建模工具包通常都会允许艺术创作者们去逐顶点得定义其 ( u , v ) (u,v) (u,v)坐标。这些的初始化过程可以是在投影仪函数或网格解包算法中初始化的。艺术创作者们可以用他们熟悉的方式,以编辑顶点位置的方法来编辑 ( u , v ) (u,v) (u,v)坐标。投影机函数通常所做的工作就是在将空间中的三维点转换为纹理坐标。建模程序中常用的函数包括球面、圆柱和平面投影。

投影仪函数也会使用一些其他的输入。例如,可以依据表面法线来选择六个平面投影方向中具体哪一个用于表面。纹理匹配的问题在于表面接缝的位置;Geiss讨论了在其间进行混合的技术。Tarini等人描述了多立方体贴图,在其中,一个模型被映射到一组立方体投影上,而不同的空间体积对应着不同的立方体。

其他投影仪函数就完全不是投影了,而是表面创建和表面细分的其中的部分。例如,参数化曲面的定义中有一组天然的 ( u , v ) (u, v) (u,v)值。参考图6.4。纹理坐标也可以由其他很多不同的参数来生成,比如说观察方向、表面的温度、或者其他任何可以想象出的东西。投影仪函数的目标是生成纹理坐标。以位置的函数的自变量来推导只是其中的一种方法。

在这里插入图片描述
图 6.4. 不同的纹理投影。从左到右依次是球面的,柱面的,平面的,以及天然面的 ( u , v ) (u,v) (u,v)投影。下面的一行展示了这些投影方法应用到同一个物体上的不同效果。

非交互式渲染器经常将这些投影仪函数作为渲染流程的其中一部分来进行调用。一个单一的投影仪函数可能足以满足整个模型的需要,但通常艺术创作者必须使用工具对模型进行细分,并且在不同的部分上分别应用各种不同的投影仪函数。参考图6.5。

在这里插入图片描述
图 6.5. 多种纹理投影在一个模型上的使用。箱体映射由六个平面映射组成,每个箱体表面都对应着一个映射。(图像由Tito Pagan提供)

在工作中,投影仪函数通常是应用在模型构建阶段,投影的结果存储在了顶点上。这并不总是如此;有时在顶点或像素着色器中应用投影功能是有利的。这样做有利于提升精度,而且可以激活各种效果,包括一些动画效果(6.4小节)。一些渲染方法,如环境映射(environment mapping,10.4小节),会有特定的投影仪函数,并会去逐像素进行计算。

球面投影(图6.4的左侧)会投射点到一个想象的球面上。这个投影方法和Blinn和Newell的环境映射法(10.4.1小节)中使用的是一样的,公式10.30即是在描述这个函数。这种投影方法存在与该节所述的顶点插值相同的问题。

柱面投影在计算纹理坐标 u u u时是和球面投影一样的,而纹理坐标 v v v则被计算为沿着圆柱轴线的距离。这个投影对于那些用于自然轴线的物体是非常有用的,例如回转表面。当表面接近垂直于圆柱体的轴线时,就会发生扭曲变形。

平面投影就像是x光线一样,沿着某个方向平行得进行投射并且将纹理应用到所有的表面。它使用了正交投影(4.7.1小节)。这种类型的投影在应用贴花时时很有用的(20.2小节)。

由于与投影方向相邻的表面存在严重的扭曲,艺术创作者往往必须手动将模型分解为接近平面的一个个小块。也存在一些工具可以通过将网格解开,或者创建一组近乎最佳的平面投影,亦或是以某种其他的方式加速这一过程,从而帮助最小化扭曲的负面效果。我们的目标是让每个多边形在纹理的面积上分配得相对更加公平,同时也尽可能地保持住原有网格的连通性。连通性很重要,因为在纹理的不同部分相接的边缘位置可能会出现采样缺陷。如果网格被拆解得好的话可以大大简化艺术创作者的工作。16.2.1小节讨论了纹理扭曲在渲染上可能会产生的不利影响。图6.6展示了创作图6.5中的建筑的工作区。这个解包过程是另一个大领域的其中一个层面,即网格参数化(mesh parameterization)。感兴趣的读者可以去到SIGGRAPH上的由Hormann等人开设的课程。

在这里插入图片描述
图 6.6. 建筑模型的一些小一点的纹理,存储在了两个较大一些的纹理中。右边的图片三角形网格是如何被解包出来的,并且显示在纹理之上以使创作过程变得更加方便。(图像由Tito Pagan提供)

纹理坐标空间并不总是二维平面的;一些时候它也使三维。在这种情况下,纹理坐标可以由一个三个元素的向量表示 ( u , v , w ) (u,v,w) (u,v,w),其中 w w w为投影方向上的深度。其他系统升值会用到多至4个坐标,经常记为 ( s , t , r , q ) (s,t,r,q) (s,t,r,q) q q q被用来表示其次坐标中的第四个值。它的作用类似于电影或幻灯机,投射的纹理大小随距离增加而增加。例如,它可以用于向舞台或其他表面投射装饰性聚光灯图案,称为图案灯(gobo)。

纹理坐标空间的另一个重要类型是方向性的,其中空间中的每个点都通过一个输入方向来进行访问。将这种空间可视化的一种方法是想象一个单位球体上的那些点,每个点的法线就代表着用于访问该位置的纹理的方向。使用这种方向性参数化方法的最常见的纹理类型是立方体地图(cube map,详见6.2.4小节)。

还有一个值得注意的是,一维纹理图像和函数也有着他们的用处。例如,在一个地面模型上,其颜色可以是由海拔高度决定的,即,较低处是绿色;山峰处是白色。线也可以有纹理;这个的其中一个用途是将雨水渲染成一组长线,然后对线用半透明的图像进行纹理处理。这样的纹理也可以用来作为值与值之间的对应和转化,即,作为一个查找表来使用。

因为多个纹理可以用到一个表面上,那可能需要定义多组纹理坐标。但是其思路都是一致的:这些纹理坐标在表面上进行插值计算,然后通过他们来获取纹理上的值。但是在插值之前,这些纹理坐标还需要经过 corresponder function 的变换。

6.1.2 The Corresponder Function(对应器函数)

corresponder function 可以将纹理坐标转换为纹理空间内的位置。这在将纹理应用到表面上提供了更多的灵活性。相关的一个例子是,使用API来选择现有纹理的一部分进行显示;仅仅这个子图像会被用于后续的操作。

另一种类型的 corresponder 是矩阵变换,这可以应用在顶点或者像素着色器中。它一般可以用来实现平移、旋转、缩放、剪切以及将纹理投射到表面等操作。前面4.1.5小节中也讨论过,变换的顺序非常重要。令人惊奇的是,纹理变换的顺序和世界坐标变换的顺序是完全相反的。这是因为纹理变换实际上影响的是那个决定图像被看到的位置的空间。图像本身并不是被变换的物体;而是定义图像位置的空间在发生改变。

另一类 corresponder function 控制的是图像被应用的方式。我们知道,图像会出现在表面上 ( u , v ) (u,v) (u,v) [ 0 , 1 ] [0,1] [0,1] 范围内的区域。但是这个区域之外该怎么处理呢?corresponder function会决定相关的行为。在OpenGL里,这个类型的 corresponder function 称为是环绕模式(warpping mode);在DirectX中,它被称为是纹理定位模式(texture addressing mode)。这个类型常用的corresponder function有:

  • 环绕(warp,DirectX中所使用的术语),重复(repeat,OpenGL中所使用的术语),或是平铺(tile)——图像会在表面上进行重复出现;从算法上讲,是纹理坐标的整数部分被忽略掉了。对于那种需要材质重复出现以完全覆盖掉的表面来说,这个函数是非常有用的,而它也常常是默认的一种方式。
  • 镜像(mirror)——图像在表面上重复出现,但是每次重复都是以镜像的方式。例如,图像正常得出现在0到1上,然后再1到2之间是翻转的,再2到3上又以正常的方式出现,然后又翻转,就这样一种循环重复。这某种程度上让纹理的边缘看上去具有一定的连续性。
  • 截取(clamp,DirectX中所使用的术语),或者截取到边缘(clamp to edge,OpenGL中所使用的术语)——将范围超出 [ 0 , 1 ] [0,1] [0,1] 的值截取到这个范围。这个操作的效果就是表面上图像纹理的边缘一直在重复。当双线性插值在纹理的边缘附近发生时,这个函数对于避免意外地从纹理的反面边缘采样很有用。
  • 边界(border,DirectX中所使用的术语),或者截取到边界(clamp to border,OpenGL中所使用的术语)——在 [ 0 , 1 ] [0,1] [0,1] 范围以外的纹理坐标会以一个额外定义的边界颜色进行渲染。这个函数在渲染材质贴画到单色表面上时是很有用的,比如纹理边缘就可以很好得与边界颜色进行混合。

参考图6.7.。这些corresponder function在每个纹理轴向上都可以以不同的方式定义,即纹理在在 u u u 轴向上是重复的,而在 v v v 轴向上是以截取的方式渲染。在DirectX中还有一种仅镜像一次模式(mirror once),这种方式具体是沿着纹理坐标的零值做一次镜像,外面的部分采用截取方式,常用在对称贴花上。
在这里插入图片描述
图 6.7. 图像纹理处理,从左到右依次是重复(repeat)函数,镜像(mirror)函数,截取(clamp)函数,以及边界(border)函数。

纹理的重复平铺可以为场景增加更多的视觉上的细节,且消耗并不高。但是,在纹理进行了三次以上的重复过后,这项技术带给人的感觉就不那么可信了,因为此时人眼可以很轻易得识别出这种重复的模式。避免这种周期性(periodicity)问题的一个常见解决方案是将纹理与另一个非平铺的纹理进行结合使用。在Andersson所描述的商业地形渲染系统中这种方法可以得到很大的扩展。在这个系统中,依照地面类型,海拔,坡度以及一些其他因子,多个纹理被结合使用。纹理图像也与几何模型(如灌木和岩石)在场景中的位置相联系(译者注:比如说我可以利用一张纹理来定义哪里是生长更多的草,哪里分布更多的石子儿等等)。

另一种避免periodicity的方式是使用着色器程序来实现特制的 correponder function,从而随机得重新组合纹理图案。王浩瓷砖问题就是这个方法的一个例子。一个王浩瓷砖集是一个由边缘匹配的方形瓷砖组成的小集合。在纹理处理过程中瓷砖被随机得进行选择。Lefebvre和Neyret实现类似的对应函数,他们是使用了依赖的纹理读取和表格,从而规避了模式重复。

最后,应用的correspinder function是隐式的,并且是从图像的大小推导而来的。纹理通常是伴随着在 [ 0 , 1 ] [0,1] [0,1] 范围的 u u u v v v来使用的。再回到我们砖墙的那个例子上,通过令图像的分辨率和这个纹理坐标值相乘,就可以得到某点的像素位置。使用 ( u , v ) (u,v) (u,v) 值的优势就在于不需要改变存储在顶点上的值就可以切换不同分辨率的图像。

6.1.3 Texture Values(纹理值)

在用 corresponder function 得到纹理空间坐标之后,就是获取纹理值的过程。对图像纹理来说,这就是通过访问纹理从而获取到图像上的纹素信息的过程。相关详细内容,参照下个小节。图像纹理处理构成了实时工作中纹理应用的绝大部分情况,但是同时另一种程序化纹理处理的使用也并不罕见。在程序化纹理处理中,获取从纹理空间位置获取纹理值的这个过程不再是一个内存的查找过程,而是相应的变为了一个函数的计算过程。6.3小节中将会讨论更多关于程序化纹理的内容。

最直接的纹理值就是RGB三个值,这也是用来替换或是修改表面颜色的;类似的,也可以返回一个单一的灰度值。另一个可以返回的数据的类型是RGBα,这在5.5小节中也描述过。α(alpha)值通常代表着颜色的不透明度,这也决定着颜色对像素的影响程度。换个思路来说,这里也可以存储任意其他的数据,例如表面粗糙度什么的。还有很多其他的数据类型可以存储在图像纹理中,我们在6.7小节将会讨论的凹凸纹理映射(bump mapping)就是这样的一个典型应用。

从纹理中返回的值是可以在使用前进行变换的。这些变换可以用着色器程序来实现。举一个例子:数据的重映射,从无符号范围 [ 0.0 , 1.0 ] [0.0,1.0] [0.0,1.0] 转换为有符号范围 [ − 1.0 , 1.0 ] [-1.0,1.0] [1.0,1.0],这在绘制存储在颜色纹理里的法线时非常常见。

6.2 Image Texturing(图像纹理处理)

在图像纹理处理中,一个二维图像被高效得贴到由一个或者多个三角形构成的面上。我们已经细致地介绍了计算纹理空间位置地过程;现在我们来看看给定一个位置,从图像纹理中获取纹理值这个过程相关的问题和算法。在本节的后续部分,图像纹理一词(image texture)将会简单地称为 texture(译者注:我们 后文的译制也会直接使用texture,读者需要知道两者是指代同样的东西)。此外,当我们提到像素的晶格(cell)时,我们希望表达的是屏幕上的该像素周围的网格单元。在5.4.1小节中讨论过,像素实际上是一个显示的颜色值,它可以(而且应该,为了提高质量)受到与其连接的多个网格单元的采样的影响。

在这个小节我们着重看一些快速采样和纹理图像的滤波方法。5.4.2小节讨论过反走样的问题,特别是针对物体的边缘的渲染。纹理也会有采样的问题,它们是发生在被渲染的三角形的内部。

像素着色器通过纹理坐标值和一个调用(如texture2D)来对纹理进行访问。这些值是在 ( u , v ) (u,v) (u,v)纹理坐标下,通过一个corresponder function来映射到 [ 0.0 , 1.0 ] [0.0,1.0] [0.0,1.0]。而GPU会负责将这个值转化为纹素坐标。不同的API其纹理坐标系统也会有不同,这主要体现在两方面。在DirectX中,纹理的左上角坐标为 ( 0 , 0 ) (0,0) (0,0),右下角为 ( 1 , 1 ) (1,1) (1,1)。这与许多图像类型存储数据的方式是匹配的,最上面一行是对应着文件中的第一个。在OpenGL里,纹素 ( 0 , 0 ) (0,0) (0,0)位于左下角,即是DirectX的沿着 y y y轴的翻转。纹素有整数坐标,但是大部分时间我们是想去访问纹素之间的位置,得到一个混合过后的结果。这就提出了一个问题——像素中心的浮点坐标是什么。Heckbert讨论了有两种可能的系统:truncating(截取)和rounding(四舍五入)。DirectX 9把每个中心定义到 ( 0.0 , 0.0 ) (0.0,0.0) (0.0,0.0)——这就是rounding的方式。某种程度上这个系统是有些令人费解的,因为位于左上角像素的左上角位置的点,即Direct坐标系统原点,其值为 ( − 0.5 , − 0.5 ) (-0.5,-0.5) (0.5,0.5)。DirectX 10则改进到OpenGL的系统,其中纹素中心的坐标值为 ( 0.5 , 0.5 ) (0.5,0.5) (0.5,0.5)——这就是truncating的方式,或者更准确来说,flooring(舍去小数部分)。这种方式是一种更加自然的系统,也符合语言表述的习惯,例如,我们说像素 ( 5 , 9 ) (5,9) (5,9),即表示 u u u坐标位于 5.0 5.0 5.0 6.0 6.0 6.0之间, v v v坐标位于 9.0 9.0 9.0 10.0 10.0 10.0之间。

在这个点上有一个术语还值得一讲,就是依赖纹理读取(dependent texture read),其包含两个定义。其中第一条特别适用于移动设备。当使用texture2D或者类似的函数去访问一张纹理时,无论何时,只要是像素着色器是去计算纹理坐标而不是使用从顶点着色器获取的无修改的纹理坐标,那么就会发生依赖纹理读取。注意,这里提到的这个纹理坐标的修改指的是对任何输入的纹理坐标的改变,甚至只是简单得讲 u u u v v v交换一下这样的修改也包含在内。旧一些的移动GPU,即那些不支持OpenGL ES 3.0的,当这些显卡运行没有依赖纹理读取的着色器时是更加高效的,因为此时可以预取纹素数据。这个术语的另一个较早的定义对早期的桌面GPU来说特别重要。在这种情况下,当一个纹理的坐标取决于前一个纹理的值的结果时,就会发生依赖性纹理读取。例如,一个纹理可能会去改变着色的法线,这反过来也会去改变用来访问cube map的坐标。在早期的GPU上这样的功能是受限的或者根本不存在。今天这样的读取会极大得影响性能表现,根据一批处理得像素的数量其表现会非常不一样,这在所有影响因素中也是占比最高的。参考23.8小节。

GPU中使用的纹理图像的大小通常是 2 m × 2 n 2^m \times 2^n 2m×2n个纹素,其中 m m m n n n都是非负整数。这些都被称为是二次幂(power-of-two,POT)纹理。现代GPU可以处理任意大小的非二次幂(non-power-of-two,NPOT)纹理,这使得生成的图像可以被当作一个纹理来处理。但是,一些更早的移动GPU可能并不支持NPOT纹理的多级纹理映射(mipmapping,6.2.2小节)。图形加速器在纹理的大小上有不同的上限。例如,DirectX 12最大允许 1638 4 2 16384^2 163842个纹素。

6.3 Procedural Texturing(程序化纹理)

6.4 Texture Animation(纹理动画)

6.5 Material Mapping(材质纹理映射)

6.6 Alpha Mapping(Alpha纹理映射)

6.7 Bump Mapping(凹凸纹理映射)

6.8 Parallax Mapping(视差纹理映射)

6.9 Textured Lights(纹理光)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Claude的羽毛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值