Broken Monogame Effect that works in XNA

I have been trying to get an effect from this tutorial Here in XNA to work in MonoGame. I began building into my own code and when it didn’t work I Remade the project exactly like the tutorial in MonoGame but it is still not working.

The only change I had to do to get the code to build in MonoGame was on this part of the effect.

technique SpriteBatch

{
pass
{
VertexShader = compile vs_4_0 SpriteVertexShader();
}
}

where vs_4_0 was previously vs_2_0. This is because MonoGame was giving me a build error relating to the version of vertex shader.

I am unsure what is causing this or where to look for help. I apologize if this is a repeat of a question but i cant find a solution. Any help or suggestions are of course greatly appreciated.

The broken effect causes no errors unfortunately but it it creates a yellow green red and black set of squares(see images). Though it should look like the grass texture from the tutorial.

I am not the best at writing effects though i have a basic understanding,
Leave a comment if You need more info on the problem. Thank You For Reading.

Need more information… post your whole shader to pastebin.com or here.

What you are seeing looks like UV coords multiplied by… hmm… 4. Make sure you are sampling texture correctly. Monogame DX requires Shader model 4.0 or newer, this is why it requires to be compiled as vector shader version 4.0. This alone doesn´t cause any issues.

Hi Ravendarke Thanks for an answer. I wasn’t clear enough but i mentioned the fact that i actually rebuilt the code from the xna tutorial into monogame line for line to make sure the problem wasn’t associated with any other code i wrote. I cant understand how the code can be broken as it is identical to the xna sample which works fine. I am guessing the problem might be an issue with compatibility or formatting of some sort, could this be correct?
I will post the shader here below but to save time for anyone trying to help the tutorial is Here and the tutorial source code is Here

I would like to get the basic tutorial code working before i continue editing it for my application.

Heres the shader

sampler TextureSampler : register(s0);
float2 ViewportSize;
float4x4 ScrollMatrix;

void SpriteVertexShader(inout float4 color : COLOR0, inout float2 texCoord : TEXCOORD0, inout float4 position : POSITION0)
{
// Half pixel offset for correct texel centering.
position.xy -= 0.5;

// Viewport adjustment.
position.xy = position.xy / ViewportSize;
position.xy *= float2(2, -2);
position.xy -= float2(1, -1);

// Transform our texture coordinates to account for camera
texCoord = mul(float4(texCoord.xy, 0, 1), ScrollMatrix).xy;
}

technique SpriteBatch
{
pass
{
VertexShader = compile vs_4_0 SpriteVertexShader();
}
}

If this also helps Im using monogame 3.5

Well, let´s say that viewportsize and scrollmatrix are being send correctly. In that case last thing that remains is to consider if Monogame correctly assign default pixel shader. My suggestion is to write simple pixel shader.

    sampler TextureSampler : register(s0);
    float2 ViewportSize;
    float4x4 ScrollMatrix;
    
    struct VertexToPixel
    {
        float4 Position : SV_Position0;
        float2 TexCoord : TEXCOORD0;
        float4 Color : COLOR0;
    };


    VertexToPixel SpriteVertexShader(inout float4 color : COLOR0, inout float2 texCoord : TEXCOORD0, inout float4 position : POSITION0)
    {
        VertexToPixel Output = (VertexToPixel)0;
        
        // Half pixel offset for correct texel centering. - This is solved by DX10 and half pixel offset would actually mess it up
        //position.xy -= 0.5;

        // Viewport adjustment.
        position.xy = position.xy / ViewportSize;
        position.xy *= float2(2, -2);
        position.xy -= float2(1, -1);

        // Transform our texture coordinates to account for camera
        Output.TexCoord = mul(float4(texCoord.xy, 0, 1), ScrollMatrix).xy;
        
        //pass position and color to PS
        Output.Color = color;
        Output.Position = position;
    }
    
    
    float4 SpritePixelShader(VertexToPixel PSIn): COLOR0
   {
        float4 diffuse = tex2D(DiffuseSampler, PSIn.TexCoord);
        return diffuse * PSIn.Color;
    }

    technique SpriteBatch
    {
    pass
        {
        VertexShader = compile vs_4_0 SpriteVertexShader();
        PixelShader = compile ps_4_0 SpritePixelShader();
        }
    }

I am kinda in rush right now, so I wrote it in notepad and didn´t try to compile it, sorry if I made some mistake, let me know if you will run into any issues. Also notice note about half pixel offset.

Hi

its works fine, I am trying too for to understand fx file with monogame.
But delete inout and replace by return Output in VertexToPixel :wink:

Ravendarke can you help me please post Effect file, I have some problems with array.

Sry for my bad english.

ah I didn´t notice, it should be just:

(float4 color : COLOR0, float2 texCoord : TEXCOORD0, float4 position : SV_Position0)

Arrays and shaders might be kinda complex, explain what issue are you having.

Yes, I see that

I have create a topic “Effect file” today.

topic

Issue is no update of variable if I use array, but without my shader works fine.

Thank you on advance

Sorry about the delay in response. I am getting an error on the Diffuse Sampler its an “undeclared identifier” must i declare this with certain parameters? I apologize if i may be asking alot(or too little) but I do not have enough experience in shaders to work competently(I will be looking for a good book on them after i solve this).

Do you have copy/past a code?

Diffuse Sampler -> its your sampler, its a minim mistake replace by TextureSampler

:wink:

Ha Ha I cant believe i missed that. Ive been looking at the same code so long its just words now :confused:
I am copy/pasting code relating to hlsl so that i can avoid mistakes, Although I will have to get fluent in it whether i like it or not.

Did you say this code works for you Tankerpat? Im getting a black screen at the moment with no errors.

lol

No errors, I see a grass texture.
I don’t know why you have a error.

sampler TextureSampler : register(s0);
    float2 ViewportSize;
    float4x4 ScrollMatrix;
    
    struct VertexToPixel
    {
        float4 Position : SV_Position0;
        float2 TexCoord : TEXCOORD0;
        float4 Color : COLOR0;
    };


    VertexToPixel SpriteVertexShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0, float4 position : POSITION0)
    {
        VertexToPixel Output = (VertexToPixel)0;
        
        // Half pixel offset for correct texel centering. - This is solved by DX10 and half pixel offset would actually mess it up
        position.xy -= 0.5;

        // Viewport adjustment.
        position.xy = position.xy / ViewportSize;
        position.xy *= float2(2, -2);
        position.xy -= float2(1, -1);

        // Transform our texture coordinates to account for camera
        Output.TexCoord = mul(float4(texCoord.xy, 0, 1), ScrollMatrix).xy;
        
        //pass position and color to PS
        Output.Color = color;
        Output.Position = position;

    return Output;
    }
    
    
    float4 SpritePixelShader(VertexToPixel PSIn): COLOR0
   {
        float4 diffuse = tex2D(TextureSampler , PSIn.TexCoord);
        return PSIn.Color *diffuse ;
    }

    technique SpriteBatch
    {
    pass
        {
        VertexShader = compile vs_4_0 SpriteVertexShader();
        PixelShader = compile ps_4_0 SpritePixelShader();
        }
    }

Try this, but its a samething :wink:

I wrote my constructor wrong. I got it working now Thanks a million @Ravendarke and @Tankerpat You have gave me a serious boost in a game im working on :grinning:
will hlsl work stably with android and ios through the pipeline?

Just as a last request can you recommend any good resources(preferably books) to help with effects.

Thanks again for all the help

For android and iOS you will have to use OpenGL version.

You don’t have to write glsl though. If you use the Pipeline Tool and ContentManager just setting the target platform will build the shader for you. You might need some preprocessor directives to work out some differences between glsl and hlsl though, like shader profile.

Doesn´t he still has to change target Shader model? I mean isn´t OpenGL limited to 2.0?

The fx file does throw an error with an incorrect version for certain ravendarke. I am getting a different error though in android and opengl projects bringing thiseffect into the mix.

System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

Ive only started to look into this but its definitely caused by the effect I just need to find out why.

Hi @Jjagg I was wondering if you have ever ran into the System.ArgumentException I mentioned before in using a HLSL fx file in opengl project. I have been trying to fix this but it seems that I keep causing errors. Maybe @Ravendarke or @Tankerpat might have an idea on what to do? I tried using a hlsl to glsl converter but it failed to create functional code. Will i need crash course GLSL? The error generated is

System.ArgumentException occurred
HResult=-2147024809
Message=Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
ParamName=“”
Source=mscorlib
StackTrace:
at System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)
at Microsoft.Xna.Framework.Graphics.ConstantBuffer.SetData(Int32 offset, Int32 rows, Int32 columns, Object data)
at Microsoft.Xna.Framework.Graphics.ConstantBuffer.SetParameter(Int32 offset, EffectParameter param)
at Microsoft.Xna.Framework.Graphics.ConstantBuffer.Update(EffectParameterCollection parameters)
at Microsoft.Xna.Framework.Graphics.EffectPass.Apply()
at Microsoft.Xna.Framework.Graphics.SpriteBatcher.FlushVertexArray(Int32 start, Int32 end, Effect effect, Texture texture)
at Microsoft.Xna.Framework.Graphics.SpriteBatcher.DrawBatch(SpriteSortMode sortMode, Effect effect)
at Microsoft.Xna.Framework.Graphics.SpriteBatch.End()
at Game1.Draw(GameTime gameTime) in C:\OpenGL_Sample\Game1.cs:line 79
InnerException:

Sorry for all the hassle I am currently operating out of my comfort zone so i may be missing a lot of need to know information.

I got the argument exception to change into an null reference now i see the problem is the pipeline ignoring two of three parameters which I need to set or the effect is useless. Why is the pipeline cutting out these necessary values only in opengl? Should this be a new Topic?

Yes, that’s one of the differences that you can solve with preprocessor directives that I was referring to.

@JJMGSOFTWORKS I’m a bit busy for a couple days, but if you share your drawing code I’ll take a look at this when I have some more time

Hi Jjagg I decided it was easier to push the code to github because its a rewrite of a tutorial anyway. The link to the repo is Here, Like i said before this code works perfect in Windows Projects I think it may be a small bug in the pipeline but i simply lack the knowledge to know for sure.
I have been developing my game with Unity recently but Id love to use Monogame because its an awesome framework for flexibility and control.