迁移到 SharpDX 非常简单,在命名和资源描述方面有一些变化,但除了相对繁琐(取决于代码库的大小)之外,没有什么太复杂的地方。
关于效果框架,你有包装它的库 SharpDX.Direct3D11.Effects,所以你当然支持它。
它与 SlimDX 对应物几乎相同,因此您应该不会有任何重大问题。
如果你想从 fx 框架过渡到更普通的 hlsl,你可以保持相同的 fx 文件,编译步骤会改变,而不是编译整个文件你需要单独编译每个着色器。
例如,编译和创建一个 VertexShader:
CompilationResult result = ShaderBytecode.Compile(content, "VS", "vs_5_0", flags, EffectFlags.None, null, null);
VertexShader shader = new VertexShader(device, result.Bytecode);
您还需要注意所有常量缓冲区/资源寄存器,通常最好明确设置它们,例如:
cbuffer cbData : register(b0)
{
float4x4 tW;
float4x4 tColor;
float4 cAmb;
};
您当然不再拥有所有的 EffectVariable,通过名称/语义获取,因此您需要将 cBuffer 映射到 c# 中的结构(您也可以直接使用数据流),并创建常量缓冲区资源。
[StructLayout(LayoutKind.Sequential,Pack=16)]
public struct cbData
{
public Matrix tW;
public Matrix tColor;
public Vector4 cAmb;
}
BufferDescription bd = new BufferDescription()
{
BindFlags = BindFlags.ConstantBuffer,
CpuAccessFlags = CpuAccessFlags.Write,
OptionFlags = ResourceOptionFlags.None,
SizeInBytes = 144, //Matches the struct
Usage = ResourceUsage.Dynamic
};
var cbuffer = new SharpDX.Direct3D11.Buffer(device, bd);
使用 UpdateSubResource 或 MapSubresource 更新数据,使用 deviceContext.VertexShader.SetConstantBuffer 绑定到管道。
如果您需要使用反射检查着色器,可以通过这种方式完成(请注意,效果框架实际上是这样做的,它只是 d3dcompiler 之上的一层):
ShaderReflection refl = new ShaderReflection(result.Bytecode);
然后您需要手动设置所有 API 调用(当您调用 EffectPass.Apply 时,Effects 会为您执行此操作)。
此外,由于您单独编译着色器,因此阶段之间不再有布局验证(效果编译器为您提供:没有有效的 VertexShader-PixelShader 组合....)。因此,您需要小心地使用不匹配的着色器设置管道(您可以使用反射数据手动验证,或者在 Visual Studio 中使用调试运行时向您的输出窗口发送垃圾邮件时观看黑屏)。
所以转换可能有点乏味,但也可能是有益的,因为它更容易最小化管道状态更改(在我的用例中,这不是问题,所以效果框架就可以了,但如果你有大量可能变得重要的绘制调用)。