我们有一个目前使用DirectX11 SlimDX的项目,并希望将其移至SharpDX。但是,这个项目使用了SlimDX的Effect框架,我理解在DirectX11中不再支持它。但是我无法找到关于如何转换效果的确切信息。
使用中的效果是相对简单的像素着色器,包含在.fx文件中。
我应该远离.fx文件吗?怎么样?简单的.hlsl文件?或者我应该使用SharpDX工具包吗?这是否使用与.fx文件不同的格式?
我找不到任何关于此的文档。有没有人进行过这种转变,可以给我一些建议,或者有关SharpDX Toolkit效果框架的任何文档?
答案 0 :(得分:4)
迁移到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,Get by name / semantic,所以你需要将cBuffer映射到c#中的结构(你也可以直接使用datastream),并创建Constant缓冲区资源。 / p>
[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时,效果会为您执行此操作)。
此外,由于您单独编译着色器,因此阶段之间不再进行布局验证(效果编译器为您提供:无有效的VertexShader-PixelShader组合......)。因此,您需要小心使用非匹配着色器设置管道(您可以使用反射数据手动验证,或者在Visual Studio中使用调试运行时垃圾邮件显示输出窗口的黑屏)。
所以过渡可能有点乏味,但也可以是有益的,因为它更容易最小化管道状态变化(在我的用例中这不是一个问题,所以效果框架确实很好,但如果你有很多绘制可能变得重要的调用。)