带有可变参数的 Metal Shader 函数,从 SwiftUI 调用?

问题描述 投票:0回答:1

我的应用程序需要在 SwiftUI

View
中渲染场强,即为
View
的每个点分配具有坐标相关不透明度的颜色。
这可以使用 Canvas 来完成,如here所述,但这非常慢。 使用金属着色器要快得多,如此处所述。

为了渲染点场,我使用这个 Metal 函数:

[[ stitchable ]] half4 pointField(float2 position, half4 currentColor, float2 center, half4 newColor) {
    // Compute distance center - position
    float x = position.x;
    float y = position.y;
    float xDistance = center.x - x;
    float yDistance = center.y - y;
    float d = sqrt(xDistance * xDistance + yDistance * yDistance);
    float r = d + 1.0; // min r is now 1
    float strength = 1.0 / sqrt(r);
    return half4(newColor.rgb, strength);
}  

可以使用例如从 SwiftUI 调用此函数

Rectangle()
    .frame(width: boardSize.width, height: boardSize.height)
    .colorEffect(ShaderLibrary.pointField(.float2(center.x, center.y), .color(Color(red: 0, green: 1, blue: 0))))

其中

center
是点场的中心。

根据Apple 的文档,金属着色器函数必须具有以下签名:

[[ stitchable ]] half4 name(float2 position, args...)

我现在想要显示多个点字段的叠加。由于数字可以在运行时更改,因此我的想法是使用与上面显示的代码相当的金属着色器,但在可变参数给出的点源上进行循环。
此博客展示了如何使用可变参数调用 Metal 着色器函数

let shader = Shader(function: function, arguments: [])  

我的问题是:
我如何确定有多少参数已从 SwiftUI 传递到 Metal?这需要循环上面的代码,并总结各个点场的场强。
我可以想象将后面的点场中心的数量作为第一个必需参数传递。这是正确的方法吗?

swiftui shader metal variadic
1个回答
0
投票

您有责任知道有多少参数已传递给 Metal,事实上它们是固定的而不是动态的。

我将传递两个参数,一个是一维值数组,另一个是当前数值的计数。

数组的长度是支持的最大值数。

© www.soinside.com 2019 - 2024. All rights reserved.