Hey Rilesly,
To avoid confusion let me first make a clear distinction. The programming language you write your shaders in in MonoGame is HLSL. But on top of that MonoGame emulates DirectX’s FX framework. With DirectX FX’s framework you can define your sampler states, shaders and techniques all inside the shader. Instead of having to define these in code. Note that you can also set sampler states in code in MonoGame through the GraphicsDevice states.
This is similar to how you did this in XNA. However since MonoGame also transcodes HLSL shaders to OpenGL there a few minor details that you have to look at.
This probably one of the simplest shaders you can write in MonoGame. It outputs a solid color for the entire 3D model. Note the defines at the start
// Standard defines
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_5_0
#define PS_SHADERMODEL ps_5_0
#else
#define VS_SHADERMODEL vs_5_0
#define PS_SHADERMODEL ps_5_0
#endif
// Properties you can use from C# code
float4x4 World;
float4x4 View;
float4x4 Projection;
float4 Color;
// Required attributes of the input vertices
struct VertexShaderInput
{
float3 Position : POSITION0;
};
// Semantics for output of vertex shader / input of pixel shader
struct VertexShaderOutput
{
float4 Position : POSITION0;
};
// Actual shaders
VertexShaderOutput MainVS(in VertexShaderInput input)
{
VertexShaderOutput output = (VertexShaderOutput)0;
float4 worldPosition = mul(float4(input.Position.xyz, 1), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
return output;
}
float4 MainPS(VertexShaderOutput input) : COLOR0
{
return Color;
}
// Technique and passes within the technique
technique ColorEffect
{
pass Pass0
{
VertexShader = compile VS_SHADERMODEL MainVS();
PixelShader = compile PS_SHADERMODEL MainPS();
}
}
After you then compile this effect using the MonoGame content pipeline tool. You can load it using the content manager
Effect effect = ContentManager.Load<Effect>("MyEffect");
And you can then apply the technique like this, make sure to set the properties before applying the technique!
effect.Parameters["World"].SetValue(Matrix.Identity);
// etc //
effect.CurrentTechnique = this.effect.Techniques["ColorEffect"];
effect.CurrentTechnique.Passes[0].Apply(); // Since we only have one pass
If you then draw something it will be done using the applied effect
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length,
indices, 0, 12);
Models usually their own shaders baked in when its build. You can overwrite the standard shaders used by setting a different processor for that mode in the MonoGame content pipeline tool. However this is quite an advanced technique and you can overwrite a model’s effect using code at runtime. So if you need that I suggest you start with that.
(For an example content pipeline extension that adds a different shader see: https://github.com/roy-t/MiniRTS/tree/master/Engine/ModelExtension)