Shader ported from XNA not working

Hi Guys,

I’ve just converted an XNA Project to MonoGame Windows DirectX. It has three shaders but since the conversion two of them no longer work. I have gone through various documentation about the changes required to make them work with MonoGame e.g. changing the pixel shader version and the main method parameters but the effect doesn’t work when applied to my sprite batch, the sprite in question just doesn’t draw at all with the shader effect enabled.

The shader code is below:

// Effect uses a scrolling displacement texture to offset the position of the main
// texture. Depending on the contents of the displacement texture, this can give a
// wide range of refraction, rippling, warping, and swirling type effects.

float2 DisplacementScroll;

sampler TextureSampler : register(s0);
sampler DisplacementSampler : register(s1);

float4 PixelShaderFunction(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// Look up the displacement amount.
float2 displacement = tex2D(DisplacementSampler, DisplacementScroll + texCoord / 3);

// Offset the main texture coordinates.
texCoord += displacement * 0.2 - 0.15;

// Look up into the main texture.
return tex2D(TextureSampler, texCoord) * color;

}

technique Refraction
{
pass Pass1
{
PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}

It uses a texture that is rotated by an external function to draw a distortion effect. I have confirmed that the texture is being loaded and applied correctly and the parameters are being set and adjusted during the update (the valies going in are exactly the same as the XNA project.

Can anyone see anything obviously wrong? If I disable the effect the sprite draws without issue.

Many thanks,

Damien

I was looking at this a while back and wanted it for my menus:

But I don’t know anything about shaders and it was for Unity and I had no idea to convert it. Then I found this:
http://xbox.create.msdn.com/en-US/education/catalog/sample/sprite_effects

Is it just me or does the shader mainly go down and right? The lower right corner is almost never seen. At least with the waterfall texture provided. This is a problem…

Yes it is an example XNA project that I’m trying to get working, I used it for some effects in my game. Unfortunately I know very little about shaders too. I take your point about the movement, but why does it work on XNA and not in MonoGame. Is MonoGame handling something differently here?

Use “SAMPLE_TEXTURE” and “DECLARE_TEXTURE” macros instead of “tex2D”
It is declared in monogame source code.

https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Graphics/Effect/Resources/Macros.fxh

Hope that will work.

Hi Kagamia,

Many thanks for your response. I’ve recently managed to get the MonoGame source to build, so was able to have a look at the code files.

You right about the Macros, though from what I can see, they just give better names for some of the more obscure definitions. However, I have now modified my shader to look like this:

#include “Macros.fxh”

float2 DisplacementScroll;

DECLARE_TEXTURE(TextureSampler, 0);
DECLARE_TEXTURE(DisplacementSampler, 1);

float4 PixelShaderFunction(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// Look up the displacement amount.
float2 displacement = SAMPLE_TEXTURE(DisplacementSampler, DisplacementScroll + texCoord / 3);

// Offset the main texture coordinates.
texCoord += displacement * 0.2 - 0.15;

// Look up into the main texture.
return SAMPLE_TEXTURE(TextureSampler, texCoord) * color;

}

technique Refraction
{
pass Pass1
{
PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}

This does compile, and I can now see my sprite drawing on the screen, which seems like a step forward. However it looks like this:

Which is almost correct but… there is no shimmering from the movement of the displacement texture so it appears that this part is not working. I have written out the values of the routine that moves the displacement texture in a circle and the values exactly match the output of the routine in XNA so this doesn’t appear to be the problem.

Does the above code look correct to you now…? If I can’t get this to work - I’ll just have to learn a bit more about HLSL and rewrite it myself. From what I can tell all it does is use the second texture as a displacement map which recolours part of the sprite texture - affecting the alpha and thus causing a shimmering effect as the aplha levels change when the texture is rotated (by some external code).

You could copy the codes from monogame build-in effect files, and learn how to declare parameters in HLSL(or CG language).

“BasicEffect.fx” and “SpriteEffect.fx” are good examples for you.

Try to put “BEGIN_CONSTANTS” and “END_CONSTANTS” in your code :slightly_smiling:

There are many difference between shader model 4.0(dx11) and 3.x(dx9, xna), it becomes strict, old style codes will not fully support.

Even reverse ps_input semantics order will make a bad effect =w=

That’s a good idea, I have started looking at the test shaders in the source code. It does look like the code is quite finnicky.

Is there any way to debug shaders in Visual Studio 2015? I keep reading that it’s possible but have yet to be able to understand the tutorials (I’m a bit ashamed of myself to be honest) but maybe I’m missing a VS extension or something…?