Question : vertex id

im new to shader language. Plan to implement this source in monogame. Is anyone can tell me wat is the purpose of
“uint fakeIndex : SV_VERTEXID”

Source code

Can’t say for sure but i usually use the index when i use it or if i use it.
For rotation or placement schemes on the shader for specific algorithmic motion effects.
So i don’t have to pass a full matrix and or update it.
Basically if each quad has its own id and they are incremented as you add them then you can multiply them or divide them or modulus them by some value, frac them pass in some additional time value ect… Then apply that as radians or a positioning index to do some effect fairly common with particles.

I imagine he is doing something similar by his notes.

Here is one of my instanced shaders were you can see im sort of doing the same thing.
As you can see there is very little data passed this way.

#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
#define PS_SHADERMODEL ps_4_0
#endif

//_________________________________________________________________
//__________________________ the gl shader_________________________
//_________________________________________________________________

static const float PI = 3.14159;
static const float PI2 = 6.28318;
static const float EIGHT_PI = 25.13274;

//float Life;
float TotalTime;
matrix WorldViewProjection;

float4 StartColor0;
float4 StartColor1;
float4 EndColor0;
float4 EndColor1;

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

//__________________________________________________________

struct VSInstanceInputSimple
{
    float3 InstancePosition : POSITION1;  // the number used must match the vertex declaration.
    float InstanceTimeOrId : BLENDWEIGHT0;
};

struct VSVertexInputSimple
{
    float4 Position : POSITION0;//SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    //uint InstanceId : SV_InstanceId;
};

struct VSOutputSimple
{
    float4 Position : SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    float4 Color : COLOR0;
};

VSOutputSimple MainVSSimple(in VSVertexInputSimple vertexInput, VSInstanceInputSimple instanceInput)
{
    VSOutputSimple output;
    output.TexCoord = vertexInput.TexCoord;
    float3 InstancePosition = instanceInput.InstancePosition;
    float InstanceTimeOrId = instanceInput.InstanceTimeOrId;
    float movingTime = InstanceTimeOrId * TotalTime + TotalTime;
    float4 posVert = mul(vertexInput.Position, WorldViewProjection);
    float4 posInst = mul(InstancePosition.xyz, WorldViewProjection);
    float4 pos = posVert + posInst;
    output.Position = pos;
    //
    // comment the below for a visual sanity in 2d proper
    // uncomment the below line for trippy 4d 
    //
    //output.Position = pos * sin(movingTime  * PI2);
    //
    output.Position.x = pos.x * cos(movingTime * PI2) - pos.y * sin(movingTime * PI2);
    output.Position.y = pos.x * sin(movingTime * PI2) + pos.y * cos(movingTime * PI2);
    // change color
    float4 startColor = lerp(StartColor0, StartColor1, InstancePosition.x);
    float4 endColor = lerp(EndColor0, EndColor1, InstancePosition.y);
    output.Color = lerp(startColor, endColor, (InstancePosition.z + InstanceTimeOrId));
    return output;
}

float4 MainPSSimple(VSOutputSimple input) : COLOR0
{
    float4 col = input.Color * tex2D(TexSampler, input.TexCoord);
    // straight clip alpha draws
    clip(col.a - .05f);
    return col;
}

technique ParticleDrawingSimple
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL MainVSSimple();
        PixelShader = compile PS_SHADERMODEL MainPSSimple();
    }
};

it eventually spins up to look like a galaxy rotating and each individual particle is doesn’t need to be continually updated with a position just a single time variable at the start of each frame is incremented.

Here is a full example project not sure if its using the same shader or just with the other option.

1 Like

SV_VERTEXID generate by pipeline for each vertex
new drawcall reset to 0
for ex:
VertexPosition[] vertices = new VertexPosition[60];

//same for vertexbuffer
GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length);
//SV_VERTEXID will be 0-59
GraphicsDevice.Draw…//SV_VERTEXID reset to 0

next
// bypass the geometry shader, and instead expand the particle here in the VS:
kind of software instancing…
uint vertexID = fakeIndex % 6; //in this case use to determine position of vertex(0-5)
uint instanceID = fakeIndex / 6; //each instance have 6 vertices

1 Like