使用凹凸映射 (Direct3D 9)

检测对凹凸映射的支持

如果设备支持D3DTOP_BUMPENVMAP或D3DTOP_BUMPENVMAPLUMINANCE纹理混合操作,则可以执行凹凸映射。 将 IDirect3D9::CheckDeviceFormat 与 D3DUSAGE_QUERY_LEGACYBUMPMAP 配合使用,以查看凹凸映射是否支持某个格式。

此外,应用程序应检查设备功能,以确保设备支持适当数量的混合阶段(通常至少三个),并至少公开一种凹凸映射像素格式。

下面的代码示例使用给定的条件检查设备功能,以检测当前设备中对凹凸映射的支持。

BOOL SupportsBumpMapping()
{
    D3DCAPS9 d3dCaps;

    d3dDevice->GetDeviceCaps( &d3dCaps );

    // Does this device support the two bump mapping blend operations?
    if ( 0 == d3dCaps.TextureOpCaps & ( D3DTEXOPCAPS_BUMPENVMAP |
                                            D3DTEXOPCAPS_BUMPENVMAPLUMINANCE ))
        return FALSE;

    // Does this device support up to three blending stages?
    if( d3dCaps.MaxTextureBlendStages < 3 )
        return FALSE;

    return TRUE;
}

创建凹凸贴图纹理

可以像创建任何其他纹理一样创建凹凸贴图纹理。 应用程序验证对凹凸映射的支持,并检索有效的像素格式,如检测凹凸映射支持中所述。

创建图面后,如果图面格式包含亮度,则可以使用相应的增量值和亮度加载每个像素。 每个像素组件的值在 凹凸贴图像素格式 (Direct3D 9) 中介绍。

配置凹凸映射参数

当应用程序已创建凹凸贴图并设置每个像素的内容时,可以通过配置凹凸映射参数来准备呈现。 凹凸映射参数包括设置所需的纹理及其混合操作,以及凹凸贴图本身的转换和亮度控件。

  1. 将基础纹理贴图(如果使用)、凹凸贴图和环境贴图纹理设置为纹理混合阶段。
  2. 为每个纹理阶段设置颜色和 alpha 混合操作。
  3. 设置凹凸贴图转换矩阵。
  4. 根据需要设置亮度刻度和偏移值。

下面的代码示例设置三个纹理 (基础纹理贴图、凹凸贴图和反射环境贴图) 到适当的纹理混合阶段。

// Set the three textures.
d3dDevice->SetTexture( 0, d3dBaseTexture );
d3dDevice->SetTexture( 1, d3dBumpMap );
d3dDevice->SetTexture( 2, d3dEnvMap );

将纹理设置为其混合阶段后,以下代码示例准备每个阶段的混合操作和参数。

// Set the color operations and arguments to prepare for
//   bump mapping.

// Stage 0: The base texture
d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); 
d3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );

// Stage 1: The bump map - Use luminance for this example.
d3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
d3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );

// Stage 2: A specular environment map
d3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 0 );
d3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_ADD );
d3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );

设置混合操作和参数时,下面的代码示例通过将 D3DTEXTURESTAGESTATETYPE 的 D3DTSS_BUMPENVMAPMAT00 和 D3DTSS_BUMPENVMAPMAT11 成员设置为 1.0,将 2x2 凹凸映射矩阵设置为标识矩阵。 将矩阵设置为标识会导致系统使用未修改的凹凸映射中的增量值,但这不是必需的。

// Set the bump mapping matrix.
//
// Note  These calls rely on the following inline shortcut function:
//   inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT00, F2DW(1.0f) );
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT01, F2DW(0.0f) );
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT10, F2DW(0.0f) );
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT11, F2DW(1.0f) );

如果将凹凸映射操作设置为包括亮度 (D3DTOP_BUMPENVMAPLUMINANCE) ,则必须设置亮度控件。 亮度控件配置系统在下一阶段调理纹理颜色之前如何计算亮度。 有关详细信息,请参阅 凹凸映射公式 (Direct3D 9)

// Set luminance controls. This is only needed when using
// a bump map that contains luminance, and when the 
// D3DTOP_BUMPENVMAPLUMINANCE texture blending operation is
// being used.
//
// Note  These calls rely on the following inline shortcut function:
//   inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVLSCALE, F2DW(0.5f) );
d3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f) );

应用程序配置凹凸映射参数后,它可以正常呈现,呈现的多边形将接收凹凸映射效果。

请注意,前面的示例演示了为反射环境映射设置的参数。 执行漫射光映射时,应用程序将最后一个阶段的纹理混合操作设置为D3DTOP_MODULATE。 有关详细信息,请参阅 Direct3D 9) (漫射光映射

凹凸贴图