- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
之间有什么联系:
[[stage_in]]
在 Metal 着色器中MTLVertexDescriptor
MTKMesh
例如
[[stage_in]]
不使用MTLVertexDescriptor
?MTLVertexDescriptor
不使用MTKMesh
,但是基于自定义结构的数据结构的数组?如struct Vertex {...}, Array<Vertex>
?MTKMesh
不使用MTLVertexDescriptor
?例如使用相同的基于结构的数据结构?我在网上没有找到这方面的资料,Metal Shading Language Specification 甚至没有包含“descriptor”或“mesh”这两个词。
最佳答案
没有。如果您尝试从没有顶点描述符的管道描述符创建渲染管道状态,并且相应的顶点函数具有 [[stage_in]]
参数,则管道状态创建调用将失败。
是的。毕竟,当您绘制一个 MTKMesh
时,您仍然有义务调用 setVertexBuffer(...)
并使用由网格的成分 MTKMeshBuffer
s。您可以轻松地自己创建一个
MTLBuffer
并将您的自定义顶点结构复制到其中。
是的。您没有
[[stage_in]]
参数,而是有一个属性为 [[buffer(0)]]
的参数(假设所有顶点数据都是交错的在单个顶点缓冲区中)类型为 MyVertexType *
,以及一个 [[vertex_id]]
参数,该参数告诉您索引到该缓冲区的位置。
这是在渲染命令编码器上从
MTKMesh
设置顶点缓冲区的示例:
for (index, vertexBuffer) in mesh.vertexBuffers.enumerated() {
commandEncoder.setVertexBuffer(vertexBuffer.buffer, offset: vertexBuffer.offset, index: index)
}
vertexBuffer
是MTKMeshBuffer
类型,而它的buffer
属性是MTLBuffer
类型;我提到这一点是因为它可能会造成混淆。
这是您可以创建顶点描述符来告诉 Model I/O 和 MetalKit 布置您正在加载的网格数据的一种方法:
let mdlVertexDescriptor = MDLVertexDescriptor()
mdlVertexDescriptor.attributes[0] = MDLVertexAttribute(name: MDLVertexAttributePosition, format: MDLVertexFormat.float3, offset: 0, bufferIndex: 0)
mdlVertexDescriptor.attributes[1] = MDLVertexAttribute(name: MDLVertexAttributeNormal, format: MDLVertexFormat.float3, offset: 12, bufferIndex: 0)
mdlVertexDescriptor.attributes[2] = MDLVertexAttribute(name: MDLVertexAttributeTextureCoordinate, format: MDLVertexFormat.float2, offset: 24, bufferIndex: 0)
mdlVertexDescriptor.layouts[0] = MDLVertexBufferLayout(stride: 32)
您可以创建相应的 MTLVertexDescriptor
以创建适合渲染此类网格的渲染管线状态:
let vertexDescriptor = MTKMetalVertexDescriptorFromModelIO(mdlVertexDescriptor)!
这是一个匹配该布局的顶点结构:
struct VertexIn {
float3 position [[attribute(0)]];
float3 normal [[attribute(1)]];
float2 texCoords [[attribute(2)]];
};
这是一个使用这些顶点之一的 stub 顶点函数:
vertex VertexOut vertex_main(VertexIn in [[stage_in]])
{
}
最后,这是一个顶点结构和顶点函数,您可以使用它来渲染完全相同的网格数据而无需顶点描述符:
struct VertexIn {
packed_float3 position;
packed_float3 normal;
packed_float2 texCoords;
};
vertex VertexOut vertex_main(device VertexIn *vertices [[buffer(0)]],
uint vid [[vertex_id]])
{
VertexIn in = vertices[vid];
}
请注意,在最后一种情况下,我需要将结构成员标记为 packed,因为默认情况下,Metal 的 simd 类型被填充用于对齐目的(具体来说,float3< 的步长
是 16 字节,而不是我们在顶点描述符中请求的 12。
关于swift - [[stage_in]]、MTLVertexDescriptor 和 MTKMesh 之间的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48455501/
我从这里下载了一个简单的 Metal 着色器:https://medium.com/@MalikAlayli/metal-with-scenekit-create-your-first-shader-
之间有什么联系: 使用 [[stage_in]]在 Metal 着色器中 使用 MTLVertexDescriptor 使用 MTKMesh 例如 是否可以使用 [[stage_in]]不使用MTLV
我是一名优秀的程序员,十分优秀!