NAKASSEIN
NAKASSEIN

Reputation: 45

Inputs and Outputs of the Geometry Shader

I was wondering if anyone would be so kind as to pin-point the problem with my program. I am certain the setback has something to do with the way in which data is passed through the GS. If, for instance, the geometry shader is taken out of the code (modifying the other two stages to accommodate for the change as well), I end up with a operational pipeline. And if I modify the data input of the GS to accept PS_INPUT instead of VS_DATA, the program does not crash, but outputs a blank blue screen. My intent here is to create a collection of squares on a two-dimensional plane, so blank blue screens are not exactly what I am going for.

Texture2D txDiffuse[26] : register(t0);
SamplerState samLinear : register(s0); //For Texturing

#define AWR_MAX_SHADE_LAY 1024

cbuffer ConstantBuffer : register(b0)
{
    float4 Matrix_Array[30];
    matrix Screen;
    float GM;
    float GA;
    float GD;
    float epsilon;
}
// Includes Layer Data
cbuffer CBLayer : register(b1)
{
    float4 Array_Fill_Color[AWR_MAX_SHADE_LAY];
    float4 Array_Line_Color[AWR_MAX_SHADE_LAY];
    float Array_Width[AWR_MAX_SHADE_LAY];
    float Array_Line_Pattern[AWR_MAX_SHADE_LAY];
    float Array_Z[AWR_MAX_SHADE_LAY];
    float Array_Thickness[AWR_MAX_SHADE_LAY];
}

//Input for Vertex Shader
struct VS_DATA
{
    float4 Pos : POSITION;
    int M2W_index : M2W_INDEX;
    int Layer_index : LAYER_INDEX;
};

//Input for Pixel Shader
struct PS_INPUT{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
    int Layer_index : LAYER_INDEX;
};

//Vertex Shader
VS_DATA VS(VS_DATA input)// Vertex Shader
{
    VS_DATA output = (VS_DATA)0;
    //Model to World Transform
    float xm = input.Pos.x, yw = input.Pos.y, zm = input.Pos.z, ww = input.Pos.w, xw, zw;
    float4 transformation = Matrix_Array[input.M2W_index];
    xw = ((xm)*transformation.y - (zm)*transformation.x) + transformation.z;
    zw = ((xm)*transformation.x + (zm)*transformation.y) + transformation.w;

    //set color
    int valid_index = input.Layer_index;
    output.Color = Array_Fill_Color[valid_index];
    output.Color.a = 0.0;

    //output.Vertex_index = input.Vertex_index;
    //output.Next_Vertex_index = input.Next_Vertex_index;

    //Snapping process
    float sgn_x = (xw >= 0) ? 1.0 : -1.0;                   
    float sgn_z = (zw >= 0) ? 1.0 : -1.0;
    int floored_x = (int)((xw + (sgn_x*GA) + epsilon)*GD);
    int floored_z = (int)((zw + (sgn_z*GA) + epsilon)*GD);
    output.Pos.x = ((float)floored_x)*GM;
    output.Pos.y = yw;
    output.Pos.z = ((float)floored_z)*GM;
    output.Pos.w = ww;

    int another_valid_index = input.Layer_index;
    output.Layer_index = another_valid_index;

    // Transform to Screen Space
    output.Pos = mul(output.Pos, Screen);

    return output;
}


[maxvertexcount(6)]
void GS_Line(line VS_DATA points[2], inout TriangleStream<PS_INPUT> output)
{
    float4 p0 = points[0].Pos;
    float4 p1 = points[1].Pos;

    float w0 = p0.w;
    float w1 = p1.w;

    p0.xyz /= p0.w;
    p1.xyz /= p1.w;

    float3 line01 = p1 - p0;
    float3 dir = normalize(line01);

    float3 ratio = float3(700.0, 0.0, 700.0);
    ratio = normalize(ratio);

    float3 unit_z = normalize(float3(0.0, -1.0, 0.0));

    float3 normal = normalize(cross(unit_z, dir) * ratio);
    float width = 0.01;

    PS_INPUT v[4];

    float3 dir_offset = dir * ratio * width;
    float3 normal_scaled = normal * ratio * width;

    float3 p0_ex = p0 - dir_offset;
    float3 p1_ex = p1 + dir_offset;

    v[0].Pos = float4(p0_ex - normal_scaled, 1) * w0;
    v[0].Color = float4(1.0, 1.0, 1.0, 1.0);
    v[0].Layer_index = 1;

    v[1].Pos = float4(p0_ex + normal_scaled, 1) * w0;
    v[1].Color = float4(1.0, 1.0, 1.0, 1.0);
    v[1].Layer_index = 1;

    v[2].Pos = float4(p1_ex + normal_scaled, 1) * w1;
    v[2].Color = float4(1.0, 1.0, 1.0, 1.0);
    v[2].Layer_index = 1;

    v[3].Pos = float4(p1_ex - normal_scaled, 1) * w1;
    v[3].Color = float4(1.0, 1.0, 1.0, 1.0);
    v[3].Layer_index = 1;

    output.Append(v[2]);
    output.Append(v[1]);
    output.Append(v[0]);

    output.RestartStrip();

    output.Append(v[3]);
    output.Append(v[2]);
    output.Append(v[0]);

    output.RestartStrip();
}

//Pixel Shader
float4 PS(PS_INPUT input) : SV_Target{
    float2 Tex = float2(input.Pos.x / (8.0), input.Pos.y / (8.0));
    int the_index = input.Layer_index;

    float4 tex0 = txDiffuse[25].Sample(samLinear, Tex);
        if (tex0.r > 0.0)
            tex0 = float4(1.0, 1.0, 1.0, 1.0);
        else
            tex0 = float4(0.0, 0.0, 0.0, 0.0);
    if (tex0.r == 0.0)
        discard;
    tex0 *= input.Color;
    return tex0;
}

Upvotes: 1

Views: 1260

Answers (1)

mrvux
mrvux

Reputation: 8963

If you compile your vertex shader as it is, you will have the following error :

(line 53) : invalid subscript 'Color'

output.Color = Array_Fill_Color[valid_index];

output is of type VS_DATA which does not contain color.

If you change your VS definition as :

PS_INPUT VS(VS_DATA input)// Vertex Shader
{
    PS_INPUT output = (PS_INPUT)0;
    //rest of the code here

Then your vs will compile, but then you will have a mismatched layout with GS (GS still expects a line of VS_DATA as input, and now you provide PS_INPUT to it) This will not give you any error until you draw (and generally runtime will silently fail, you would have a mismatch message in case debug layer is on)

So you also need to modify your GS to accept PS_INPUT as input eg:

[maxvertexcount(6)]
void GS_Line(line PS_INPUT points[2], inout TriangleStream<PS_INPUT> output)

Upvotes: 1

Related Questions