XNA to MonoGame shader porting

Hello! Im trying to use this shader for a new project with monogame.

When i try to change color of a texture, it remains black.

src:
https://pastebin.com/KzEEHMPA

i use vs_4_0_level_9_1 and ps_4_0_level_9_1

Have you set your project graphics settings to HiDef? Google for that line

Pro tip: wrap your code in triple backticks ` to format it properly.

1 Like

no it 's sets “Reach”

I did not see any sv_position in your shader, only position0 in vs input.

Do you have an alpha channel in your picture? Because there are discard calls when alpha ==0

1 Like

I’m trying to port this project (https://github.com/ZaneDubya/UltimaXNA/blob/master/dev/Content/Shaders/IsometricWorld.fx)

from XNA to MonoGame.
After some internal fix game runnin good, but it doesnt color object. Only BLACK!
I’m sure it works on xna platform.

I made some changes, but it doesnt work :frowning: : https://pastebin.com/4EgySAGw

In ps_input you can use POSITION0, choosing one or another has to do with interpolation

Concerning Compiler Targets:

Look at Shader movel ps_4_0_level_9_1 doesn't allow reading from position semantics. too :wink:

About SV_POSITION and when to use it:
Semantics - Win32 apps | Microsoft Learn says:

The pixel location (x,y) in screen space. To convert a Direct3D 9 shader (that uses this semantic) to a Direct3D 10 and later shader, see Direct3D 9 VPOS and Direct3D 10 SV_Position)

Also, have a look at "‘Semantics Supported Only for Direct3D 10 and Newer.’

What is the technique you are currently trying to use ?
Have you tried with a simple:

‘’‘return float4(1.0, 0, 0, 0);’‘’

to see if it draws red ?

Changed into ps_input from sv_position to position0.

im trying to use “HueTechnique”.

into PixelShader_Hue, if i return float4(1,0,0,0) it returns all red

but it doesnt work for my target :frowning:

So it somewhat works.
Did you check you had an alpha channel on the texture?

1 Like

if after color.a== 0 { discard;} i put a return color;, it color my game with basic texture color.
else color black.

I think the problem is this part:

if (IN.Hue.x >= HuesPerTexture)
{
hueColor = tex2D(HueSampler1, float2(inHueIndex, (IN.Hue.x - HuesPerTexture) / HuesPerTexture));
}
else
{
hueColor = tex2D(HueSampler0, float2(inHueIndex, IN.Hue.x / HuesPerTexture));
}

if i put float4 hueColor = float4(IN.Hue.x, 0,0,0), return red… maybe wrong order input?

it’s an old game, it hasnt alpha textures :stuck_out_tongue:

Well, discard is not equivalent to return, it only does not display the output of the current pixel:
http://jbrd.github.io/2008/02/14/hlsl-discard-doesnt-return.html

Adding a return with black or whatever color should improve performances instead of continuing with the remaining code and finally not displaying it.
Also, from dx10, you dont need halfpixel calculations on the position (which is usually done on texcoords not position)

What i dont understand is why there is a test on alpha if there is no alpha in the texture?
Alpha channel was already used in the doom1 era, the bfg effect used it, weapons of the player too.
What does it do if you remove this part?
It may also come from the part you are pointing, see if it gives values between [0,1] in the float2
Also check the value of the hueindex by maybe returning in the green channel?

My mistake: alpha exists, and discard it’s necessary to draw correctly game to avoid tile overlapping.

float2 gives values between 0 and 1 (both for x and y, i dont know how retrive exaclty value in runtime :D)

hueindex value is between 0 and 0.5…

float inHueIndex = ((color.r + color.g + color.b) / 3.0f);
It should be between 0 and 1 if r , g, b are within [0,1]

Basically, this part only changes the direction of the sampling depending on where we are in IN.Hue.x compared to HuesPerTexture: increasing gradiant, or decreasing it, and changing the sampler according to that.

{	
     hueColor = tex2D(HueSampler1, float2(inHueIndex, (IN.Hue.x - HuesPerTexture) / HuesPerTexture));
}
else
{	
    hueColor = tex2D(HueSampler0, float2(inHueIndex, IN.Hue.x / HuesPerTexture));	
}```

if i do:

float4 color = tex2D(DrawSampler, IN.TexCoord);
if (color.a == 0)
discard;
return color;

Textures are colored with basic game texture. (https://i.imgur.com/WDFy6EI.jpg)

after returned color is ever black… (https://i.imgur.com/JZJtlgD.png)

You need to do

if (color.a == 0)
{
    discard;
    return color;
}

Nonetheless the 1st screenshot seems ok if hue textures are gray gradients.

monopipeline compiler gets an error if i put a rturn after discard.

grey color it s base texture color in this game, but an item can has a different color

float4x4 ProjectionMatrix;
float4x4 WorldMatrix;
float2 Viewport;

float3 lightDirection;
float lightIntensity;
float ambientLightIntensity;
bool DrawLighting;

sampler textureSampler[15];
sampler hueTextureSampler;

struct VS_INPUT
{
	float4 Position : POSITION0;
	float3 Normal	: NORMAL0;
	float3 TexCoord : TEXCOORD0;
	float2 Hue		: TEXCOORD1; //If X = 0, not hued. If X > 0 Hue, if X < 0 partial hue. If Y != 0, target

};

struct PS_INPUT
{
	float4 Position : POSITION0;
	float3 TexCoord : TEXCOORD0;
	float3 Normal	: TEXCOORD1;
	float2 Hue		: TEXCOORD2;
};

PS_INPUT VertexShaderFunction(VS_INPUT IN)
{
	PS_INPUT OUT;
	
	OUT.Position = mul(mul(IN.Position, WorldMatrix), ProjectionMatrix);
	
	// Half pixel offset for correct texel centering.
	OUT.Position.x -= 0.5 / Viewport.x;
	OUT.Position.y += 0.5 / Viewport.y;

	OUT.TexCoord = IN.TexCoord; 
	OUT.Normal = IN.Normal;
	OUT.Hue = IN.Hue;
	
    return OUT;
}

// New pixelshader created by Jeff - simulates sunrise.
float HuesPerColumn = 2024;
float HuesPerRow = 2;
float4 PixelShaderFunction(PS_INPUT IN) : COLOR0
{	
	// get the initial color
	float4 color = tex2D(textureSampler[0], IN.TexCoord);
	
	if (IN.TexCoord.x < 0.0f || IN.TexCoord.y < 0.0f ||
		IN.TexCoord.x > 1.0f || IN.TexCoord.y > 1.0f)
		color.a = 0;
	
	if (color.a == 0)
	{
		discard;
	}

	// do lighting
	if (DrawLighting)
	{
		float light_DirectedIntensity = 0.5f + lightIntensity / 2;
		float light_AmbientIntensity = (1.0f - lightIntensity / 10) * ambientLightIntensity;
		float NDotL = saturate(dot(-lightDirection, IN.Normal));
		color.rgb = (light_AmbientIntensity * color.rgb) + (light_DirectedIntensity * NDotL * color.rgb);
	}
	
	// is the texture hued or partially transparent?
	// Hue effects are bit flags:
	// 1 = hued 
	// 2 = partially hued
	// 4 = partially transparent.
	// 1 & 2 are mutually exclusive. default to 1 if both exist.
	float hueY = (((IN.Hue.x - (IN.Hue.x % 2)) / HuesPerRow) / (HuesPerColumn));
	float gray = ((color.r + color.g + color.b) / 3.0f / HuesPerRow + ((IN.Hue.x % 2) * 0.5f)) * 0.999f;
	float4 huedColor = tex2D(hueTextureSampler, float2(gray, hueY));
	huedColor.a = color.a;

	if (IN.Hue.y >= 4) // 50% transparent
	{
		IN.Hue.y -= 4;
		color *= 0.5f;
	}

	if (IN.Hue.y == 2) // partial hue - map any grayscale pixels to the hue. Colored pixels remain colored.
	{
		if ((color.r == color.g) && (color.r == color.b))
			color = huedColor;
	}
	else if (IN.Hue.y >= 1) // normal hue - map the hue to the grayscale.
	{
		color = huedColor;
	}

	return color;
}


technique StandardEffect
{
	pass p0
	{
		VertexShader = compile vs_3_0 VertexShaderFunction();
		PixelShader = compile ps_3_0 PixelShaderFunction();
	}
}

When i try to compile, compiler gives to me an error (unexpected token’[’ found, expected semicolo, comma or closeparenthesis) at
“sampler textureSampler[15];”

How to fix?

I am not sure an array of samplers can exist in a shader