Custom shader example, HLSL, 3D

Working shader example (only tested on OPENGL, Windows)

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

float4x4 wvp;

float4 ColorAndAlpha = float4(1,1,1,1);
float2 SourcePos = float2(0,0);
float2 SourceSize = float2(1,1); 

texture ColorMap;
sampler ColorMapSampler = sampler_state 
{
    texture = <ColorMap>;    
};

struct VS_IN
{
    float4 Position : SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : NORMAL;
    float3 Tangent : TANGENT;
};
struct VS_OUT
{
    float4 Position : SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : TEXCOORD1;
};

VS_OUT VS_Flat(VS_IN input)
{
    VS_OUT output = (VS_OUT)0;
    output.Position = mul(input.Position,wvp);
    output.TexCoord = input.TexCoord;
    return output;
}

VS_OUT VS_FixedLight(VS_IN input)
{
    VS_OUT output = (VS_OUT)0;
    output.Position = mul(input.Position,wvp);
    output.Normal = input.Normal;
    output.TexCoord = input.TexCoord;

    return output;
}

float4 PS_Flat(VS_OUT input) : COLOR0
{
    float4 texCol = tex2D(ColorMapSampler, (input.TexCoord * SourceSize + SourcePos));
    float4 output = texCol * ColorAndAlpha;

    output.rgb *= ColorAndAlpha.a;
    clip(texCol.a - 0.01);

    return output;
}

float4 PS_FixedLight(VS_OUT input) : COLOR0
{   
    float2 textureCoord = input.TexCoord * SourceSize + SourcePos;
    float4 texCol = tex2D(ColorMapSampler, textureCoord);

    float3 normalNormal = normalize(input.Normal);
    float3 lightDir = normalize(float3(1,1,1));
    float lightReflect = dot(normalNormal, lightDir) * 0.3;

     float4 output = (texCol * 0.7 + texCol * lightReflect) * ColorAndAlpha;

    output.a = texCol.a * ColorAndAlpha.a;
    output.rgb *= output.a;
    clip(texCol.a - 0.01);

    return output;
}

technique Flat //Renders a 3d model with no light effect
{
    pass Pass0
    {
        VertexShader = compile VS_SHADERMODEL VS_Flat();
        PixelShader = compile PS_SHADERMODEL PS_Flat();
    }
}

technique FixedLight //Renders a 3d model with a static ligtht gradient (Lambert)
{
    pass Pass0
    {
        VertexShader = compile VS_SHADERMODEL VS_FixedLight();
        PixelShader  = compile PS_SHADERMODEL PS_FixedLight();
    }
}

http://lmgtfy.com/?q=hlsl+monogame+texture :innocent:

Yes, yes, Ive been googling and testing different shaders. I am trying to figure out why my shaders that work in XNA, just crashes the game now.

If you share the shader, people here can troubleshoot.

This is one of my shaders, its pretty messy though.
If I remove
float3 CamView : TEXCOORD2;
float4 posS : TEXCOORD3;
and just render the vColor without any the processing, it works.

#if OPENGL

#define SV_POSITION POSITION

#define VS_SHADERMODEL vs_3_0

#define PS_SHADERMODEL ps_3_0

#else

#define VS_SHADERMODEL vs_4_0_level_9_1

#define PS_SHADERMODEL ps_4_0_level_9_1

#endif


float4x4 wvp : WorldViewProjection;
float4x4 world : World;

#define FogStart 160
#define MaxShadows 8
#define DepthColor 0.01
#define MaxLightningStrength 0.7
#define MaxMagicLightStrength 0.3

int ShadowQty = 0;
float3 LightSourcePosition[MaxShadows];
float LightSourceRadius[MaxShadows];
int LightSourceType[MaxShadows];

float Opacity;

struct VS_IN
{
    float4 Position : SV_POSITION;
    //float2 TexCoord : TEXCOORD0;
    //float3 Normal : NORMAL;
    //float3 Tangent : TANGENT;
    float4 vcolor : COLOR0;
};
struct VS_OUT
{
    float4 Position : SV_POSITION;
    float3 CamView : TEXCOORD2;
    float4 posS : TEXCOORD3;
    float4 vcolor : COLOR0;
    
};

VS_OUT VS_FlatVertexColored(VS_IN input)
{
    VS_OUT output = (VS_OUT)0;
    output.Position = mul(input.Position, wvp);
    output.posS = mul(input.Position, wvp);
    output.vcolor = input.vcolor;

    output.CamView = mul(input.Position, world);
    return output;
}

float4 PS_VertexColoredWidthPointShadows(VS_OUT input) : COLOR0
{   
    float4 output = input.vcolor;

    for (int i = 0; i < ShadowQty; i++)
    {
        float3 shadowDist = LightSourcePosition[i] - input.CamView;
        if (LightSourceType[i] == 0)
        { //SHADOW
            shadowDist.y *= 0.5; //makes the shadows flatter
            float dist = length(shadowDist);
            dist /= LightSourceRadius[i];
            float colMultiply = 0.6 + dist * dist;

            if (colMultiply < 1)
            {
                output.rgb *= colMultiply;
            }
        }
        else if (LightSourceType[i] == 1)
        { //FIRE
            float dist = length(shadowDist);
            float strength = LightSourceRadius[i] - dist * dist;
            if (strength > 0)
            {
                output.r += 0.03 * strength;
                output.g += 0.006 * strength;
                output.b += 0.004 * strength;
            }
        }
        else if (LightSourceType[i] == 3)
        { //MAGIC LIGHT, has a bluegreen color
            float dist = length(shadowDist);
            float strength = 1 - (dist / LightSourceRadius[i]);
            if (strength > 0)
            {
                if (strength > MaxMagicLightStrength)  strength = MaxMagicLightStrength;

                output.r += 0.1 * strength;
                output.g += 0.6 * strength;
                output.b += strength;
            }
        }

    }

    output.rgb *= length(input.vcolor) - 0.1; //the length of the normal is used to add shadows and highlights
    //Fog effect
    if (input.posS.z > FogStart)
    {
        float t = saturate((input.posS.z - FogStart * 3) * 0.001f);
        float3 farColorMid = float3(0.20703125, 0.62745098039, 0.80392156862); // copied from BackgroundScenery.cs
        float3 farColorBtm = float3(0.8515625, 0.9375, 0.97265625); // copied from BackgroundScenery.cs
        float3 farColor = lerp(farColorBtm, farColorMid, 0.4);
        // 0.4 is an approximation. Later when we're using deferred rendering, we can do this properly.
    
        output.rgb = lerp(output.rgb, farColor, t);
    }
    output.rgba *= Opacity; //for chunks that fade in
    clip(output.a - 0.1);
    return output;
}

Try changing:

float3 CamView : TEXCOORD2;
float4 posS : TEXCOORD3;

to this:

float3 CamView : TEXCOORD0;
float4 posS : TEXCOORD1;

Still crashes, on effect passes apply

It looks like it doesnt like when CamView float3, calculated from an float4. But im not sure how to fix that…

That is not an issue, it will get auto truncated.
If you do
position.xyz = position.xyzw
result will be same as
position.xyz = position.xyz

Multiple branching inside loop within shader is insanity, but it shouldnt cause the crash, some more details about crash? I would suggest you to start removing part of code, in fact start with basic VertexShader and PixelShader that just return float4(1,0,0,1) and see if that past, then readd your vertex shader and go from that point on.

On second though, if you are not using custom vertex declaration or simplified vertex declaration without UVcoords, add
float2 TexCoord : TEXCOORD0;
to vertex input… also are you sure that you are using vertex declaration where SV_Position is float4 and not float3? Is there chance you just commented off UV coords and changed input of SV_Position from float3 to float4 because this part:

mul(input.Position, world)
Didnt work? So you’ve done that instead of
mul(float4(input.Position,1), world); ?

Ive got the whole thing to run without crashes. The crashes happens on
customEffectGround.CurrentTechnique.Passes[0].Apply();
and it gives a null ref exception.
The “float3 CamView : TEXCOORD2;” must be a float4, or I get the crash.

The only issue left is that I can’t get the shadows to work, when debugging the “CamView” values they seem just random. It worked fine in XNA…

I gladly admit that I have no idea what I am doing :slight_smile:

PS. I use VertexPositionColor, so there is no UV

Current version, no crashes, but “PosWorld” values are wrong somehow:

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif


float4x4 wvp : WorldViewProjection;
float4x4 world : World;

#define FogStart 160
#define MaxShadows 8
#define DepthColor 0.01
#define MaxLightningStrength 0.7
#define MaxMagicLightStrength 0.3


int ShadowQty = 0;
float3 LightSourcePosition[MaxShadows];
float LightSourceRadius[MaxShadows];
int LightSourceType[MaxShadows];

float Opacity;

struct VS_IN
{
    float4 Position : SV_POSITION;
    float4 vcolor : COLOR0;
};
struct VS_OUT
{
    float4 Position : SV_POSITION;
    float4 PosWVP : TEXCOORD0;
    float4 PosWorld : TEXCOORD1;
    float4 vcolor : COLOR0;
    
};

VS_OUT VS_FlatVertexColored(VS_IN input)
{
    VS_OUT output = (VS_OUT)0;
    output.Position = mul(input.Position, wvp);
    output.PosWVP = mul(input.Position, wvp);
    output.vcolor = input.vcolor;
    output.PosWorld = mul(input.Position, world);
    return output;
}

float4 PS_VertexColoredWidthPointShadows(VS_OUT input) : COLOR0
{   
    //return input.PosWorld / 10000;
    float4 output = input.vcolor;

    for (int i = 0; i < ShadowQty; i++)
    {
        float3 shadowDist = LightSourcePosition[i] - input.PosWorld.xyz;
        if (LightSourceType[i] == 0)
        { //SHADOW
            shadowDist.y *= 0.5; //makes the shadows flatter
            float dist = length(shadowDist);
            dist /= LightSourceRadius[i];
            float colMultiply = 0.6 + dist * dist;

            if (colMultiply < 1)
            {
                output.rgb *= colMultiply;
            }

            
        }
        else if (LightSourceType[i] == 1)
        { //FIRE
            float dist = length(shadowDist);
            float strength = LightSourceRadius[i] - dist * dist;
            if (strength > 0)
            {
                output.r += 0.03 * strength;
                output.g += 0.006 * strength;
                output.b += 0.004 * strength;
            }
        }
        else if (LightSourceType[i] == 3)
        { //MAGIC LIGHT, has a bluegreen color
            float dist = length(shadowDist);
            float strength = 1 - (dist / LightSourceRadius[i]);
            if (strength > 0)
            {
                if (strength > MaxMagicLightStrength)  strength = MaxMagicLightStrength;

                output.r += 0.1 * strength;
                output.g += 0.6 * strength;
                output.b += strength;
            }
        }

    }

    //Fog effect
    if (input.PosWVP.z > FogStart)
    {
        float t = saturate((input.PosWVP.z - FogStart * 3) * 0.001f);
        float3 farColorMid = float3(0.20703125, 0.62745098039, 0.80392156862); // copied from BackgroundScenery.cs
        float3 farColorBtm = float3(0.8515625, 0.9375, 0.97265625); // copied from BackgroundScenery.cs
        float3 farColor = lerp(farColorBtm, farColorMid, 0.4);
        // 0.4 is an approximation. Later when we're using deferred rendering, we can do this properly.
    
        output.rgb = lerp(output.rgb, farColor, t);
    }
    output.rgba *= Opacity; //for chunks that fade in
    clip(output.a - 0.1);
    return output;
}

technique Flat
{
    pass Pass0
    {
        VertexShader = compile VS_SHADERMODEL VS_FlatVertexColored();
        PixelShader = compile PS_SHADERMODEL PS_VertexColoredWidthPointShadows();
    }
}