编译着色器

注意

本主题介绍 FXC.EXE 用于着色器模型 2 到 5.1 的编译器。 对于着色器模型 6,请改用 DXC.EXE 使用 dxc.exe 和 dxcompiler.dll中所述。 选择“着色器模型 6”进行 HLSL 属性页配置时,Visual Studio 将自动使用 DXC.EXE

Microsoft Visual Studio 可以从 C++ 项目中包含的 *.hlsl 和 *.fx 文件编译着色器代码。

在生成过程中,Visual Studio 使用 fxc.exedxc.exe HLSL 代码编译器将 HLSL 着色器源文件编译为二进制着色器对象文件或头文件中定义的字节数组。 HLSL 代码编译器如何编译项目中每个着色器源文件取决于为该文件指定 Ouput Files 属性的方式。 有关 HLSL 属性页的详细信息,请参阅 HLSL 属性页

使用的编译方法通常取决于 HLSL 着色器源文件的大小。 如果在标头中包含大量字节代码,则会增加应用的大小和初始加载时间。 你还会强制所有字节代码驻留在内存中,即使在创建着色器之后,也会浪费资源。 但是,在标头中包含字节代码时,可以降低代码复杂性并简化着色器的创建。

现在,让我们看一下各种方法来编译着色器代码以及着色器代码文件扩展名的约定。

使用着色器代码文件扩展名

若要符合 Microsoft 约定,请将以下文件扩展名用于着色器代码:

  • 扩展名为 .hlsl 的文件包含高级着色语言 (HLSL) 源代码。 也支持较旧的 .fx 扩展,但通常与 旧版效果系统相关联。
  • 扩展名为 .cso 的文件保留经过编译的着色器对象。
  • 扩展名为 .h 的文件是头文件,但在着色器代码上下文中,此头文件定义保留着色器数据的字节数组。 HLSL 着色器代码标头的其他常见扩展包括 .hlsli 和 .fxh。

在生成时编译为对象文件

如果将 .hlsl 文件编译为二进制着色器对象文件,则应用需要从这些对象文件读取数据, (.cso 是这些对象文件的默认扩展名) ,将数据分配给字节数组,并从这些字节数组创建着色器对象。 例如,若要 (ID3D11VertexShader**) 创建顶点着色器,请使用包含已编译顶点着色器字节代码的字节数组调用 ID3D11Device::CreateVertexShader 方法。 在此示例代码中,SimpleVertexShader.hlsl 文件的 Ouput Files 属性指定编译为 SimpleVertexShader.cso 对象文件。

        auto vertexShaderBytecode = ReadData("SimpleVertexShader.cso");
        ComPtr<ID3D11VertexShader> vertexShader;
        DX::ThrowIfFailed(
            m_d3dDevice->CreateVertexShader(
                vertexShaderBytecode->Data,
                vertexShaderBytecode->Length,
                nullptr,
                &vertexShader
                )

此处的 ReadData 帮助程序将查找当前工作目录,以及与当前进程的 EXE 文件相同的目录,因为 .cso 文件通常与其他 VS 生成产品一起找到。 有关示例实现,请参阅 ReadData.h

在生成时编译到头文件

如果将 .hlsl 文件编译为在头文件中定义的字节数组,则需要在代码中包含这些头文件。 在此示例代码中,PixelShader.hlsl 文件的 Ouput Files 属性指定编译为 PixelShader.h 头文件中定义的 g_psshader 字节数组。

namespace
{
       include "PixelShader.h"
}
...
        ComPtr<ID3D11PixelShader> m_pPixelShader;
        hr = pDevice->CreatePixelShader(g_psshader, sizeof(g_psshader), nullptr, &m_pPixelShader);

使用 D3DCompileFromFile 进行编译

还可以在运行时使用 D3DCompileFromFile 函数编译 Direct3D 11 的着色器代码。 有关如何执行此操作的详细信息,请参阅 如何:编译着色器

注意

Windows 应用商店应用支持使用 D3DCompileFromFile 进行开发,但不支持用于部署。

 

HLSL 编程指南

HLSL 编程指南