我目前正在创建一个使用 Directx 11 的程序。我正在使用用 HLSL 编写的着色器。我有一些特定结构的着色器文件:
global.hlsl
lighting.hlsl
folderA/shader1VS.hlsl
folderA/shader1PS.hlsl
文件 global.hlsl 定义了像 DirectionalLight、PointLight 这样的结构,因为我在该文件中有用于灯光的 cbuffer(使用这些结构)。
File lighting.hlsl 具有照明计算功能,我希望它使用来自 global.hlsl 文件(DirectionalLight 等)的那些结构。所以这个文件包括全局为:
#include "global.hlsl"
文件 shader1PS.hlsl 使用 global.hlsl 和 lighting.hlsl 所以它包括它们为:
#include "../global.hlsl"
#include "../lighting.hlsl"
我在 VS2022 中点击构建解决方案按钮时正在检查着色器是否正确(我认为它使用内置着色器编译器?)。这样-一切都很好。但是要使用这些着色器,我使用 D3DCompileFromFile 函数编译它们。不幸的是,我对 shader1PS.hlsl 文件的那些包含有错误:“无法打开源文件'global.hlsl'.
我认为问题是着色器编译器做了一个非常简单的包含——字面上的复制和粘贴。由于 shader1PS 包含 lighting.hlsl,它将插入 #include "global.hlsl",这是一个不正确的相对路径(从 folderA/shader1PS.hlsl 到 global.hlsl)。
有人知道如何在不更改文件文件夹结构的情况下解决这个问题(我不想将所有着色器文件放在一个文件夹中)吗?
编辑1: 以下是我的代码片段。
编译像素着色器:
DxResPtr<ID3DBlob> pixelShaderBlob, errorBlob;
HRESULT result;
D3D_SHADER_MACRO globalMacros[] = {
// here are some macros
NULL, NULL
};
if (!pixelShaderFilePath.empty())
{
result = D3DCompileFromFile(pixelShaderFilePath.c_str(), globalMacros, D3D_COMPILE_STANDARD_FILE_INCLUDE, "main", "ps_5_0", shaderCompilationFlags, 0, pixelShaderBlob.reset(), errorBlob.reset());
if(FAILED(result))
{
if(errorBlob)
{
OutputDebugStringA((char*)errorBlob->GetBufferPointer());
}
}
result = g_device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, m_pixelShader.reset());
}
还有那 3 个着色器文件:
global.hlsl:
#ifndef __GLOBAL_HLSL__
#define __GLOBAL_HLSL__
// structs, cbuffers, functions
#endif
lighting.hlsl:
#ifndef __LIGHTING_HLSL__
#define __LIGHTING_HLSL__
#include "global.hlsl"
// lighting functions that uses structs from global.hlsl
#endif
shader1PS.hlsl:
#ifndef __SHADER1PS_HLSL__
#define __SHADER1PS_HLSL__
#include "../global.hlsl"
#include "../lighting.hlsl"
// main pixel shader that uses functions from global.hlsl and lighting.hlsl
#endif
首先,如果您将扩展名为
.hlsl
的文件添加到 Visual Studio 项目,它将尝试使用 FXC.EXE 构建它。您应该将包含文件称为 .hlsli
之类的名称。如果您不希望在运行时构建 .hlsl
文件,则需要修改它的 MSBuild 属性,使其“不包含在构建中”。
通常,
#include
语句中的相对路径是不可移植的,所以最好的选择是使用:
#include "global.hlsli"
然后通过
..\
(或 /I
对于 HLSL MSBuild 规则)向编译器提供适当的路径 (AdditionalIncludeDirectories
)。如果你想在运行时进行编译,你必须实现自己的包含处理程序来查看其他路径。