2017-12-05 6 views
0

Ich versuche, eine dicke gefütterte Sinus-Kurve mit diesem Ansatz zu ziehen: https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shaderHLSL Geometry Shader Dicke Linien DirectX

ich Port versucht, es zu HLSL Geometrie-Shader:

  • Einstellen der Dimension 500 zu beheben/500 atm
  • DICKE scheint das Problem nicht zu ändern
struct PSInput 
{ 
    float4 Position : SV_POSITION; 
}; 

float2 toScreenSpace(float4 vertex) 
{ 
    float2 WIN_SCALE = { 500.0f, 500.0f }; 
    return float2(vertex.xy/vertex.w) * WIN_SCALE; 
} 

[maxvertexcount(7)] 
void main(lineadj float4 vertices[4] : SV_POSITION, inout TriangleStream<PSInput> triStream) 
{ 
    float2 WIN_SCALE = { 500.0f, 500.0f }; 

    float2 p0 = toScreenSpace(vertices[0]); // start of previous segment 
    float2 p1 = toScreenSpace(vertices[1]); // end of previous segment, start of current segment 
    float2 p2 = toScreenSpace(vertices[2]); // end of current segment, start of next segment 
    float2 p3 = toScreenSpace(vertices[3]); // end of next segment 


    // perform naive culling 
    float2 area = WIN_SCALE * 1.2; 
    if (p1.x < -area.x || p1.x > area.x) 
     return; 
    if (p1.y < -area.y || p1.y > area.y) 
     return; 
    if (p2.x < -area.x || p2.x > area.x) 
     return; 
    if (p2.y < -area.y || p2.y > area.y) 
     return; 

    float2 v0 = normalize(p1 - p0); 
    float2 v1 = normalize(p2 - p1); 
    float2 v2 = normalize(p3 - p2); 

    // determine the normal of each of the 3 segments (previous, current, next) 
    float2 n0 = { -v0.y, v0.x}; 
    float2 n1 = { -v1.y, v1.x}; 
    float2 n2 = { -v2.y, v2.x}; 

    // determine miter lines by averaging the normals of the 2 segments 
    float2 miter_a = normalize(n0 + n1); // miter at start of current segment 
    float2 miter_b = normalize(n1 + n2); // miter at end of current segment 

    // determine the length of the miter by projecting it onto normal and then inverse it 
    float THICKNESS = 1; 
    float length_a = THICKNESS/dot(miter_a, n1); 
    float length_b = THICKNESS/dot(miter_b, n1); 

    float MITER_LIMIT = 0.75; 
    //float MITER_LIMIT = -1; 
    //float MITER_LIMIT = 0.1; 

    PSInput v; 
    float2 temp; 

    //// prevent excessively long miters at sharp corners 
    if (dot(v0, v1) < -MITER_LIMIT) 
    { 
     miter_a = n1; 
     length_a = THICKNESS; 

     // close the gap 
     if (dot(v0, n1) > 0) 
     { 
      temp = (p1 + THICKNESS * n0)/WIN_SCALE; 
      v.Position = float4(temp, 1.0, 1.0); 
      triStream.Append(v); 

      temp = (p1 + THICKNESS * n1)/WIN_SCALE; 
      v.Position = float4(temp, 1.0, 1.0); 
      triStream.Append(v); 

      v.Position = float4(p1/WIN_SCALE, 1.0, 1.0); 
      triStream.Append(v); 

      //triStream.RestartStrip(); 

     } 
     else 
     { 
      temp = (p1 - THICKNESS * n1)/WIN_SCALE; 
      v.Position = float4(temp, 1.0, 1.0); 
      triStream.Append(v); 

      temp = (p1 - THICKNESS * n0)/WIN_SCALE; 
      v.Position = float4(temp, 1.0, 1.0); 
      triStream.Append(v); 

      v.Position = float4(p1/WIN_SCALE, 1.0, 1.0); 
      triStream.Append(v); 

      //triStream.RestartStrip(); 
     } 
    } 

    if (dot(v1, v2) < -MITER_LIMIT) 
    { 
     miter_b = n1; 
     length_b = THICKNESS; 
    } 

    // generate the triangle strip 
    temp = (p1 + length_a * miter_a)/WIN_SCALE; 
    v.Position = float4(temp, 1.0, 1.0); 
    triStream.Append(v); 

    temp = (p1 - length_a * miter_a)/WIN_SCALE; 
    v.Position = float4(temp, 1.0, 1.0); 
    triStream.Append(v); 

    temp = (p2 + length_b * miter_b)/WIN_SCALE; 
    v.Position = float4(temp, 1.0, 1.0); 
    triStream.Append(v); 

    temp = (p2 - length_b * miter_b)/WIN_SCALE; 
    v.Position = float4(temp, 1.0, 1.0); 
    triStream.Append(v); 

    //triStream.RestartStrip(); 

} 

Das Ding ist, dass es nichts der Kurve ausgeben wird, die ich als Punkte ihm gebe. Es funktioniert schon sehr gut ohne dicke Linien, aber ich will das haben. Ich kann Rauschen zu meinem Sinussignal hinzufügen, und wenn ich das tue, (y-Werte steigen um ein kleines zufälliges%) plötzlich erscheint die Kurve und ist dicker und scheint zu funktionieren, aber ich möchte, dass sie dick ist und auch ohne Rauschen zeigt .

Wenn ich die Frequenz, ohne Rauschen, Punkt erscheint verstreut-Plot-Stil, aber nicht als eine verbundene Sinus.

Wenn ich mit dem VS Graphics Debugger debugge, kann ich sehen, dass in dem Frame ohne Noise die Pixel-Shader-Stage nicht ausgeführt wird (?). Der Rahmen mit Lärm zeigt es laufen und arbeiten.

Vielleicht ist meine Portierung falsch und ich vergesse etwas, ich bin sehr neu in der Programmierung von Shadern. Vielleicht verstehe ich den Ansatz überhaupt nicht.

Jede Hilfe wird geschätzt.

Antwort

0

Ich musste das Standardverhalten des Culling zu CullMode.None festlegen, um alle das Dreieck gezeichnet zu erhalten.

Verwandte Themen