I want to draw large width lines using triangular primitives. As the number of vertices rises, the frame rate goes down sharply.The following code is the way to draw primitive and the shader.
Vertex structure
struct Point { var position:float2 var color:float4 init() { position = float2(0, 0) color = float4(0,0,0,0) } init(position:float2,color:float4) { self.position = position self.color = color } } struct Line { var begin:Point var end:Point }
Draw method
commandEncoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: (size - 1) * 4 , instanceCount: size - 1)
Shader code
#include <metal_stdlib>
using namespace metal;
struct InputVertex {
float2 position;
float4 color;
};
struct Vertex {
float4 position [[position]];
float4 color;
};
struct Point
{
float2 position;
float4 color;
};
struct Line
{
Point begin;
Point end;
};
struct XCoord
{
float beginX ;
float endX ;
float leftX ;
float rightX ;
float x;
};
struct Uniforms {
float4x4 modelMatrix;
};
vertex Vertex vertex_func(constant Line *lines [[buffer(0)]],
constant Uniforms &uniforms [[buffer(1)]],
uint vertexId [[vertex_id]],
uint instanceId [[instance_id]]) {
float4x4 matrix = uniforms.modelMatrix;
float thickness = 0.004;
Line line = lines[instanceId];
uint index = vertexId % 4;
float4 startPosition = matrix * float4(line.begin.position.x,line.begin.position.y ,0 ,1);
float4 endPosition = matrix * float4(line.end.position.x,line.end.position.y ,0 ,1);
float4 position;
float4 color;
float4 v = endPosition - startPosition;
float2 p0 = float2(startPosition.x,startPosition.y);
float2 v0 = float2(v.x,v.y);
float2 v1 = thickness * normalize(v0) * float2x2(float2(0,-1),float2(1,0));
if (index == 0)
{
float2 pa = p0 + v1;
position = float4(pa.x,pa.y,0,1);
color = line.begin.color;
}
else if (index == 1)
{
float2 pb = p0 - v1;
position = float4(pb.x,pb.y,0,1);
color = line.begin.color;
}
else if (index == 2)
{
float2 pc = p0 - v1 + v0;
position = float4(pc.x,pc.y,0,1);
color = line.end.color;
}
else if (index == 3)
{
float2 pd = p0 + v1 + v0;
position = float4(pd.x,pd.y,0,1);
color = line.end.color;
}
else
{
float2 pd = p0 + v1 + v0;
position = float4(pd.x,pd.y,0,1);
color = line.end.color;
}
Vertex out;
out.position = position;
out.color = color;
return out;
}
fragment float4 fragment_func(Vertex vert [[stage_in]]) {
return vert.color;
}
Hello
Sorry for delay. Alas, I was not able of running this - I have older Xcode, and currently running urgent projects for client, so cannot reinstall that. But I think I know what is the problem. You invoke drawing like that:
commandEncoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: (size - 1) * 4 , instanceCount: size - 1)
And this is not what you want. If you want instancing of line segments, drawn as quads (4 vertex triangle strips) then you really should invoke your code with vertexCount: 4, not (size - 1) * 4. By doing what you do, you basically do O(n^2) instead of O(n) work (assuming single line strip drawing is O(1)). So for size = 51 like it is set now, you do basically 50 times the work you really want to do.
Hope that helps
Michal