在游戏或应用中使用三维资产

本文介绍如何使用 Visual Studio 处理 3D 资产并将其包含在生成中。

使用 Visual Studio 中的工具创建 3D 资产后,下一步是在应用中使用它们。 但是,在使用它们之前,资产必须转换为 DirectX 可以理解的格式。 为了帮助你转换资产,Visual Studio 为它可以生成的每种资产提供生成自定义项。 若要在生成中包含资产,只需将项目配置为使用生成自定义项,将资产添加到项目,并将资产配置为使用正确的生成自定义。 之后,你可以将资产加载到应用中,并通过创建和填充 DirectX 资源来使用这些资源,就像在任何其他 DirectX 应用中一样。

配置您的项目

在将 3D 资产作为构建的一部分进行部署之前,Visual Studio 必须了解您要部署的资产类型。 Visual Studio 已经知道许多常见的文件类型,但由于只有某些类型的应用使用 3D 资产,Visual Studio 不假定项目将生成此类文件。 你可以通过使用为每种资产类型提供的 生成自定义(这些文件告知 Visual Studio 如何以有用的方式处理不同类型的文件),告诉 Visual Studio 你的应用使用这些类型的资产。 由于这些自定义项基于每个项目应用,因此只需向项目添加适当的自定义项。

将生成自定义添加到你的项目

  1. 解决方案资源管理器中,打开项目的快捷菜单,然后选择 生成依赖项>生成自定义项

    随即显示“Visual C++ 生成自定义文件”对话框

  2. 可用的构建自定义文件下,勾选与您希望在项目中使用的资产类型相对应的复选框,如下表所述:

    资产类型 生成自定义名称
    纹理和图像 ImageContentTask(.targets, .props)
    三维模型 MeshContentTask(.targets, .props)
    着色器 ShaderGraphContentTask(.targets, .props)

    备注

    由于 Autodesk FBX SDK 中的安全问题,Visual Studio 2022 17.9.3 删除了对模型编辑器和 MeshContentTask 的支持。 请参阅 CVE-2023-27911

  3. 选择“确定”按钮

将资产包含在生成中

现在,你的项目已了解要使用的不同类型的 3D 资产,下一步是告诉它哪些文件是 3D 资产,以及它们的资产类型。

将资产添加到生成

  1. 解决方案资源管理器中,在项目中打开资产的快捷菜单,然后选择 属性

    随即显示资产的“属性页”对话框

  2. 确保将 配置平台 属性设置为要应用更改的值。

  3. 配置属性下,选择 常规,然后在属性网格中,在 常规下,将 项类型 属性设置为相应的内容管道项类型。 例如,对于图像或纹理文件,请选择 图像内容管道

    重要

    默认情况下,Visual Studio 假定应使用内置于 Visual Studio 中的 图像 项类型对许多类型的图像文件进行分类。 因此,必须更改要由图像内容管道处理的每个图像的 项类型 属性。 3D 模型和视觉着色器图形的其他类型的内容管道源文件默认为正确的 项类型

  4. 选择“确定”按钮

以下是三种内容管道项类型及其关联的源和输出文件类型。

项目类型 源文件类型 输出文件格式
图像内容管道 可移植网络图形(.png

JPEG(.jpg.jpeg.jpe.jfif

直接绘画表面 (.dds)

图形交换格式(.gif

位图(.bmp、.dib)

标记的图像文件格式(.tif.tiff

Targa (.tga)
直接绘画表面 (.dds)
网格内容管道 AutoDesk FBX 交换文件 (.fbx)

Collada DAE 文件 (.dae)

Wavefront OBJ 文件 (.obj
3D 网格文件(.cmo
着色器内容管道 视觉对象着色器图 (.dgsl) 编译着色器输出 (.cso)

配置资产内容管道属性

可以设置每个资产文件的内容管道属性,以便以特定方式生成它。

配置内容管道属性的步骤

  1. 在“解决方案资源管理器”中,在你的项目中打开资产文件的快捷菜单,然后选择“属性”

    随即显示资产的“属性页”对话框

  2. 确保将 配置平台 属性设置为要应用更改的值。

  3. 配置属性下,选择内容管道节点(例如,纹理和图像资产的图像内容管道),然后在属性网格中,将属性设置为相应的值。 例如,若要在生成时为纹理资产生成 mipmap,请将“生成 Mip”属性设置为“是”

  4. 选择“确定”按钮

图像内容管道配置

使用图像内容管道工具生成纹理资产时,可以通过各种方式压缩纹理,指示生成时是否应生成 MIP 级别,并更改输出文件的名称。

财产 描述
压缩 指定用于输出文件的压缩类型。

可用选项包括:

- 无压缩
- BC1_UNORM 压缩
- BC1_UNORM_SRGB 压缩
- BC2_UNORM 压缩
- BC2_UNORM_SRGB 压缩
- BC3_UNORM 压缩
- BC3_UNORM_SRGB 压缩
- BC4_UNORM 压缩
- BC4_SNORM 压缩
- BC5_UNORM 压缩
- BC5_SNORM 压缩
- BC6H_UF16 压缩
- BC6H_SF16 压缩
- BC7_UNORM 压缩
- BC7_UNORM_SRGB 压缩

有关 DirectX 不同版本中支持哪些压缩格式的信息,请参阅 DXGI 编程指南。
转换为预乘 alpha 格式 若要将输出文件中的图像转换为预乘 alpha 格式,则为“是”;否则为“否”。 仅更改输出文件,源图像保持不变。
生成 Mip 若要在生成时生成完整的 MIP 链并将它包含在输出文件中,则为“是”;否则为“否”。 如果 值为“无”,并且源文件已包含 mipmap 链,则输出文件将具有 mipmap 链;否则,输出文件将没有 mipmap 链。
内容输出 指定输出文件的名称。 重要提示: 更改输出文件的文件扩展名不会影响其文件格式。

网格内容管道配置

使用网格内容管道工具生成网格资产时,可以更改输出文件的名称。

财产 描述
内容输出 指定输出文件的名称。 重要提示: 更改输出文件的文件扩展名不会影响其文件格式。

着色器内容管道配置

使用着色器内容管道工具生成着色器资产时,可以更改输出文件的名称。

财产 描述
内容输出 指定输出文件的名称。 重要提示: 更改输出文件的文件扩展名不会影响其文件格式。

在运行时加载和使用三维资产

使用纹理和图像

Direct3D 提供用于创建纹理资源的函数。 在 Direct3D 11 中,D3DX11 实用工具库提供了用于直接从图像文件创建纹理资源和资源视图的其他功能。 有关如何在 Direct3D 11 中创建纹理资源的详细信息,请参阅 纹理。 有关如何使用 D3DX11 库从图像文件创建纹理资源或资源视图的详细信息,请参阅 如何:从文件初始化纹理。

使用 3D 模型

Direct3D 11 不提供用于从 3D 模型创建资源的函数。 相反,必须编写代码来读取 3D 模型文件,并创建表示 3D 模型和模型所需的任何资源的顶点和索引缓冲区,例如纹理或着色器。

使用着色器

Direct3D 提供用于创建着色器资源并将其绑定到可编程图形管道的功能。 有关如何在 Direct3D 中创建着色器资源并将其绑定到管道的详细信息,请参阅 HLSL编程指南。

在可编程图形管道中,管道的每个阶段都必须为管道的下一阶段提供一个采用其理解方式进行格式化的结果。 由于着色器设计器只能创建像素着色器,这意味着你的应用程序负责确保接收的数据是预期的格式。 在像素着色器之前发生几个可编程着色器阶段并执行几何转换-顶点着色器、外壳着色器、域着色器以及几何着色器。 非可编程分割阶段也发生在像素着色器之前。 无论这些阶段中的哪一个阶段直接位于像素着色器之前,它都必须以以下格式提供其结果:

struct PixelShaderInput
{
    float4 pos : SV_POSITION;
    float4 diffuse : COLOR;
    float2 uv : TEXCOORD0;
    float3 worldNorm : TEXCOORD1;
    float3 worldPos : TEXCOORD2;
    float3 toEye : TEXCOORD3;
    float4 tangent : TEXCOORD4;
    float3 normal : TEXCOORD5;
};

根据您在着色器中使用的着色器设计器节点,您可能还需要根据以下定义格式提供其他数据。

Texture2D Texture1 : register( t0 );
Texture2D Texture2 : register( t1 );
Texture2D Texture3 : register( t2 );
Texture2D Texture4 : register( t3 );
Texture2D Texture5 : register( t4 );
Texture2D Texture6 : register( t5 );
Texture2D Texture7 : register( t6 );
Texture2D Texture8 : register( t7 );

TextureCube CubeTexture1 : register( t8 );
TextureCube CubeTexture2 : register( t9 );
TextureCube CubeTexture3 : register( t10 );
TextureCube CubeTexture4 : register( t11 );
TextureCube CubeTexture5 : register( t12 );
TextureCube CubeTexture6 : register( t13 );
TextureCube CubeTexture7 : register( t14 );
TextureCube CubeTexture8 : register( t15 );

SamplerState TexSampler : register( s0 );

cbuffer MaterialVars : register (b0)
{
    float4 MaterialAmbient;
    float4 MaterialDiffuse;
    float4 MaterialSpecular;
    float4 MaterialEmissive;
    float MaterialSpecularPower;
};

cbuffer LightVars : register (b1)
{
    float4 AmbientLight;
    float4 LightColor[4];
    float4 LightAttenuation[4];
    float3 LightDirection[4];
    float LightSpecularIntensity[4];
    uint IsPointLight[4];
    uint ActiveLights;
}

cbuffer ObjectVars : register(b2)
{
    float4x4 LocalToWorld4x4;
    float4x4 LocalToProjected4x4;
    float4x4 WorldToLocal4x4;
    float4x4 WorldToView4x4;
    float4x4 UVTransform4x4;
    float3 EyePosition;
};

cbuffer MiscVars : register(b3)
{
    float ViewportWidth;
    float ViewportHeight;
    float Time;
};
标题 描述
如何:导出包含 mipmap 的纹理 描述如何使用“图像内容管道”导出包含预计算 mipmap 的纹理。
如何:导出包含预乘 alpha 的纹理 介绍如何使用图像内容管道导出包含预乘 alpha 值的纹理。
如何:导出纹理以用于 Direct2D 或 JavaScript 应用 介绍如何使用图像内容管道导出可在 Direct2D 或 JavaScript 应用中使用的纹理。
处理游戏和应用的三维资产 介绍 Visual Studio 提供的用于创建和操作 3D 资产的编辑工具,其中包括纹理和图像、3D 模型和着色器。
如何:导出着色器 介绍如何从着色器设计器导出着色器。