2023-03-26

Apple Metal lineStrip how to draw thicker lines

I am developing an iOS application using XCode 14.2, and my deployment target is iOS 16.2. I have a list of X,Y, and Z values that I want to draw with Metal using lineSrip. This works, however the line that is drawn is too thin for my purposes. I've read about various strategies on how to thicken the line and I've decided to attempt to draw the same line many iterations with a small amount of noise each time to give the appearance of a thicker line.

I generate 3 random floats each time through the render loop and send them to my vertex shader with a uniform. The issue is that the resulting line seems to be more periodic than random and more iterations does not seem to give the appearance of a thicker line.

How can I draw thicker lines using this strategy? Thank you.

enter image description here enter image description here

Draw many iterations:

// Draw many iterations
for iteration in 1...1024 {
    scene.track?.draw(encoder: commandEncoder,
                      modelMatrix: accumulatedRotationMatrix,
                      projectionMatrix: projectionMatrix * viewMatrix,
                      secondsInEpoch: Float(self.epochTime))
}

Random floats:

var jitter = 1.0 / Float(self.screenSizeX) - 1 / Float(self.screenSizeY)
var jitterX = Float.random(in: -jitter...jitter)
var jitterY = Float.random(in: -jitter...jitter)
var jitterZ = Float.random(in: -jitter...jitter)

Vertex Uniform:

struct VertexUniforms {
    
    var viewProjectionMatrix: float4x4
    var modelMatrix: float4x4
    var normalMatrix: float3x3
    var jitterX: Float
    var jitterY: Float
    var jitterZ: Float
    var iteration: Float
}

Draw primitives call:

encoder.drawPrimitives(type: .lineStrip , vertexStart: 0, vertexCount: vertices.count / 3)

Vertex shader:

// Calculate the jitter for X/Y/Z
//float subFactor = 0.0099;
float subFactor = 0.0105;
float smallFactorX = (subFactor * uniforms.jitterX);
float smallFactorY = (subFactor * uniforms.jitterY);
float smallFactorZ = (subFactor * uniforms.jitterZ);
if (vertexId % 2 == 0) {
    vertexOut.position.x += (vertexOut.position.x * smallFactorX);
    vertexOut.position.y += (vertexOut.position.y * smallFactorY);
    vertexOut.position.z += (vertexOut.position.z * smallFactorZ);
} else {
    vertexOut.position.x -= (vertexOut.position.x * smallFactorX);
    vertexOut.position.y -= (vertexOut.position.y * smallFactorY);
    vertexOut.position.z -= (vertexOut.position.z * smallFactorZ);
}

return vertexOut;


No comments:

Post a Comment