如何在Metal中从顶点着色器传递数组到片元着色器

6
在GLSL中,我会简单地使用out vec3 array[10];来从顶点着色器传递一个数组到片段着色器。然而,在Metal中,我考虑采用以下方式:
struct FragmentIn {
    float4 position [[position]];
    float3 array[10];
};

这会产生以下错误:
Type 'FragmentIn'对于属性'stage_in'无效,因为字段'array'具有无效类型'float3 [10]'
如何解决这个问题?我需要对每个顶点的数据进行某些计算,供片段着色器使用。
2个回答

9
您需要“展开”数组:
struct FragmentIn {
    float4 position [[position]];
    float3 thing0;
    float3 thing1;
    float3 thing2;
    float3 thing3;
    float3 thing4;
    float3 thing5;
    float3 thing6;
    float3 thing7;
    float3 thing8;
    float3 thing9;
};

2
有没有其他的方法? - Won

2

注意:我是一名图形爱好者,日常工作中不使用Metal或C++!

关于展开答案的建议:由于Metal Shading Language是C++,因此您可以使用宏使得使用展开数组更加简便。

创建重复宏

重复代码并不美观,但只需要编写一次:

#define REP1(FN, ...) FN(0, ##__VA_ARGS__)
#define REP2(FN, ...) REP1(FN, ##__VA_ARGS__) FN(1, ##__VA_ARGS__)
#define REP3(FN, ...) REP2(FN, ##__VA_ARGS__) FN(2, ##__VA_ARGS__)
#define REP4(FN, ...) REP3(FN, ##__VA_ARGS__) FN(3, ##__VA_ARGS__)
#define REP5(FN, ...) REP4(FN, ##__VA_ARGS__) FN(4, ##__VA_ARGS__)
#define REP6(FN, ...) REP5(FN, ##__VA_ARGS__) FN(5, ##__VA_ARGS__)
#define REP7(FN, ...) REP6(FN, ##__VA_ARGS__) FN(6, ##__VA_ARGS__)
#define REP8(FN, ...) REP7(FN, ##__VA_ARGS__) FN(7, ##__VA_ARGS__)
#define REP9(FN, ...) REP8(FN, ##__VA_ARGS__) FN(8, ##__VA_ARGS__)
#define REP10(FN, ...) REP9(FN, ##__VA_ARGS__) FN(9, ##__VA_ARGS__)

#define REPEAT(N, ...) REP ## N(__VA_ARGS__)

声明数组

函数宏可以用于生成数组成员:

#define DECLARE_VAR(VAR_INDEX, VAR_TYPE, VAR_PREFIX) VAR_TYPE VAR_PREFIX ## VAR_INDEX;

struct FragmentIn {
    float4 position [[position]];
    REPEAT(10, DECLARE_VAR, float3, array)
};

这将扩展为:

struct FragmentIn {
    float4 position [[position]];
    float3 array0;
    float3 array1;
    float3 array2;
    float3 array3;
    float3 array4;
    float3 array5;
    float3 array6;
    float3 array7;
    float3 array8;
    float3 array9;
};

访问数组

然后,您可以逐个访问未展开的数组元素,或编写另一个类似函数的宏来操作它们。以下示例对未展开的数组求和:

#define SUM_ARRAY(VAR_INDEX, VAR_PREFIX, TOTAL) TOTAL += VAR_PREFIX ## VAR_INDEX;

float3 sumOfVectors;
REPEAT(10, SUM_ARRAY, fragmentIn.array, sumOfVectors)

这会扩展为:

float3 sumOfVectors;
sumOfVectors += fragmentIn.array0;
sumOfVectors += fragmentIn.array1;
sumOfVectors += fragmentIn.array2;
sumOfVectors += fragmentIn.array3;
sumOfVectors += fragmentIn.array4;
sumOfVectors += fragmentIn.array5;
sumOfVectors += fragmentIn.array6;
sumOfVectors += fragmentIn.array7;
sumOfVectors += fragmentIn.array8;
sumOfVectors += fragmentIn.array9;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接