我正在使用Xcode14.2开发一个iOS应用,而我的部署目标是iOS16.2,我有一个X、Y、Z值的列表,我想使用lineStrip用Metal绘制这些值,这样就可以了,不过这条线对我的目的来说太细了。我读过关于如何加粗这条线的各种策略,我我决定尝试绘制同一条线多次迭代,每次使用少量的噪声,以给予线看起来更粗。
我每次通过渲染循环生成3个随机浮点数,并将它们发送到我的顶点着色器,问题是,结果线似乎比随机更周期性,更多的迭代似乎并没有给予更粗的线的外观。
如何使用此策略绘制较粗的线条?
第一节第一节第一节第一节第一次
绘制多个迭代:
// Draw many iterations
for iteration in 1...1024 {
scene.track?.draw(encoder: commandEncoder,
modelMatrix: accumulatedRotationMatrix,
projectionMatrix: projectionMatrix * viewMatrix,
secondsInEpoch: Float(self.epochTime))
}
随机浮动:
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)
顶点均匀:
struct VertexUniforms {
var viewProjectionMatrix: float4x4
var modelMatrix: float4x4
var normalMatrix: float3x3
var jitterX: Float
var jitterY: Float
var jitterZ: Float
var iteration: Float
}
绘制基本体调用:
encoder.drawPrimitives(type: .lineStrip , vertexStart: 0, vertexCount: vertices.count / 3)
顶点着色器:
// 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;
1条答案
按热度按时间41zrol4v1#
要生成较粗的线,您可以:
triangleStrip
而不是lineStrip
。你需要记住,金属线是一个像素厚。因此,对于每一个额外的像素线厚度,你将需要一个新的,直接相邻的线。而不是依赖于随机性,我会简单地增加/减少一个像素的线,在每次迭代,在一种垂直于线的方向。我也会使迭代的数量视屏幕大小而定。
你可以将迭代次数设置为屏幕宽度或高度(取决于线条是垂直还是水平)除以所需的线条厚度。你也可以将像素大小(屏幕大小的1倍)传递给顶点着色器,在那里你将通过像素大小乘以所讨论的线条的迭代次数来偏移线条。
或者,您可以放弃绘制
lineStrip
的想法,而是绘制triangleStrip
。这种解决方案可能比以略微不同的偏移量绘制大量线条更有效。为了实现这个,你需要复制这条线上的每个顶点(额外的一条线,而不是无数条线),并在垂直于线本身的方向上将其偏移所需的厚度。然后你需要调用
drawPrimitives()
,使用type: .triangleStrip
而不是type: .lineStrip
。新的顶点将与旧的顶点交错,而不是在它们之后。