pixel shader problem [solved][example]

Im on win 7 vs 2017 using the gl based template.

Im trying to do my specular lighting on the pixel shader instead of in the vertice shader were it gives artifacts i put this on the backburner for a long time but picked it up.

… however … i need a some help.

Im having a problem getting a normal to the pixel shader. Im getting a crash if i try to use it at all, it just exits monogame or tells me the vertice element data is the wrong size?. If i don’t access it in the pixel shader and just do the calculations on the vertice shader, it runs. Even if i just get one element of the normal and try to use it in the pixels shader the app crashes ?.

What am i doing wrong here.

// ok so this crashes monogame in my pixel shader why ?
,
float4 ncol = tex2D(TextureSamplerA, input.TexureCoordinateA);
float3 norm = input.Normal;
float avar = norm.x;
ncol = avar * ncol;
output.Color = ncol;

here is a full example.

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

//_______________________________________________________________
// common
//_______________________________________________________________
bool     displayVertexNormalShading;
float    alphaDiscardThreshold;
float3   lightDir;
float4   lightColor;
float    specularSharpness;
float    specularPercentage;
float    ambientColor;

float4 cameraForward;
float4x4 gworld;
//float4x4 gview;
//float4x4 gprojection;
float4x4 gworldviewprojection;

Texture2D TextureA;
sampler2D TextureSamplerA = sampler_state
{
    Texture = <TextureA>;
    //AddressU = Wrap;
    //AddressV = Wrap;
    //MinFilter = Anisotropic;
    //MagFilter = Anisotropic;
    //MipFilter = Point;
};

//_______________________________________________________________
// structs TechniqueC
//_______________________________________________________________
struct VertexShaderInputC
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float4 Color : COLOR0;
    float2 TexureCoordinateA : TEXCOORD0;
};
struct VertexShaderOutputC
{
    float4 Position : SV_Position;
    float3 Normal : NORMAL0;
    float4 Color : COLOR0;
    float2 TexureCoordinateA : TEXCOORD0;
};
struct PixelShaderOutputC
{
    float4 Color : COLOR0;
};
//______________________________________________________________
// shader techniques TechniqueC
//______________________________________________________________

VertexShaderOutputC VertexShaderFunctionC(VertexShaderInputC input)
{
    VertexShaderOutputC output;
    output.Position = mul(input.Position, gworldviewprojection);
    output.Color = input.Color;
    output.TexureCoordinateA = input.TexureCoordinateA;
    output.Normal = input.Normal;
    return output;
}
PixelShaderOutputC PixelShaderFunctionC(VertexShaderOutputC input)
{
    PixelShaderOutputC output;
    float4 ncol = tex2D(TextureSamplerA, input.TexureCoordinateA) *input.Color;

    // ok so this crashes monogame how why ?
    float3 norm = input.Normal;
    float avar = norm.x;
    ncol = avar * ncol;
    // 
    
    output.Color = ncol;
    // just display vertex normal shading
    if (displayVertexNormalShading)
    {
        float4 mixedcol = (input.Color *.5) + (ncol *.5);
        output.Color = mixedcol;
    }
    return output;
}

technique TechniqueC
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL VertexShaderFunctionC();
        PixelShader = compile PS_SHADERMODEL PixelShaderFunctionC();
    }
}

don’t know what cause
but change semantic and it work

     struct VertexShaderOutputC
     {
        float4 Position : SV_Position;
        float3 Normal : TEXCOORD1;//
        float4 Color : COLOR0;
        float2 TexureCoordinateA : TEXCOORD0;
     };

look like it can’t recognize some semantics in ps

Wow i spent a entire day trying to figure out how to get it to work and even narrowing down the problem the original shader is much more complex. You are the best pumpkin in the entire patch lol.

Now the questions…
Why wont Normal0 work for a Normal but a second Texcoord1 will ?
Will the vertice shader still interpolate properly between these normal vertices ? ill find out.
How does this even work when i have defined it as a normal in the vertex declaration ?
So should i report this as a issue on github ?

DX9/10 docs say that NORMAL[n] is treated only as input semantics.
Here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx#VS

yes it does.

How does this even work when i have defined it as a normal in the vertex declaration ?

your vertexdeclaration goes for vs as it efine VertexShaderInputC
but change semantic for ps so it ok.

Well there we go

Re edit…
I spend a good amount of time editing this and improving it today. Here it is if anyone wants to give it a try. This version lets you set the amount of diffuse specular or ambiance as a percentage.

The color im passing in is going to be used for a later transparency experiment on individual polygons.

,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

//_______________________________________________________________
// common
//_______________________________________________________________
bool     displayVertexNormalShading;
//float    alphaDiscardThreshold;
float3   lightDir;
float4   lightColor;
float    specularSharpness;
float    specularInfluence;
float    diffuseInfluence;
float    ambientInfluence;
float4   ambientColor;
float4   cameraForward;
float4x4 gworld;
//float4x4 gview;
//float4x4 gprojection;
float4x4 gworldviewprojection;

Texture2D TextureA;
sampler2D TextureSamplerA = sampler_state
{
    Texture = <TextureA>;
    //AddressU = Wrap;
    //AddressV = Wrap;
    //MinFilter = Anisotropic;
    //MagFilter = Anisotropic;
    //MipFilter = Point;
};
//_______________________________________________________________
// structs ShaderLightingA
//_______________________________________________________________
struct VertexShaderInputC
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float4 Color : COLOR0;
    float2 TexureCoordinateA : TEXCOORD0;
};
struct VertexShaderOutputC
{
    float4 Position : SV_Position;
    float3 Normal : TEXCOORD1;// removed cause it didn't work  NORMAL0;
    float4 Color : COLOR0;
    float2 TexureCoordinateA : TEXCOORD0;
};
struct PixelShaderOutputC
{
    float4 Color : COLOR0;
};
//______________________________________________________________
// shader techniques ShaderLightingA
//______________________________________________________________
VertexShaderOutputC VertexShaderFunctionC(VertexShaderInputC input)
{
    VertexShaderOutputC output;
    output.Position = mul(input.Position, gworldviewprojection); //  * input.Color;
    output.Color = input.Color;
    output.TexureCoordinateA = input.TexureCoordinateA;
    output.Normal = input.Normal;
    return output;
}

PixelShaderOutputC PixelShaderFunctionC(VertexShaderOutputC input)
{
    PixelShaderOutputC output;
    float4 texelcolor = tex2D(TextureSamplerA, input.TexureCoordinateA);// *input.Color;
    float4 vertcolor = input.Color;
    //
    float3 V_normal = normalize(mul(input.Normal, (float3x3)gworld)); //world space normal
    // diffuse theta
    float LtoV_diffuseTheta = saturate(dot(V_normal, -lightDir));
    
    // specular reflect vector theta and power 
    float3 LtoV_reflectVector = reflect(lightDir, V_normal);
    float LtoE_specularTheta = saturate(dot(cameraForward, -LtoV_reflectVector));
    float specularResult = saturate(pow(LtoE_specularTheta, specularSharpness));

    float4 additiveAmbient = (texelcolor * ambientColor) * ambientInfluence;
    float4 additiveDiffuse = (texelcolor * lightColor) * LtoV_diffuseTheta * diffuseInfluence;
    float4 additiveSpecular = (texelcolor * lightColor) * specularResult * specularInfluence;
    //_____________blend____________________
    float4 result = additiveAmbient + additiveDiffuse + additiveSpecular;

    //____________finalize__________________
    result.a = input.Color.a;
    output.Color = result;
    //__just display vertex normal shading__
    if (displayVertexNormalShading)
    {
        float4 result = float4(1, 1, 1, 1);
        //result *= vertcolor;
        //result *= LtoE_specularTheta;
        //result *= specularResult;
        //result *= LtoV_diffuseTheta;
        //result *= ((LtoV_diffuseTheta * diffuseInfluence) + (specularResult * specularInfluence));
        result = ((float4(0, 0, 1, 1) * LtoV_diffuseTheta * diffuseInfluence) + (float4(1, 0, 0, 1) * specularResult * specularInfluence));
        //____________________
        result.a = input.Color.a;
        output.Color = result;
    }
    return output;
}
technique ShaderLightingA
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL VertexShaderFunctionC();
        PixelShader = compile PS_SHADERMODEL PixelShaderFunctionC();
    }
}