【问题标题】:Moving from SlimDX to SharpDX - Effects从 SlimDX 迁移到 SharpDX - 效果
【发布时间】:2014-06-12 13:18:47
【问题描述】:

我们有一个项目目前使用 DirectX11 SlimDX,并希望将其移至 SharpDX。但是,这个项目使用了 SlimDX 的 Effect 框架,据我了解,DirectX11 不再正确支持它。但是,我找不到关于如何转换效果的确切信息。

使用的效果是相对简单的像素着色器,包含在 .fx 文件中。

我应该远离 .fx 文件吗?要做什么?到普通的 .hlsl 文件?还是我应该使用 SharpDX 工具包?这是否使用与 .fx 文件不同的格式?

我找不到任何关于此的文档。有没有做过这种转变的人可以给我一些建议,或者任何关于 SharpDX Toolkit 效果框架的文档?

【问题讨论】:

  • 我建议使用普通的 hlsl 文件,因为这也是 DirectX 11 选择的方向。不再支持 fx
  • @thumbmunkeys:感谢您的回复。你能给我指出任何告诉我如何做到这一点的文档吗?
  • 为什么需要迁移到 SharpDX?只要 Direct3D11 在机器上运行,您的代码就可以运行,即使效果不再更新
  • @xoofx:主要是因为我们担心依赖一个不再维护的库。
  • @xoofx:还有:我想知道怎么做!

标签: c# .net slimdx sharpdx


【解决方案1】:

迁移到 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 中使用调试运行时向您的输出窗口发送垃圾邮件时观看黑屏)。

所以转换可能有点乏味,但也可能是有益的,因为它更容易最小化管道状态更改(在我的用例中,这不是问题,所以效果框架就可以了,但如果你有大量可能变得重要的绘制调用)。

【讨论】:

  • 谢谢!这正是我想要的!
  • 我的VertexShader shader = new VertexShader(device, result.Bytecode); -> result.Bytecode 不返回Byte[],它返回DataStream。所以我不能将它用作VertexShader 构造函数的参数。有什么想法吗?
  • @JeroenvanLangen 哪个版本的 SharpDX?刚刚检查了 3,它通过了一个字节 []。它还有一个隐式转换器,所以 new VertexShader(device, result);也应该立即工作
  • @catflier 感谢您的反应。看到你给出的许多反应很有用。对我来说,我通过引用另一个 sharpdx 程序集来解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
相关资源
最近更新 更多