首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将SCNGeometryTessellator与使用自定义SCNProgram的SCNGeometry一起使用?

将SCNGeometryTessellator与使用自定义SCNProgram的SCNGeometry一起使用?
EN

Stack Overflow用户
提问于 2021-05-06 13:13:28
回答 1查看 79关注 0票数 0

我正在尝试将SCNGeometryTessellator添加到一些使用自定义SCNProgram的SceneKit几何体中。我的几何图形渲染正常,但我一添加SCNGeometryTessellator,就会看到以下错误:

代码语言:javascript
运行
复制
[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

下面是我创建几何体的方法:

代码语言:javascript
运行
复制
let program = SCNProgram()
program.vertexFunctionName = "myVertexShader"
program.fragmentFunctionName = "myFragmentShader"

let mat = SCNMaterial()
mat.program = previewProgram

let plane = SCNPlane()
plane.widthSegmentCount = 1
plane.heightSegmentCount = 1
plane.firstMaterial = mat

let tessellator = SCNGeometryTessellator()
tessellator.edgeTessellationFactor = 10.0
tessellator.insideTessellationFactor = 10.0
tessellator.smoothingMode = .pnTriangles
plane.tessellator = tessellator

// add plane node to scene...

如果我移除自定义材质,则镶嵌器实际上可以工作,但我需要使用SCNProgram。

导致此错误的原因是什么?如何使用SCNGeometryTessellator

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-06 13:13:28

添加tessellatorSCNGeometry后,SCNProgram需要使用细分后顶点函数,而不是标准顶点函数。我找到的唯一能涵盖这一点的文档是苹果的metal tessellation programming guide

虽然我不是一个金属镶嵌的期望值,但这是我对这个问题的理解:

假设您的正常顶点函数如下所示:

代码语言:javascript
运行
复制
struct VertexInput {
    float3 position [[attribute(SCNVertexSemanticPosition)]];
    float3 normal [[attribute(SCNVertexSemanticNormal)]];
    float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
};

vertex ColorInOut myVertexShader(VertexInput in [[ stage_in ]], ...) {
    ...
}

有关Attribute 0 incompatible with MTLStepFunctionPerPatchControlPoint的错误说明您的输入类型(VertexInput)与当前渲染管道的预期顶点输入不匹配。这是因为添加细分后,渲染管道将更改为使用特殊的后期细分顶点函数,而不是标准顶点函数。

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

代码语言:javascript
运行
复制
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);
    
    ...
}

将折点函数重写为镶嵌后折点函数后,几何应使用镶嵌和自定义SCNProgram进行渲染

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67412205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档