You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用DirectX9为网格应用Bump Map凹凸贴图效果

你目前使用的是DirectX9固定功能管线实现渲染,要在现有基础上添加Bump Map(凹凸贴图,采用常规切线空间法线贴图方案),按以下步骤操作即可:

前置准备

  • 首先为你的网格生成切线空间数据(切线Tangent、副切线Binormal),并更新顶点声明包含这两个分量,固定管线需要这组数据将光照向量转换到切线空间,和法线贴图采样结果做计算。
  • 你用到的Bump Map需要是标准切线空间法线贴图,导入时建议指定格式为D3DFMT_Q8W8V8U8或者D3DFMT_V8U8,适配固定管线的DOTPRODUCT3计算操作。

代码修改步骤

在现有漫反射纹理绑定逻辑之后、高光纹理绑定逻辑之前,插入Bump Map的处理逻辑,完整修改后的代码如下:

std::vector<std::string> tex_keys = {
    mesh + "_Diffuse",
    mesh + "_Ambient",
    mesh + "_Specular",
    mesh + "_Dissolve",
    mesh + "_Bump",
    mesh + "_Sharpness"
};
auto device = GetDevice();
// Diffuse Map _ Base Texture
if (TextureMap[tex_keys[0]])
{
    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_COLOROP, D3DTOP_MODULATE);
    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_COLORARG1, D3DTA_TEXTURE);
    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_COLORARG2, D3DTA_DIFFUSE);

    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
    device->SetTextureStageState(TextureMap[tex_keys[0]]->GetSlot(), D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
    TextureMap[tex_keys[0]]->Bind();
}

// ========== 新增Bump Map处理逻辑 开始 ==========
if (TextureMap[tex_keys[4]])
{
    UINT bumpSlot = TextureMap[tex_keys[4]]->GetSlot();
    // 第一步:用法线贴图采样值和切线空间光照向量做点积,得到凹凸光照系数
    device->SetTextureStageState(bumpSlot, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
    device->SetTextureStageState(bumpSlot, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    device->SetTextureStageState(bumpSlot, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    // 第二步:将凹凸光照系数和前一阶段的漫反射结果相乘,得到带凹凸效果的漫反射颜色
    device->SetTextureStageState(bumpSlot, D3DTSS_COLORARG0, D3DTA_CURRENT);
    device->SetTextureStageState(bumpSlot, D3DTSS_COLOROP, D3DTOP_MODULATE);
    device->SetTextureStageState(bumpSlot, D3DTSS_COLORARG1, D3DTA_ARG0);
    device->SetTextureStageState(bumpSlot, D3DTSS_COLORARG2, D3DTA_ARG1);
    
    // 绑定Bump纹理
    TextureMap[tex_keys[4]]->Bind();
}
// ========== 新增Bump Map处理逻辑 结束 ==========

// Specular Map
if (TextureMap[tex_keys[2]])
{
    device->SetTextureStageState(TextureMap[tex_keys[2]]->GetSlot(), D3DTSS_COLOROP, D3DTOP_ADD);
    device->SetTextureStageState(TextureMap[tex_keys[2]]->GetSlot(), D3DTSS_COLORARG1, D3DTA_TEXTURE);
    device->SetTextureStageState(TextureMap[tex_keys[2]]->GetSlot(), D3DTSS_COLORARG2, D3DTA_CURRENT);
    TextureMap[tex_keys[2]]->Bind();
}

额外配置说明

  • 需要提前开启设备的光照渲染状态:device->SetRenderState(D3DRS_LIGHTING, TRUE);,同时保证场景中配置了至少一盏可用的平行光。
  • 如果凹凸效果不明显,可以调整法线贴图的对比度,或者在纹理阶段配置时添加额外的缩放参数放大凹凸系数。
  • 后续如果改用可编程管线(HLSL着色器)实现,逻辑会更灵活,不需要依赖固定管线的DOTPRODUCT3操作,可以直接在像素着色器中完成切线空间光照计算,实现更多自定义效果。

内容的提问来源于stack exchange,提问作者sparkskapil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:15:02