views:

56

answers:

1

Hello, 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.

+3  A: 

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)

Andrew Russell
Firstand foremost, THANK YOU. And I think it'll be easier all round to use XNA 4.0. I was under the mistaken impression that the "function name" parameter on the ShaderCompiler.CompileFromFile() method was to specify an entry point method for the Shader.Thanks again!
Val
You're welcome :)
Andrew Russell
+1, for linking excellent Shawn Hargreaves WebLog :)
Stringer Bell