从 XNA 中的文件动态编译和运行着色器

发布于 2024-09-17 07:33:19 字数 299 浏览 5 评论 0原文

我想知道是否可以从文件动态编译像素着色器并将其应用到网格。

首先我将从一些背景信息开始。我有一个系统,它根据一系列数据创建 HLSL 像素着色器,这对问题来说并不重要。重要的是这些着色器不使用技术或通道。因为它们不适合用作 .fx 文件。

ShaderCompiler.CompileFromFile() 方法能够成功将文件编译为 CompiledShader

是否可以将此着色器应用于网格?

因为我不想找到每个文件的入口点以将其包装在允许将其编译为效果的技术中。

im wondering if its possible to dynamically compile a pixel-shader from file and apply it to a mesh.

First I'll just start with some background information. I have a system which creates HLSL pixel-shaders based on a range of data which is not really important to the question. What is important is that these shaders do not use techniques or passes. As they are not meant to be used as .fx files.

The ShaderCompiler.CompileFromFile() method is able to successfully compile the file into a CompiledShader.

Is it possible to apply this shader to a mesh?

As i do not want to locate the entry point for each file to wrap it in a technique to allow for it to be compiled as an Effect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清晰传感 2024-09-24 07:33:20

首先 - 如果你的着色器没有入口点,那么你实际上并没有编译任何东西! HLSL 函数(听起来这就是您正在使用的函数)从入口点开始内联。。如果你没有入口点,那么你得到的就是一个空的着色器。

(您可以通过在编译后反汇编生成的着色器来确认这一点。检查这个问题和答案的说明。)

因此,首先 - 您将必须编写代码来生成技术包装器。粗略地解析源代码并发现函数名称应该不会那么困难。您可以将源代码加载到缓冲区中并附加生成的技术声明。然后使用采用从该缓冲区创建的 StreamShaderCompiler.CompileFromFile 版本。

要在 XNA 3.1 中的显卡上设置此着色器,您可以使用:

CompiledShader cs = ShaderCompiler.CompileFromFile(...);
PixelShader ps = new PixelShader(graphicsDevice, cs.GetShaderCode());
graphicsDevice.PixelShader = ps;

当使用 XNA 的内置网格物体时,您需要使用 ModelMeshPart.Draw 来绘制网格物体。这会绕过所有 Model 的内置 Effect 内容。

值得指出的是,整个 ShaderCompilerCompiledShaderPixelShader 系统在 XNA 4.0 中已从 XNA 中删除。这是 此处解释。 XNA 4.0中动态编译效果的方法是此处描述

(鉴于您必须在 XNA 4.0 中使用 Effect,并且在 XNA 3.1 中 Effect 和使用 PixelShader 之间没有太大区别,我建议您使用 Effect,使用 Effect.CompileEffectFromSource,如果您选择保留 XNA 3.1,而不是使用 ShaderCompiler

First of all - if your shader doesn't have an entry point, you're not actually compiling anything! HLSL functions (it sounds like that is what you are working with) are inlined starting from the entry point. If you have no entry point, then what you've got is an empty shader.

(You could confirm this by disassembling the resulting shader after you compile it. Check this question and answer for instructions.)

So first of all - you are going to have to write code to generate technique wrappers. It shouldn't be that hard to roughly parse your source and discover the function name. You could load the source into a buffer and append a generated technique declaration. Then use the version of ShaderCompiler.CompileFromFile that takes a Stream that you create from that buffer.

To set this shader on the graphics card, in XNA 3.1, you can use:

CompiledShader cs = ShaderCompiler.CompileFromFile(...);
PixelShader ps = new PixelShader(graphicsDevice, cs.GetShaderCode());
graphicsDevice.PixelShader = ps;

When using XNA's built in mesh stuff, you want to use ModelMeshPart.Draw to draw your meshes. This bypasses all of Model's built-in Effect stuff.

It is worth pointing out that the entire ShaderCompiler, CompiledShader, PixelShader system was removed from XNA in XNA 4.0. This is explained here. The way to dynamically compile effects in XNA 4.0 is described here.

(Given that you must use Effect in XNA 4.0, and that there's not really much difference in XNA 3.1 between Effect and using PixelShader, I would recommend you use Effect, compiling with Effect.CompileEffectFromSource, if you choose to stay on XNA 3.1, instead of using ShaderCompiler)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文