三次环境映射 (Direct3D 9)

立方体环境贴图(有时称为多维数据集贴图)是包含图像数据的纹理,表示对象周围的场景,就像对象位于多维数据集的中心一样。 立方体环境地图的每个面在水平和垂直方向上覆盖一个 90 度的视野,每个立方体地图有 6 个面。 人脸的方向如下图所示。

中心坐标轴垂直于立方体面的立方体图示

立方体的每个面都垂直于世界空间中的 x/y、y/z 或 x/z 平面。 下图显示了每个平面如何对应于人脸。

具有平面坐标投影的多维数据集面的插图

三次环境贴图作为一系列纹理对象实现。 应用程序可以使用静态图像进行立方环境映射,也可以呈现到多维数据集映射的面中以执行动态环境映射。 此方法要求多维数据集映射图面是有效的呈现目标图面,使用D3DUSAGE_RENDERTARGET标志集创建。

立方体地图的面不需要包含周围场景的极其详细的渲染。 在大多数情况下,环境贴图应用于曲线图。 鉴于大多数应用程序使用的曲率量,由此产生的反射失真会使环境地图中的极端细节在内存和呈现开销方面浪费。

Mipmapped Cubic 环境映射

可以 mipm 应用多维数据集映射。 若要创建 mipmapped 多维数据集映射,请将 CreateCubeTexture 方法的 Levels 参数设置为所需的级别数。 可以设想这些表面的地形,如下图所示。

具有 n mip 级别的 mipmapped 多维数据集映射的示意图

创建 mipmapped 立方环境映射的应用程序可以通过调用 GetCubeMapSurface 方法访问每个人脸。 首先从 D3DCUBEMAP_FACES 枚举类型设置适当的值,如 创建立方环境映射图面 (Direct3D 9) 中所述。 接下来,通过将 GetCubeMapSurface 级别参数设置为所需的 mipmap 级别来选择要检索的级别。 请记住,0 对应于顶级图像。

立方环境贴图的纹理坐标

为三方环境贴图编制索引的纹理坐标不是简单的 u、v 样式坐标,就像应用标准纹理时那样。 事实上,立方环境贴图根本不使用纹理坐标。 为了代替一组纹理坐标,立方环境贴图需要一个 3D 矢量。 必须注意指定正确的顶点格式。 除了告诉系统应用程序使用多少组纹理坐标外,还必须提供有关每个集中有多少个元素的信息。 Direct3D 为此提供 D3DFVF_TEXCOORDSIZEN 组宏。 这些宏接受单个参数,用于标识要描述其大小的纹理坐标集的索引。 对于 3D 向量,请包含由D3DFVF_TEXCOORDSIZE3宏创建的位模式。 下面的代码示例演示如何使用此宏。

// Create a flexible vertex format descriptor for a vertex that contains
//   a position, normal, and one set of 3D texture coordinates.

DWORD dwFVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0); 

在某些情况下,例如漫射光映射,对矢量使用相机空间顶点法线。 在其他情况下(如反射环境映射)使用反射向量。 由于转换的顶点法线被广泛理解,因此此处的信息集中在计算反射向量上。

自行计算反射向量需要了解每个顶点的位置,以及从视点到该顶点的向量的位置。 Direct3D 可以自动计算几何图形的反射矢量。 使用此功能可节省内存,因为不需要包括环境映射的纹理坐标。 它还会减少带宽,并且对于 T&L HAL 设备,它可以明显快于应用程序可以自行完成的计算。 若要使用此功能,请在包含三次环境贴图的纹理阶段中,将D3DTSS_TEXCOORDINDEX纹理阶段状态设置为 D3DTEXTURESTAGESTATETYPE 的 D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 成员和纹理坐标集索引的组合。 在某些情况下,例如漫射光映射,可以使用 D3DTEXTURESTAGESTATETYPE 的 D3DTSS_TCI_CAMERASPACENORMAL 成员,这会导致系统使用转换后的相机空间、顶点法线作为纹理的寻址向量。 索引仅由系统用于确定纹理的包装模式。

下面的代码示例演示如何使用此值。

// The m_d3dDevice variable is a valid pointer
// to an IDirect3DDevice9 interface.

// Automatically generate texture coordinates for stage 2.
// This assumes that stage 2 is assigned a cube map.
// Use the wrap mode from the texture coordinate set at index 1.

m_d3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX,
                                   D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR | 1); 

启用自动纹理坐标生成时,系统会使用两个公式之一来计算每个顶点的反射矢量。 当D3DRS_LOCALVIEWER呈现状态设置为 TRUE 时,将使用以下公式。

反射矢量的公式 (r = 2 (exn) n-e)

在前面的公式中,R 是正在计算的反射矢量,E 是规范化的位置到眼睛向量,N 是相机空间顶点法线。

当D3DRS_LOCALVIEWER呈现状态设置为 FALSE 时,系统会使用以下公式。

反射矢量的公式 (r = 2nzn-i)

此公式中的 R 和 N 元素与上一个公式相同。 NZ 元素是顶点法线的世界空间 z,I 是无限远视点 (0,0,1) 的向量。 系统使用任一公式中的反射矢量来选择和处理多维数据集贴图的相应面。

注意

在大多数情况下,应用程序应启用顶点法线的自动规范化。 为此,请将D3DRS_NORMALIZENORMALS设置为 TRUE。 如果未启用此呈现状态,则环境映射的外观将大大不同于预期。

 

其他信息包含在以下主题中。

环境映射