【问题标题】:How to draw tens of thousands of lines in SceneKit?如何在 SceneKit 中画出上万条线?
【发布时间】:2017-04-27 05:05:02
【问题描述】:

我要在SceneKit 中画很多线。我搜索了如何画线,发现this answer

它对我来说很好,除了它不适合绘制大量线条。当我画几万条线时,占用的 RAM 将是可怕的(n Gb)。

我想知道是否有一种方法可以有效地绘制大量线条。我只需要 3D 线,它们的从坐标和长度可能不同。

【问题讨论】:

    标签: ios swift graphics scenekit


    【解决方案1】:

    referenceed answer中描述的方法是正确的,您只是没有为每一行创建SCNGeometrySource/SCNGeometryElement/SCNNode,只需填充数组:

    SCNVector3 positions[] = {
        SCNVector3Make(0.0, 0.0, 0.0),    // line1 begin  [0]
        SCNVector3Make(10.0, 10.0, 10.0), // line1 end    [1]
        SCNVector3Make(5.0, 10.0, 10.0),  // line2 begin  [2]
        SCNVector3Make(10.0, 5.0, 10.0)   // line2 end    [3]
    };
    
    int indices[] = {0, 1, 2, 3};
                  // ^^^^  ^^^^
                  // 1st   2nd
                  // line  line
    

    然后从 NSData 创建几何源,步幅:

    NSData *data = [NSData dataWithBytes:positions length:sizeof(positions)];
    
    SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithData:data
                                                semantic:SCNGeometrySourceSemanticVertex
                                             vectorCount:POSITION_COUNT
                                         floatComponents:YES
                                     componentsPerVector:3 // x, y, z
                                       bytesPerComponent:sizeof(CGFloat) // size of x/y/z/ component of SCNVector3
                                              dataOffset:0 
                                              dataStride:sizeof(SCNVector3)*2]; // offset in buffer to the next line positions
    

    如果您有 10000 行,那么您的位置缓冲区将为 2*3*10000*8 = 480KB,索引为 2*10000*4 = 80KB,即对于GPU来说真的不多。

    如果您可以减少索引和/或位置的长度,您甚至可以进一步减少缓冲区。例如,如果您的所有坐标都是 -127..128 范围内的整数,那么传递 floatComponent:NO, bytesPerComponent:1 会将位置缓冲区减少到 60KB)。

    当然,如果您的所有生产线都具有相同的材料属性,则这是适用的。否则,您必须将SCNGeometrySource/SCNGeometryElement/SCNNode 中具有相同属性的所有行分组。

    【讨论】:

    • 正如stackoverflow.com/questions/41037428/… 中提到的,您可以跳过NSData 转换并使用SCNGeometryElement(indices:primitiveType:) 生成索引缓冲区。
    • 这正是我要找的!谢谢!
    • 只是为了其他人需要解决类似的问题,在一个几何图形中绘制过多的线(如 300 条)会使您的应用程序崩溃。我不知道原因,但它确实发生了。
    猜你喜欢
    • 2020-02-16
    • 2015-03-14
    • 2010-11-12
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2021-12-02
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多