struct VertexShaderInput
{
float3 Position : POSITION0;
float4 Color : COLOR0;
};
struct VertexShaderOutput
{
float4 Position : SV_POSITION;
float4 Color : COLOR0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
output.Color = input.Color;
output.Position = float4(input.Position,1);
return output;
}
That is how it should be.
Input does not take SV_POSITION it has to be POSITION0 and must be first in struct same with output, SV_POSITION not SV_POSITION0 and it must be first in the struct.
If u look at the vertex struct in C# it has to match the one in HLSL.
I'm not sure if this will work in mono game but if u are talking full screen quad then u can do it like this:
don't set a vb or ib or inputlayout, call context.draw(3) and have the vertex shader like this...
// outputs a full screen triangle with screen-space coordinates
// input: three empty vertices
VertexShaderOutput VSQuad(uint vertexID : SV_VertexID)
{
VertexShaderOutput result;
result.TexCoord = float2((vertexID << 1) & 2, vertexID & 2);
result.Position = float4(result.TexCoord * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
return result;
}
I would have color set as a const so u can set it from C# per object
Edit: The name of the vertex element does not match the vertex input because in mono game on the back end the elements would look something like this:
Public Shared VertexElements As InputElement() = New InputElement() {New InputElement("POSITION", 0, DXGI.Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0),
New InputElement("NORMAL", 0, DXGI.Format.R32G32B32_Float, InputElement.AppendAligned, 0, InputClassification.PerVertexData, 0),
New InputElement("TEXCOORD", 0, DXGI.Format.R32G32_Float, InputElement.AppendAligned, 0, InputClassification.PerVertexData, 0)
}
Notice how the name of POSITION not SV_POSITION in XNA it didn't matter how u did ur vertex structs the runtime would sort it out but now all names must match so if you put SV_ in your shader it want match if u decompile the backend I'm sure it will look something like what I posted because that is how u do it in sharp dx.
But I don't even do it like that anymore because input layout building sucks by hand so I wrote this:
Private Function InputLayoutBuilder(_shader As ShaderBytecode) As InputLayout
Dim blah As New ShaderReflection(_shader)
Dim Elements As New List(Of InputElement)
For i As Integer = 0 To blah.Description.InputParameters - 1
Dim nnn As ShaderParameterDescription = blah.GetInputParameterDescription(i)
If nnn.SemanticName.Contains("SV_") Then
Continue For
End If
Dim _InputElement As New InputElement
Dim format As New DXGI.Format
_InputElement.SemanticName = nnn.SemanticName
_InputElement.SemanticIndex = nnn.SemanticIndex
_InputElement.Slot = nnn.Stream
_InputElement.InstanceDataStepRate = 0
If i = 0 Then
_InputElement.AlignedByteOffset = 0
Else
_InputElement.AlignedByteOffset = InputElement.AppendAligned
End If
If nnn.SemanticName = "WORLD" Then
_InputElement.Slot = 1
If nnn.SemanticIndex = 0 Then
_InputElement.AlignedByteOffset = 0
Else
_InputElement.AlignedByteOffset = InputElement.AppendAligned
End If
_InputElement.InstanceDataStepRate = 1
_InputElement.Classification = InputClassification.PerInstanceData
Else
_InputElement.InstanceDataStepRate = 0
_InputElement.Classification = InputClassification.PerVertexData
End If
If nnn.SemanticName = "SHID" Then
_InputElement.Slot = 1
_InputElement.AlignedByteOffset = InputElement.AppendAligned
_InputElement.InstanceDataStepRate = 1
_InputElement.Classification = InputClassification.PerInstanceData
End If
If nnn.UsageMask = 1 Then
If nnn.ComponentType = RegisterComponentType.UInt32 Then
_InputElement.Format = Format.R32_UInt
ElseIf nnn.ComponentType = RegisterComponentType.SInt32 Then
_InputElement.Format = Format.R32_SInt
ElseIf nnn.ComponentType = RegisterComponentType.Float32 Then
_InputElement.Format = Format.R32_Float
End If
ElseIf nnn.UsageMask <= 3 Then
If nnn.ComponentType = RegisterComponentType.UInt32 Then
_InputElement.Format = Format.R32G32_UInt
ElseIf nnn.ComponentType = RegisterComponentType.SInt32 Then
_InputElement.Format = Format.R32G32_SInt
ElseIf nnn.ComponentType = RegisterComponentType.Float32 Then
_InputElement.Format = Format.R32G32_Float
End If
ElseIf nnn.UsageMask <= 7 Then
If nnn.ComponentType = RegisterComponentType.UInt32 Then
_InputElement.Format = Format.R32G32B32_UInt
ElseIf nnn.ComponentType = RegisterComponentType.SInt32 Then
_InputElement.Format = Format.R32G32B32_SInt
ElseIf nnn.ComponentType = RegisterComponentType.Float32 Then
_InputElement.Format = Format.R32G32B32_Float
End If
ElseIf nnn.UsageMask <= 15 Then
If nnn.ComponentType = RegisterComponentType.UInt32 Then
_InputElement.Format = Format.R32G32B32A32_UInt
ElseIf nnn.ComponentType = RegisterComponentType.SInt32 Then
_InputElement.Format = Format.R32G32B32A32_SInt
ElseIf nnn.ComponentType = RegisterComponentType.Float32 Then
_InputElement.Format = Format.R32G32B32A32_Float
End If
End If
Elements.Add(_InputElement)
Next
If Elements.Count > 0 Then
Dim newinputlayout As New InputLayout(MainDevice, _shader, Elements.ToArray)
blah.Dispose()
Return newinputlayout
Else
Return Nothing
End If
End Function
That will pull it all out of the shader and spit out an input layout no need to do it by hand just set in your shader and let this do the rest it also checks for a WORLD tag so u can pass a world matrix to the vertex shader for instancing. Mono game may let you get at all that stuff but it may be hidden under all there abstraction but that bit of code saves all this tweaking for different input strucs.
Try this:
Texture2D colorMap;
sampler colorSampler = sampler_state
{
AddressU = Clamp;
AddressV = Clamp;
Filter = MIN_MAG_MIP_POINT;
};
struct VertexShaderOutput
{
float4 Position : SV_Position;
float2 TexCoord : TEXCOORD0;
};
struct PixelShaderOutput
{
float4 Color : SV_Target0;
};
// outputs a full screen triangle with screen-space coordinates
// input: three empty vertices
VertexShaderOutput VSQuad( uint vertexID : SV_VertexID )
{
VertexShaderOutput result;
result.TexCoord = float2((vertexID << 1) & 2, vertexID & 2);
result.Position = float4(result.TexCoord * float2(2.0f, -2.0f) + float2 -1.0f, 1.0f), 0.0f, 1.0f);
return result;
}
PixelShaderOutput PShader(VertexShaderOutput input)
{
PixelShaderOutput output = (PixelShaderOutput)1;
float4 Color = colorMap.Sample(colorSampler, input.TexCoord);
output.Color =Color;
output.Color.a=1;
return output;
}
technique11 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VSQuad() ) );
SetPixelShader( CompileShader( ps_5_0, PShader() ) );
}
}