4

在我用 Swift 编写的 iOS 应用程序中,我生成了一个 Metal 缓冲区,其中包含:

vertexBuffer = device.newBufferWithBytes(vertices, length: vertices.count * sizeofValue(vertices[0]), options: nil)

并将其绑定到我的着色器程序:

renderCommandEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 1)

在我用 Metal 着色语言编写的着色器程序中,我可以访问缓冲区的大小吗?我想访问缓冲区中的下一个顶点来进行一些微分计算。就像是:

vertex float4 my_vertex(const device packed_float3* vertices [[buffer(1)]],
                         unsigned int vid[[vertex_id]]) {
    float4 vertex = vertices[vid];
    // Need to clamp this to not go beyond buffer, 
    // but how do I know the max value of vid? 
    float4 nextVertex = vertices[vid + 1]; 
    float4 tangent = nextVertex - vertex;
    // ...
}

我唯一的选择是将顶点数作为统一传递吗?

4

3 回答 3

7

据我所知,不,你不能,因为顶点指向一个地址。就像 C++ 一样,必须有两件事才能知道数组的计数或大小:
1) 知道数组的数据类型(浮点数或某些结构)

2a) 数据类型的数组计数或
2b) 的总字节数数组。

所以是的,您需要将数组计数作为制服传递。

于 2014-10-29T21:41:19.007 回答
1

对于纹理缓冲区,您可以。

您可以从着色器代码中获取纹理缓冲区的大小。
纹理缓冲区有一个get_width()andget_height()函数,它返回一个uint.

uint get_width() const; uint get_height() const;

但这可能并不能回答 OP 关于顶点缓冲区的问题。

于 2018-10-17T11:36:06.933 回答
-1

其实你可以。您可以将结果值用于循环或条件。您不能使用它来初始化对象。(所以动态数组失败)

uint tempUint = 0; // some random type
uint uintSize = sizeof(tempUint); // get the size for the type
uint aVectorSize = sizeof(aVector) / uintSize; // divide the buffer by the type.

float dynamicArray[aVectorSize]; // this fails

for (uint counter = 0; counter < aVectorSize; ++ counter) {
    // do stuff
};

if (aVectorSize > 10) {
    // do more stuff
} 
于 2015-09-01T16:46:46.583 回答