Xna to monogame FX shader conversion help

Hello im not great at shaders but i have a shader from an old xna game of mine that looks amazing but get several errors while trying to convert it for use in monogame,one big problem is it uses parameters, below is the whole shader this is for windows on directx

/************* TWEAKABLES **************/

float4x4 worldIT : WorldInverseTranspose;
float4x4 wvp : WorldViewProjection;
float4x4 world : World;
float4x4 viewI : ViewInverse;

float4 tint = float4(1,1,1,1);

float reflectStrength 
< 
	string Object = "ReflectiveStrength";
	string UIName = "ReflectiveStrength";
	string Space = "World";	
> = 1.0;

float refractStrength 
< 
	string Object = "RefractStrength";
	string UIName = "RefractStrength";
	string Space = "World";	
> = 1.0;

half3 etas 
 < 
	string Object = "ETAS";
	string UIName = "ETAS";
	string Space = "World";	
> = { 0.80, 0.82, 0.84 };

texture cubeMap;

texture fresnelTex;

samplerCUBE environmentMapSampler = sampler_state
{
	Texture = <cubeMap>;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
};

sampler2D fresnelSampler = sampler_state
{
	Texture = <fresnelTex>;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = None;
};

/************* DATA STRUCTS **************/

/* data from application vertex buffer */
struct appdata {
    float4 Position	: POSITION;
    float4 UV		: TEXCOORD0;
    float3 Normal	: NORMAL;
};

/* data passed from vertex shader to pixel shader */
struct vertexOutput {
    float4 HPosition	: POSITION;
    float4 TexCoord		: TEXCOORD0;
    float3 WorldNormal	: TEXCOORD1;
    float3 WorldView	: TEXCOORD2;
};

/*********** vertex shader ******/

vertexOutput mainVS(appdata IN,
    uniform float4x4 WorldViewProj,
    uniform float4x4 WorldIT,
    uniform float4x4 World,
    uniform float4x4 viewI
) {
    vertexOutput OUT;
    float3 normal = normalize(IN.Normal);
    OUT.WorldNormal = mul(normal, (float3x3) WorldIT);
    float3 Pw = mul(IN.Position, World).xyz;
    OUT.TexCoord = IN.UV;
    OUT.WorldView = viewI[3].xyz - Pw;
    OUT.HPosition = mul(IN.Position, WorldViewProj);
    return OUT;
}

/********* pixel shader ********/

// modified refraction function that returns boolean for total internal reflection
float3 refract2( float3 I, float3 N, float eta, out bool fail )
{
	float IdotN = dot(I, N);
	float k = 1 - eta*eta*(1 - IdotN*IdotN);
	fail = k < 0;
	return eta*I - (eta*IdotN + sqrt(k))*N;
}

// approximate Fresnel function
float fresnel(float NdotV, float bias, float power)
{
   return bias + (1.0-bias)*pow(1.0 - max(NdotV, 0), power);
}

// function to generate a texture encoding the Fresnel function
float4 generateFresnelTex(float NdotV : POSITION) : COLOR
{
	return fresnel(NdotV, 0.2, 4.0);
}

float4 mainPS(vertexOutput IN,
    uniform samplerCUBE EnvironmentMap, 
    uniform half reflectStrength,
    uniform half refractStrength,
    uniform half3 etas
    ) : COLOR
{
    half3 N = normalize(IN.WorldNormal);
    float3 V = normalize(IN.WorldView);
    
 	// reflection
    half3 R = reflect(-V, N);
    half4 reflColor = texCUBE(EnvironmentMap, R);

	half fresnel = generateFresnelTex(dot(N, V));

	// wavelength colors
	const half4 colors[3] = {
    	{ 1, 0, 0, 0 },
    	{ 0, 1, 0, 0 },
    	{ 0, 0, 1, 0 },
	};
        
	// transmission
 	half4 transColor = 0;
  	bool fail = false;
    for(int i=0; i<3; i++) 
    {
    	half3 T = refract2(-V, N, etas[i], fail);
    	transColor += texCUBE(EnvironmentMap, T) * colors[i];
	}

    return lerp(transColor*refractStrength, reflColor*reflectStrength, fresnel) * tint;
}

/*************/

technique dx9 
{
	pass p0   
	{		
	    VertexShader = compile vs_4_0_level_9_1 mainVS(wvp,worldIT,world,viewI);
        PixelShader = compile ps_4_0_level_9_1 mainPS(environmentMapSampler,reflectStrength, refractStrength,etas);
	}
}

/***************************** eof ***/`

Can you edit your post to wrap the shader code in triple backticks. That will format it properly.

Looks like this

Backtick: `

You can remove the entry point function parameters and use the uniforms directly. E.g. remove the WorldViewProj parameter and replace the occurrences with wvp in MainVS. Then in your technique remove the arguments too. E.g. VertexShader = compile vs_4_0_level_9_1 MainVS();

If you are going to also use this in a DesktopGL project, know that parameter initialization does not work for GL platforms. So in that case you should set the parameters in your C# code after loading the effect.

I don’t know what the Object, UIName and Space strings are for, I don’t know that syntax. But you’re probably not using those, right? So if they cause issues you can just remove them.

Edit: if you still have errors after this, just post them here :slight_smile:

1 Like

Thanks Jjagg i will try that yes the Object Uiname and space are just for editors and im setting the params in C#
i.e like myeffect.Parameters[“world”].SetValue(world); for them all

i will give that a try many thanks for the quick reply.

1 Like

Many Thanks Jjagg your a life saver all works perfect now :slight_smile:

1 Like

We need screenshots now :wink:

hehe i cant give you any current ones because i still have a whole bunch of other stuff to do BUT heres what it looked like in XNA :slight_smile:

1 Like