Ios 是否将SCNGeometry振荡器与使用自定义SCN程序的SCNGeometry一起使用?

Ios 是否将SCNGeometry振荡器与使用自定义SCN程序的SCNGeometry一起使用?,ios,scenekit,arkit,metal,Ios,Scenekit,Arkit,Metal,我正在尝试向某些使用自定义SCNProgram的SceneKit几何体添加scnGeometryteSellator。我的几何体渲染正常,但只要添加SCNGEOmetrolyteSellator,我就会看到以下错误: [SceneKit] Error: Compiler error while building render pipeline state for node <C3DNode:0x1053e9700 "(null)" geometry: <C3D

我正在尝试向某些使用自定义
SCNProgram
的SceneKit几何体添加
scnGeometryteSellator
。我的几何体渲染正常,但只要添加
SCNGEOmetrolyteSellator
,我就会看到以下错误:

[SceneKit] Error: Compiler error while building render pipeline state for node <C3DNode:0x1053e9700 "(null)"
  geometry: <C3DParametricGeometry<Plane>:0x1053e9160 "(null)"
  mesh: <C3DMesh 0x282590620 "(null)"
  element0: <C3DMeshElement 0x2823922b0 type:triangles primCount:200 channels:1 indexBytes:2 offset:0 acmr:0.605000 inst:1 dataSize:1200 shared:0x0>
  source position (channel:0) : <C3DMeshSource 0x2837fbbf0(position) data:(0x281009ce0) mut:0 count:121 type:float3 divisor:0 mtl:0 offset:0 stride:32>
  source normal (channel:0) : <C3DMeshSource 0x2837fb480(normal) data:(0x281009ce0) mut:0 count:121 type:float3 divisor:0 mtl:0 offset:12 stride:32>
  source texcoord (channel:0) : <C3DMeshSource 0x2837fbb80(texcoord) data:(0x281009ce0) mut:0 count:121 type:float2 divisor:0 mtl:0 offset:24 stride:32>
  renderable element0: <C3DMeshElement 0x2823922b0 type:triangles primCount:200 channels:1 indexBytes:2 offset:0 acmr:0.605000 inst:1 dataSize:1200 shared:0x0>
  renderable source position: <C3DMeshSource 0x2837fbbf0(position) data:(0x281009ce0) mut:0 count:121 type:float3 divisor:0 mtl:0 offset:0 stride:32>
  renderable source normal: <C3DMeshSource 0x2837fb480(normal) data:(0x281009ce0) mut:0 count:121 type:float3 divisor:0 mtl:0 offset:12 stride:32>
  renderable source texcoord: <C3DMeshSource 0x2837fbb80(texcoord) data:(0x281009ce0) mut:0 count:121 type:float2 divisor:0 mtl:0 offset:24 stride:32>
>
  mat0: <C3DMaterial 0x2837159d0 : "(null)", custom <C3DFXTechnique>>
>
>:
Error Domain=AGXMetalA14 Code=3 "Attribute 0 incompatible with MTLStepFunctionPerPatchControlPoint." UserInfo={NSLocalizedDescription=Attribute 0 incompatible with MTLStepFunctionPerPatchControlPoint.}
[SceneKit] Error: _executeProgram - no pipeline state
如果删除自定义材质,tesselator实际上可以工作,但我需要使用SCN程序


导致此错误的原因是什么以及如何使用
SCNgeometryteSellator

一旦添加了
tessellator
一个
SCNGeometry
,您的
SCNProgram
需要使用后细分顶点函数,而不是标准顶点函数。我发现的唯一一个真正涵盖这一点的文件是苹果的

虽然我对金属镶嵌并不期待,但我对这个问题的理解如下:

假设法线顶点函数如下所示:

struct VertexInput {
    float3 position [[attribute(SCNVertexSemanticPosition)]];
    float3 normal [[attribute(SCNVertexSemanticNormal)]];
    float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
};

vertex ColorInOut myVertexShader(VertexInput in [[ stage_in ]], ...) {
    ...
}
关于属性0与MTLStepFunctionPerPatchControlPoint不兼容的错误说明您的输入类型(
VertexInput
)与当前渲染管道的预期顶点输入不匹配。这是因为添加细分后,渲染管道将更改为使用特殊的细分后顶点函数,而不是标准顶点函数

后细分顶点函数从细分器而不是几何体获取输入。下面是转换为细分后顶点函数的上述顶点着色器:

struct PatchIn {
    patch_control_point<VertexInput> control_points;
};

[[patch(triangle, 3)]]
vertex ColorInOut myVertexShader(PatchIn patchIn [[stage_in]],
                                 float3 patch_coord [[ position_in_patch ]], ...)
{
    // We have to compute the correct input positions from the tessellation data 
    // Note that there's probably a cleaner/better way to do this

    // Barycentric coordinates
    float u = patch_coord.x;
    float v = patch_coord.y;
    float w = patch_coord.z;
    
    // Convert to cartesian coordinates
    const float3 pos = float3(
                              u * patchIn.control_points[0].position.x + v * patchIn.control_points[1].position.x + w * patchIn.control_points[2].position.x,
                              u * patchIn.control_points[0].position.y + v * patchIn.control_points[1].position.y + w * patchIn.control_points[2].position.y,
                              u * patchIn.control_points[0].position.z + v * patchIn.control_points[1].position.z + w * patchIn.control_points[2].position.z);
    
    ...
}
struct PatchIn{
贴片控制点控制点;
};
[patch(三角形,3)]]
顶点颜色输出myVertexShader(PatchIn PatchIn[[stage_in]],
浮动3面片坐标[[面片中的位置],…)
{
//我们必须根据细分数据计算正确的输入位置
//请注意,可能有一种更干净/更好的方法来做到这一点
//重心坐标
float u=patch_coord.x;
浮点数v=贴片坐标y;
float w=面片坐标z;
//转换为笛卡尔坐标
常量浮动3位置=浮动3(
u*patchIn.control_points[0]。position.x+v*patchIn.control_points[1]。position.x+w*patchIn.control_points[2]。position.x,
u*patchIn.control_points[0]。position.y+v*patchIn.control_points[1]。position.y+w*patchIn.control_points[2]。position.y,
u*patchIn.control_points[0]。position.z+v*patchIn.control_points[1]。position.z+w*patchIn.control_points[2]。position.z);
...
}
将顶点函数重写为细分后顶点函数后,几何体应使用细分和自定义
SCNProgram