📄 纹理 (textures).htm
字号:
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 2"><B><SPAN
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">将<SPAN
lang=EN-US>Texel映射到屏幕空间<o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">Microsoft®
Direct3D®直接把纹理中的texel映射到屏幕空间,这样就省略了中间步骤并极大地提高了效率。这个映射的过程实际上是一个反向映射,也就是说,系统根据每个像素在屏幕空间中的位置计算该像素在纹理空间中相应的texel的位置,然后对位于该点或该点附近的纹理颜色进行取样。取样的过程被称为纹理过滤。更多信息请参阅<U>纹理过滤</U>。<o:p></o:p></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">纹理中每个<SPAN
lang=EN-US>texel的位置可以用它的texel坐标表示。但是为了把texel贴到图元表面,Direct3D需要所有的纹理中的texel具有相同的地址范围,所以Direct3D使用了一种通用的寻址方法。在这种寻址方法中,所有texel的地址都在闭区间0.0到1.0内。Direct3D用u,v值表示纹理坐标,这和用x,y坐标表示二维笛卡尔坐标系非常相似。从技术上讲,系统事实上可以处理0.0到1.0范围外的纹理坐标,系统根据应用程序设置的纹理寻址模式来进行此类处理。更多信息,请参阅<U>纹理寻址模式</U>。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">采用这种方法的结果是相同的纹理地址在不同的纹理中会映射到不同的<SPAN
lang=EN-US>texel坐标。在下图中,正在使用的纹理地址是(0.5,1.0)。但是,因为纹理的大小不同,所以该纹理地址映射到不同的texel。左边纹理的大小为5x5,纹理地址(0.5,1.0)映射到texel
(2,4)。右边纹理的大小为7x7,纹理地址(0.5,1.0)映射到texel (3,6)。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><!--[if gte vml 1]><v:shape
id=_x0000_i1141 style="WIDTH: 359.25pt; HEIGHT: 223.5pt" type = "#_x0000_t75"
coordsize = "21600,21600"><v:imagedata o:title="texadr1" src =
"Textures_files/image005.gif"></v:imagedata></v:shape><![endif]--><![if !vml]><img border=0 width=479 height=298
src="Textures_files/image005.gif" v:shapes="_x0000_i1141"><![endif]><o:p></o:p></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">下图描述了一个经简化的<SPAN
lang=EN-US>texel映射过程。这个示例显然非常简单,要了解更多细节信息,请参阅<U><A
href="http://www.gesoftfactory.com/developer/Textures.htm#直接把Texel映射到像素">直接把Texel映射到像素</A></U>。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><!--[if gte vml 1]><v:shape
id=_x0000_i1142 style="WIDTH: 360.75pt; HEIGHT: 253.5pt" type = "#_x0000_t75"
coordsize = "21600,21600"><v:imagedata o:title="texadr2" src =
"Textures_files/image006.gif"></v:imagedata></v:shape><![endif]--><![if !vml]><img border=0 width=481 height=338
src="Textures_files/image006.gif" v:shapes="_x0000_i1142"><![endif]><o:p></o:p></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">本例中,图的左边显示了一个被理想化为正方形色块的像素。像素四角的地址被映射到对象空间中的三维图元,因为三维场景中图元的形状及观察角度的不同,像素的形状常常会被扭曲。像素四角所对应图元表面的区域然后被映射到纹理空间,这个映射过程会再次扭曲像素的形状。像素的最终颜色根据像素映射的区域所覆盖的<SPAN
lang=EN-US>texel计算得到。通过设置纹理过滤方法,应用程序可以控制让Direct3D使用何种方法计算像素颜色。更多信息,请参阅<B
style="mso-bidi-font-weight: normal">纹理过滤</B>。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">应用程序可以直接给顶点指定纹理坐标,这使应用程序可以控制把纹理的哪些部分贴到图元上。例如,设想应用程序创建了一个与下面的纹理大小完全相同的图元,本例中,如果应用程序希望把整张纹理贴到整面墙上,那么应用程序给图元的顶点指定的纹理坐标就应该是<SPAN
lang=EN-US>(0.0,0.0), (1.0,0.0), (1.0,1.0), 和
(0.0,1.0)。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><!--[if gte vml 1]><v:shape
id=_x0000_i1129 style="WIDTH: 260.25pt; HEIGHT: 232.5pt" type = "#_x0000_t75"
coordsize = "21600,21600"><v:imagedata o:title="texadr3" src =
"Textures_files/image007.gif"></v:imagedata></v:shape><![endif]--><![if !vml]><img border=0 width=347 height=310
src="Textures_files/image007.gif" v:shapes="_x0000_i1129"><![endif]><o:p></o:p></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">如果应用程序决定把墙的高度减半,应用程序仍可以把整张贴图贴到稍小的墙上,但这会挤压纹理并使之扭曲,或者应用程序也可以重新指定纹理坐标,使<SPAN
lang=EN-US>Direct3D使用纹理的下半部分。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">如果应用程序为了把纹理贴到稍小的墙上而决定挤压或拉伸纹理,那么应用程序使用的纹理过滤方法会影响最终图像的质量。更多信息,请参阅<B
style="mso-bidi-font-weight: normal">纹理过滤</B>。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">如果应用程序决定重新指定纹理坐标并使<SPAN
lang=EN-US>Direct3D使用纹理的下半部分,那么在本例中应用程序给图元的顶点指定的纹理坐标应该是(0.0,0.5), (1.0,0.5),
(1.0,1.0), 和 (0.0,1.0),这样Direct3D就会把纹理的下半部分贴到墙上。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">顶点的纹理坐标有可能大于<SPAN
lang=EN-US>1.0,如果应用程序给顶点指定的纹理坐标不在闭区间0.0到1.0范围内,那么应用程序还应该设置纹理寻址模式。更多信息,请参阅<B
style="mso-bidi-font-weight: normal">纹理寻址模式</B>。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 2"><B><SPAN
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">纹理坐标和纹理层<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">纹理坐标通过纹理层与纹理联系在一起。纹理通过<SPAN
lang=EN-US>SetTexture(stageIndex, pTextre)
被设定到某一纹理层。请参阅<U>IDirect3DDevice9::SetTexture</U>。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">一个弹性顶点格式码最多可以定义八组纹理坐标,纹理坐标数据由用户在顶点数据中提供,数据通过索引值<SPAN
lang=EN-US>0到7来引用。最多可以有八个纹理混合层,一张纹理通过SetTexture(stageIndex,
pTexture)与某一纹理层联系在一起。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">完成以上操作后,任意一组纹理坐标可以被任意一纹理层使用。每一组纹理坐标通过<SPAN
lang=EN-US>SetTextureStageState(stageIndex, D3DTSS_TEXCOORDINDEX,
textureCoordinateIndex)与某一纹理层联系在一起。请参阅<U>IDirect3DDevice9::SetTextureStageState</U>。通过这种方法,可以设置纹理混合层使它们使用任意一张纹理和任意一组纹理坐标。多个纹理层可以使用同一张纹理,或同一组纹理坐标。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">以下主题包含了更多的信息。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<UL type=disc>
<LI class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l6 level1 lfo7"><U><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体; mso-bidi-font-weight: bold"><A
href="http://www.gesoftfactory.com/developer/Textures.htm#直接把Texel映射到像素">直接把Texel映射到像素</A><o:p></o:p></SPAN></U>
<LI class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l6 level1 lfo7"><U><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><A
href="http://www.gesoftfactory.com/developer/Textures.htm#纹理坐标的格式">纹理坐标的格式</A></SPAN></U><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN>
<LI class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l6 level1 lfo7"><U><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><A
href="http://www.gesoftfactory.com/developer/Textures.htm#纹理坐标的处理">纹理坐标的处理</A></SPAN></U><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN>
</LI></UL>
<DIV class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">
<HR align=center width="100%" SIZE=1>
</SPAN></DIV>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 1"><A
name=直接把Texel映射到像素><B><SPAN
style="FONT-SIZE: 24pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体; mso-font-kerning: 18.0pt">直接把<SPAN
lang=EN-US>Texel映射到像素<o:p></o:p></SPAN></SPAN></B></A></P><SPAN
style="mso-bookmark: 直接把Texel映射到像素"></SPAN>
<DIV class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">
<HR align=center width="100%" SIZE=1>
</SPAN></DIV>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">应用程序经常需要把纹理贴到几何体上并使<SPAN
lang=EN-US>texel直接映射到屏幕上的像素。例如,以一个需要在纹理中显示文本的应用程序为例,为了使纹理中的文本能清晰地显示,应用程序需要以某种方式确保映射到几何体上的texel不受纹理过滤的影响。如果无法保证这一点,那么得到的图像通常会是模糊的,如果纹理过滤方法为最近点取样,那么可能会产生粗糙边缘。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">为了统一像素和纹理取样,并同时支持图像和纹理过滤,<SPAN
lang=EN-US>Microsoft®
Direct3D®的像素和纹理取样规则经过了精心定义,但这也使得把纹理中的texel直接映射到屏幕上的像素成为一个相当有意义却又艰难的挑战。要战胜这个挑战,需要透彻地理解Direct3D如何把用浮点数表示的纹理坐标映射到光栅化器使用的整数像素坐标。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">为了把用浮点数表示的纹理坐标映射到<SPAN
lang=EN-US>texel地址,Direct3D执行下面的计算。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体"><!--[if gte vml 1]><v:shape
id=_x0000_i1143 style="WIDTH: 91.5pt; HEIGHT: 36pt" type = "#_x0000_t75"
coordsize = "21600,21600"><v:imagedata o:title="texcoord_to_texel" src =
"Textures_files/image008.gif"></v:imagedata></v:shape><![endif]--><![if !vml]><img border=0 width=122 height=48
src="Textures_files/image008.gif" v:shapes="_x0000_i1143"><![endif]><o:p></o:p></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">在这些公式中,<I><SPAN
lang=EN-US>T</SPAN></I><SUB><SPAN lang=EN-US>x</SPAN></SUB>和<I><SPAN
lang=EN-US>T</SPAN></I><SUB><SPAN lang=EN-US>y</SPAN></SUB>为水平<SPAN
lang=EN-US>/垂直方向的输出texel坐标,<I>u</I><SPAN
style="mso-bidi-font-style: italic">和<I>v</I></SPAN>为顶点提供的水平/垂直方向的纹理坐标。<I>M</I><SUB>x</SUB>和<I>M</I><SUB>y</SUB>元素表示当前mipmap级水平/垂直方向的texel的数量。本节剩余部分将主要讨论在水平方向上从texel到像素的映射,垂直方向上的映射与水平方向完全相同。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN
style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-family: 宋体">把纹理坐标<SPAN
lang=EN-US>0.0和1.0代入以上公式,会使纹理坐标0.0映射到本次纹理迭代的第一个texel和上次纹理迭代的最后一个texel的中间,纹理坐标1.0会被映射到本次纹理迭代的最后一个texel和下次纹理迭代的第一个texel的中间。对于一个宽度为4的迭代纹理,在mipmap的第0级,下图显示了系统把坐标0.0和1.0映射到哪里。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"><SPAN lang=EN-US
style="FONT-FAMILY: 宋体; mso-farea
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -