In the WPF and Silverlight “desktop” worlds we have the luxury of being able to use shader effects (fx) in our apps, this infrastructure is not available in the “Windows Phone” or “WinRT XAML/C#” worlds.
However thanks to SharpDx and the improved hlsl graphics features in VS11 we can now easily use these same fx effects. Let me show you how I consume fx files in my XAML/C# WinRT apps…
FX to CSO (HLSL)
Our goal is to turn the FX file into something we can use, and if you’ve followed my previous posts the best option we have in DX11.1 world is a custom shader (cso) and thanks to SharpDx we can do that … So lets try to turn this fx file into a cso
Now the HLSL editor and the compile shader features in Visual Studio 11 shader works only in a DirectX/Cx project.
So first step is to create a DirectX/Cx project to host our FX files. In my case I created a Direct3D Application called “D3DFXConverter”
Then copy across the fx files you want to convert into this new project, in my example I’m going to convert a “Pixelate.fx” . I took this fx file from the “wpf pixel shaders libarary” project on codeplex.
Now rename the “fx” extension to “hlsl”
We now get all the editor experience of an hlsl file for our fx file.
What we want to do is try to compile this as a pixelshader, so go to the compiler setting and set the “Shader Model” to “Shader Model 4 Level 9_1 (/4_0_level_9_1)” and “Shader Type” to “Pixel Shader (/ps)” . note that the fx file in WPF is a shader model 2 or 3.
Now if we try to compile the D2DFXConverter you’ll notice some errors
What these errors mean is that the hlsl code is not compliant with the shader model we’ve chosen, we need to make some minor alterations to the hlsl ..
The changes are very minor, I’ve actually converted several fx shaders and in ALL cases the following is all I needed to change
1. Wrap constants inside a cbuffer
2. Alter the Sampler Input
3. Alter the interface of the main entry point to the shader
4. Alter the text2D call
Now if you compile the project ….
And if you check out the output directory for the successful build you’ll find the binary of the compiled custom shader (cso).
We’ve successfully converted our fx to a cso ready for consumption in our managed metro SharpDx app.
Consuming the CSO as a custom effect via SharpDx
To speed things up I’m going to reuse the D2DCustomPixelShaderEffect project I created a few posts ago, “Custom Effects – Ripple Effect (Pixel Shader)” .
Copy across the cso into the project …
Create a C# custom effect wrapper around the cso much like what we did in the above mentioned post for the RippleEffect. Basically I just copied the RippleEffect.cs and renamed it to PixelateEffect.cs and changed some of the internals, it was pretty obvious what needed to be changed. If you get confused just re-read the above mentioned post
And the last step is to alter the EffectRenderer.cs to call the newly created custom effect PixelateEffect.cs .
The changes were simple, register the PixelEffect and wire up some gestures to alter the shaders 2 properties “HorizontalPixelCounts”, “VerticalPixelCounts”.
Again I won’t explain how to do that as it was covered in my earlier “custom effects” post.
Video of the demo
The frame rate is low and fluctuates quite a bit because of the video recording going on simultaneously.
I’ve successfully converted 14 of the FX files from the WPF/SL codeplex project , the ones that weren’t so easy to convert I will cover in future posts.
SharpDx is turning into a great framework that fills a big hole in the XAML/C# stack.
As for the performance of SharpDx, the shader demo’s I’ve been doing consistently achieve frame rates in the 60+ range. It’s definitely performant …
I look forward to seeing what others create on top of SharpDx!