效果文件(管道阶段的集合)在 directX 中有用吗?

is effect file(collection of pipeline stage) useful in directX?

您好,我目前正在关注“使用 directx11 进行 3d 游戏编程”。 我发现这本旧书(大约从 2011 年开始)正在使用 hlsl 代码的效果文件。 对于我的项目,我根本没有使用任何效果文件,只是在其中制作 hlsl 文件和代码。所以我有很多我需要的hlsl文件。

所以我想到了这个问题,使用效果文件进行着色器编码有用吗??? 如果是,那是什么原因???

这是比较效果文件和hlsl文件的示例代码(只是例子)

这是包含VS的效果文件,PS一应俱全

cbuffer cbPerObject 
{ 
 float4x4 gWorldViewProj; 
}; 
struct VertexIn 
{ 
 float3 Pos : POSITION; 
 float4 Color : COLOR; 
}; 
struct VertexOut 
{ 
 float4 PosH : SV_POSITION; 
 float4 Color : COLOR; 
}; 
VertexOut VS(VertexIn vin) 
{ 
 VertexOut vout; 
 vout.PosH = mul(float4(vin.Pos, 1.0f), gWorldViewProj); 
 vout.Color = vin.Color; return vout; 
} 
float4 PS(VertexOut pin) : SV_Target 
{ 
 return pin.Color; 
} 
technique11 ColorTech 
{ 
 pass P0 
 { 
  SetVertexShader( CompileShader( vs_5_0, VS() ) );
  SetPixelShader( CompileShader( ps_5_0, PS() ) ); 
 } 
}

这是我的 VS 2 hlsl 项目,PS 相对

struct VS_INPUT
{
    float3 pos : POSITION;
};
struct VS_OUTPUT
{
    float4 pos : SV_POSITION;
};

VS_OUTPUT main(VS_INPUT input)
{
    VS_OUTPUT output;

    output.pos = float4(input.pos, 1);

    return output;
}
struct PS_INPUT
{
    float4 pos : SV_POSITION;
};

float4 main(PS_INPUT input) : SV_Target
{
    return float4(1,1,1,1);
}

这是 中引用的此问题版本的答案副本。

Q: ...is it best to separate each shader (i.e. Vertex, Geometry, Tessellation, Pixel) in each file? I can’t seem to find a best practice around this. I see some examples that have all shaders in one .hlsl or .fx file and some in each vs.hlsl, ps.hlsl or vs.fx, px.fx files. Thanks!

A: Historically the extension '.fx' refers to a HLSL shader intended to be built using the legacy effects fx_4_0, fx_5_0, etc. profiles; while '.hlsl' refers to individual HLSL shaders. The reality is that there's no consistency here. You will see lots of '.fx' files without any technique/pass statements.

Unlike C/C++ source files, HLSL files can contain a lot of stuff that gets ignored in a given invocation of the compiler. If you have a big .fx file with a dozen shaders in it and a bunch of technique/passes, you can compile the same file many times with different entry-points and profiles to generate lots of shaders.

It's really all a matter of how you want to build your shader content. For example, DirectX Tool Kit uses a command-line script to build all the possible combinations of shaders: currrently it builds 161 shader blobs from 12 .fx files--and actually it can build them twice: once with the Windows compiler and once with the Xbox One XDK compiler, but only one set of these shader blobs is included in a given build of the DirectXTK.lib anyhow. DirectXTK doesn't use legacy Effects 11 at all.

If you use the Visual Studio 2012-2019 content pipeline to build your shaders, you do have to deal with a limitation of MSBuild which assumes each source file is built once for each result. So in that case, you'd want an individual .hlsl file for each shader combination (which for the DirectX Tool Kit example would mean 161 .hlsl files). One way to handle this would be to keep the shader source itself in a single file, and then have a bunch of .hlsl files that #include the 'source' file. Something like:

// BasicEffectVSBasicVertexLighting.hlsl
// 

#include "BasicEffect.fx"
// BasicEffectPSBasicVertexLighting.hlsl
// 

#include "BasicEffect.fx"

You then compile each of these .hlsl files once with the proper shader profile and entry-point. This approach works fine for smaller projects, but doesn't scale well to large complex shaders without using legacy fx profiles. In that case, other build solutions like DirectX Tool Kit's build solution is probably better.

如果您使用的是旧版 fx 配置文件,您当然只需要编译每个 .fx 一次,它将一次性生成它在 technique/passes 中指定的所有着色器。请记住效果 11:

  • Direct3D 11 运行时的最新效果可在 GitHub 上找到。
  • HLSL 编译器中的 fx_5_0 配置文件支持已弃用,并且不完全支持 DirectX 11.1 HLSL 功能,例如最小精度类型。 Windows 8.x/Windows 10 SDK 版本的 HLSL 编译器 (FXC.EXE) 和 D3DCompile API (#46) 支持它。它使用 D3DCompile API (#47) 生成弃用警告。 Shader Model 6 (DXC.EXE) 或更高版本的 DXIL 编译器不支持