Shader Question [solved]

I have a basic Problem using shader.
I’m new to shader and I want to understand the basics.
I got plenty tutorials to read but no one seems to work with monogame. (won’t compile or blank screen)
So my question is what do I wrong?

I started with a shader where input = output.

sampler s0;

float4 PixelShaderFunction(float2 coord : TEXCOORD0) : COLOR0
{
	float4 color = tex2D(s0, coord);
	return color;
}


technique
{
    pass P0
    {
        PixelShader = compile ps_4_0_level_9_3 PixelShaderFunction();
    }
}

and I Draw with:

spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, _AlphaShader);

spriteBatch.Draw(_Planet, new Vector2(0, 0), Color.White);

spriteBatch.End();

But there is no output. I have a blank screen.
This seems like a noob-question, I just want to understand how this works and why I can’t get a shader to work.

return float4(1, 0, 0, 1); works for the test (red square where the image is)

Thank you

float4 PixelShaderFunction(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0

You must always have an SV_POSITION in an input of the PixelShaderFunctionmethod (POSITION for vertex)

Thank you. This is working =)
And I understand now how I can manipulate the pixels on runtime with parameters and SetValue.
This is cool.

I have another question:
If I want a second image as alpha mask how can i load this in the shader just for the alpha information?
Tried with a second parameter
sampler alphamask;
But if I want to fill it with
_AlphaShader.Parameters["alphamask"].SetValue(_AlphaMap);
I get a NullReferenceException.

SamplerState alphaSampler
{
    Texture = (alphaTex);   
    Filter = Linear;  
    AddressU = clamp;
    AddressV = clamp;
};

....
_AlphaShader.Parameters["alphaTex"].SetValue(_AlphaMap);

Sry… I can’t get this to work either.
Same error.

Need a little bit more advice on this.
Sry i’m new to this =/

Post your whole shader.

sampler s0;
float input;
texture alphaTex;
sampler alphamap = sampler_state
{
    Texture = (alphaTex);   
    Filter = Linear;  
    AddressU = clamp;
    AddressV = clamp;
};

float4 PixelShaderFunction(float4 position : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0
//float4 PixelShaderFunction(float2 coords : TEXCOORD0) : COLOR0
{
	color = tex2D(s0, coords);
	if (!any(color)) return color;

	float step = 1.0/input;

	if (coords.x < (step * 1)) color = float4(1, 0, 0, color.a);
	else if (coords.x < (step * 2)) color = float4(1, .5, 0, color.a);
	else if (coords.x < (step * 3)) color = float4(1, 1, 0, color.a);
	else if (coords.x < (step * 4)) color = float4(0, 1, 0, color.a);
	else if (coords.x < (step * 5)) color = float4(0, 0, 1, color.a);
	else if (coords.x < (step * 6)) color = float4(.3, 0, .8, color.a);
	else color = float4(1, .8, 1, color.a);

return color;
}


technique
{
    pass P0
    {
        PixelShader = compile ps_4_0_level_9_3 PixelShaderFunction();
    }
}

if (!any(color)) return color; //not sure if this even works

You will want to avoid predictive instruction in shader as much as possible, it is kinda giving hell to the whole point of parallelization which makes GPU effective. I am not saying that modern GPU can´t deal with one or two ifs in shader, but nested condition…

Anyway you are not sampling your alpha texture anywhere, if you want to use alphaTex as alpha of texture in sampler 0 then:

float4 color = tex2D(s0, coords);
float alpha = tex2D(alphamap, coords).a;

color.a = alpha;

Also in your example color isn´t declared properly. I am pretty sure that XNA and monogames shader tutorials explains that thoroughly.

this whole thing with step and color works.
that was only a test for parameters.

i deleted the stuff
this one compiles as long as I don’t touch the parameters in my c# code.

sampler s0;
texture alphaTex;
sampler alphamap = sampler_state
{
    Texture = (alphaTex);   
    Filter = Linear;  
    AddressU = clamp;
    AddressV = clamp;
};

float4 PixelShaderFunction(float4 position : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0
//float4 PixelShaderFunction(float2 coords : TEXCOORD0) : COLOR0
{
	color = tex2D(s0, coords);
	return color;
}


technique
{
    pass P0
    {
        PixelShader = compile ps_4_0_level_9_3 PixelShaderFunction();
    }
}

_AlphaShader.Parameters["alphaTex"].SetValue(_AlphaMap);
this line shows an NullReferenceException If I add it.
Whole Draw code:

    GraphicsDevice.Clear(Color.White);

    _AlphaShader.Parameters["alphaTex"].SetValue(_AlphaMap);

    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, _AlphaShader);

    spriteBatch.Draw(_Planet, new Vector2(testx, 0), Color.White);

    spriteBatch.End();

It is giving you null reference because you never use that alphasampler, you never sample single pixel from it, thus compiler removes it as part of optimization. As I said:

float4 color = tex2D(s0, coords);
float alpha = tex2D(alphamap, coords).a;

color.a = alpha;
...

Also, ah yeah, you are using color from input, rather just name this one differently, for instance:

float4 diffuse = tex2D(s0, coords);

Oh crap, i’m sry.
Didn’t understand that :smiley:
I thought just setting the texture without using it let me compile.
Very senitive haha

I’ve rewritten the part with color too =)

It works now. Thank you very much! =D

No problem, glad it works. Also yeah, that compiler is aggresive as hell. Even worse there is strange fallthrough. For instance let´s say you have 4 samplers to be used in shader. You have to use them (float4 normal = tex2D(…) ) in same order as they are declared, otherwise if you will for instance use 4th sampler before 3rd then texture assigned to 4th will suddenly be assigned to 3rd sampler.

This is issue when you are using for example normal map to distort uv coords of texture in sampler0 because in that case you need to sample second sampler first in order to get texCoords for first sampler, but you kinda can´t. So you have to shuffle with textures in code while draw call is being created. Something to keep in mind.

What does this mean for my alpha shader?
should I first load my mask or first the background?

So far I get i to work =)
Just have to figure out why there is this white stuff

	float4 textcolor = tex2D(s0, coords);
	float4 alpha = tex2D(alphamap, coords);
	textcolor.a = textcolor.a * alpha.a;
	
	return textcolor;


In your case order doesn´t matter, so it means nothing. This “white stuff” is alpha blending of nonpremultiplied alpha channel, either use .nonpremultiplied blendstate or multiply rgb with alpha channel, thus textcolor.rgb *= textcolor.a before output.

I seriously recommend you to carefully read those tutorials and materials. I work as technical artist for two years (while having master degree in computer science - computer graphic focus) and still I am considering myself a beginner, you are not going to get any deeper explanation in this thread as it is extremely complex subject. Also after obtaining basics I recommend you to find GPU gems 1 - 3 which were made accessible for free by Nvidia on web.

I love you xD

Now this is working as I want!
Perfect.

I do it with the rgb solution

The Problem about the tutorials I found … the most are outdated as hell.

I will look at the GPU gems.
I hope there are many 2D examples.

Well it doesn´t matter much (the fact that they are outdated), most things are the same and now we have covered main differences in behavior between XNA and Monogame. Lot of techniques from 3d are applicable in 2d.

I worked years ago in a small company (while studying computer science - didn’t finished it though) and had to work with C# and XNA there. Many tutorials I know back then don’t work with monogame without recoding.
I was sad as I heard XNA will not be developed further.
Never had to use shader ^^

But now I will seriously coding a game and need to know as much as possible for shading 2D grafics.
I will read the gems for sure! Just had to understand the basics.