我想知道是否可以从文件动态编译像素着色器并将其应用到网格。
首先我将从一些背景信息开始。我有一个系统,它根据一系列数据创建 HLSL 像素着色器,这对问题来说并不重要。重要的是这些着色器不使用技术或通道。因为它们不适合用作 .fx 文件。
ShaderCompiler.CompileFromFile()
方法能够成功将文件编译成CompiledShader
。
是否可以将此着色器应用于网格?
因为我不想找到每个文件的入口点以将其包装在一种技术中以允许将其编译为
Effect
。
首先 - 如果你的着色器没有入口点,那么你实际上并没有编译任何东西! HLSL 函数(听起来这就是您正在使用的函数)是内联的从入口点开始。如果你没有入口点,那么你得到的就是一个空的着色器。
(您可以通过在编译后反汇编生成的着色器来确认这一点。检查此问题并回答说明。)
所以首先 - 您将必须编写代码来生成技术包装器。粗略地解析源代码并发现函数名称应该不那么困难。您可以将源加载到缓冲区中并附加生成的技术声明。然后使用 ShaderCompiler.CompileFromFile
的版本,该版本采用您从该缓冲区创建的
Stream
。要在显卡上设置此着色器,在 XNA 3.1 中,可以使用:
CompiledShader cs = ShaderCompiler.CompileFromFile(...);
PixelShader ps = new PixelShader(graphicsDevice, cs.GetShaderCode());
graphicsDevice.PixelShader = ps;
当使用 XNA 内置的网格物体时,您需要使用
ModelMeshPart.Draw
来绘制网格物体。这会绕过所有
Model
的内置效果。值得指出的是,整个
ShaderCompiler
、
CompiledShader
、PixelShader
系统在 XNA 4.0 中已从 XNA 中删除。这在这里解释。在 XNA 4.0 中动态编译效果的方法是描述在这里。 (鉴于您必须在 XNA 4.0 中使用 Effect,并且在 XNA 3.1 中 Effect 和使用 PixelShader 之间没有太大区别,如果您选择留在 XNA,我建议您使用 Effect,使用
Effect.CompileEffectFromSource
进行编译3.1,而不是使用
ShaderCompiler
)