自定义几何网格 - 如何三角剖分以使其看起来平滑

时间:2015-08-19 15:13:45

标签: ios swift 3d scenekit

编辑:改变细分计数似乎使表面平滑。然而,我的表面现在似乎已经缩小了...我似乎无法恢复它的正常尺寸。为什么会发生这种情况?如何解决这个问题?

我希望在3D空间中依次绘制数百个平滑的平面来模拟数据。这些平面看起来会略有不同,但对于每一个平面,我只给出平面的四个角 - 加上平面中间的任意一点,使表面略微弯曲,以达到美感。

感谢这个网站的帮助,我在某种程度上对表面进行了三角测量,但它看起来像金字塔。这是我到目前为止所做的:

    var vertices = [SCNVector3(x: -5, y: 5, z: 0),
                    SCNVector3(x: 0, y: 5, z: -5),
                    SCNVector3(x: 5, y: 5, z: 0),

                    SCNVector3(x: 0, y: 5, z: 5),
                    SCNVector3(x: 0, y: 7, z: 0)]

    var indices : [CInt] = [4,0,1,
                            4,1,2,
                            4,2,3,
                            4,3,0]

    var normals = [SCNVector3]()
    var normalMap = [Int : SCNVector3]()
    for (var i = 0; i < vertices.count; i++) {
        var origVec = SCNVector3(x: 0.0, y: 0.0, z: 0.0)
        normalMap.updateValue(origVec, forKey: i)
    }


    //CALCULATE FACE NORMALS -->
    for (var i = 0; i < vertices.count - 2; i++) {
        var p1 = vertices[i] //B
        var p2 = vertices[i + 1] //A
        var p3 = vertices[vertices.count - 1] //C

        var vector1 = SCNVector3(x: 0, y: 0, z: 0)
        var vector2 = SCNVector3(x: 0, y: 0, z: 0)

        vector1.x = p1.x - p2.x
        vector1.y = p1.y - p2.y
        vector1.z = p1.z - p2.z

        vector2.x = p3.x - p2.x
        vector2.y = p3.y - p2.y
        vector2.z = p3.z - p2.z

        var faceNormal = crossProduct(vector1, v2: vector2)
        ((normalMap[i]!).x) += faceNormal.x
        ((normalMap[i]!).y) += faceNormal.y
        ((normalMap[i]!).z) += faceNormal.z
        ((normalMap[i + 1]!).x) += faceNormal.x
        ((normalMap[i + 1]!).y) += faceNormal.y
        ((normalMap[i + 1]!).z) += faceNormal.z
        ((normalMap[vertices.count - 1]!).x) += faceNormal.x
        ((normalMap[vertices.count - 1]!).y) += faceNormal.y
        ((normalMap[vertices.count - 1]!).z) += faceNormal.z
    }

    for (var i = 0; i < vertices.count; i++) {
            normals.append(normalize(normalMap[i]!))
    }



    //VERTEX SOURCE -->
    var vertexSource = SCNGeometrySource(vertices: vertices, count: 5)

    //NORMAL SOURCE -->
    var normalSource = SCNGeometrySource(normals: normals, count: 5)

    //INDICES AS DATA -->
    var data = NSData(bytes: indices, length: countElements(indices) * sizeof(Int))

    //GEOMETRY ELEMENT -->
    var geometryElement = SCNGeometryElement(data: data, primitiveType: .Triangles, primitiveCount: 4, bytesPerIndex: sizeof(CInt))

    //GEOMETRY -->
    var geometry = SCNGeometry(sources: [vertexSource, normalSource], elements: [geometryElement])

    geometry.firstMaterial?.doubleSided = true
    let node = SCNNode(geometry: geometry)
    self.rootNode.addChildNode(node)

因为我希望这个金字塔形状看起来很光滑,我只需要硬连接更多的三角形吗?如果是这样,那么“神奇数字是多少?”

或者,是否有某种方法可以实现三角测量过程的自动化?

或者,也许我正在咆哮错误的树,只需要通过照明或阴影或那种性质来改善模型的外观。改变细分计数会提供任何帮助吗?

感谢您的帮助;我以前从未构建过自定义几何体。

1 个答案:

答案 0 :(得分:1)

在没有细分的情况下获得平滑结果的常用方法是平均接触相邻平面的顶点的法线。即,获得同一位置的所有法线的平均值。 从问题中不清楚这是否是可接受的解决方案,或者每架飞机是否需要清楚地区分。

这是一个描述流程的链接(见下图): http://www.lighthouse3d.com/opengl/terrain/index.php3?normals

总之,每个顶点应该具有周围多边形的平均法向量。