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.