【问题标题】:Display stretched material apply on SCNGeometrySource node显示拉伸材质应用于 SCNGeometrySource 节点
【发布时间】:2019-11-08 00:40:39
【问题描述】:

我使用 SCNGeometrySource 创建了 SCNNode,使用自定义选择的 SCNVector3 点超过三个,并应用图像材质来显示非常拉伸的材质。如何在 SCNGeometrySource 节点上正确应用材质。

func getsquareDrawnLineFrom(pos1: SCNVector3,
                            pos2: SCNVector3,
                            pos3: SCNVector3) -> SCNNode {

    let square = SquareplanlineFrom(vector1: pos1, vector2: pos2, vector3: pos3)
    //SCNGeometrySource.Semantic.texcoord
    //SCNGeometrySource.Semantic.normal
    let material = SCNMaterial()
    // material.diffuse.contents = UIColor.lightGray
    material.diffuse.contents = UIImage(named: "grid")
    material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
    material.diffuse.wrapS = .repeat
    material.diffuse.wrapT = .repeat
    square.materials = [material]
    let square1 = SCNNode(geometry: square)
    square1.name = "tringle"
    return square1
}

// get line geometry between two vectors
func SquareplanlineFrom(vector1: SCNVector3,
              vector2: SCNVector3, vector3: SCNVector3) -> SCNGeometry {
     let normalsPerFace = 3
    let indices: [Int32] = [0, 1, 2]
    let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
    let normals:[SCNVector3] = [
        vector1,
        vector2,
        vector3].map{[SCNVector3](repeating:$0,count:normalsPerFace)}.flatMap{$0}
    let normalSource = SCNGeometrySource(normals: normals)
    let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
    let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
    let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
    let textcoord = SCNGeometrySource(textureCoordinates: [cgp1,cgp2,cgp3])

    // let texcoord = SCNGeometrySource(textureCoordinates: [])
    // let normalSource = SCNGeometrySource(normals: [vector1, vector2, vector3])

    let element = SCNGeometryElement(indices: indices,
                                     primitiveType: .triangles)
    return SCNGeometry(sources: [source,normalSource,textcoord], elements: [element])
}

【问题讨论】:

    标签: ios swift scenekit augmented-reality arkit


    【解决方案1】:

    在您的情况下,这是纹理的比例问题:

    我不知道您的模型的大小,但我认为问题在于 - 您增加了比例,但您必须减小比例才能正确放置纹理。

    提示:我的纹理大小为 2K 正方形(2048x2048,72dpi)。

    这是一个代码(对不起,我使用的是 macOS 版本):

    func getSquareDrawnLineFrom(pos1: SCNVector3,
                                pos2: SCNVector3,
                                pos3: SCNVector3) -> SCNNode {
    
        let square = squarePlanLineFrom(vector1: pos1, 
                                        vector2: pos2, 
                                        vector3: pos3)
    
        let material = SCNMaterial()
        material.diffuse.contents = NSImage.Name("art.scnassets/jaguar.jpg")
    
        // your scale
        // material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)           
    
        material.isDoubleSided = true
    
        material.diffuse.contentsTransform = .init(m11: 0.05, m12: 0,    m13: 0,    m14: 0, 
                                                   m21: 0,    m22: 0.05, m23: 0,    m24: 0, 
                                                   m31: 0,    m32: 0,    m33: 1,    m34: 0, 
                                                   m41: 0,    m42: 0,    m43: 0,    m44: 1)
        material.diffuse.wrapS = .repeat
        material.diffuse.wrapT = .repeat
        square.materials = [material]
    
        let square1 = SCNNode(geometry: square)
        scene.rootNode.addChildNode(square1)
        square1.name = "triangle"
        return square1
    }
    
    func squarePlanLineFrom(vector1: SCNVector3,
                            vector2: SCNVector3,
                            vector3: SCNVector3) -> SCNGeometry {
    
        let normalsPerFace = 3
        let indices: [Int32] = [0, 1, 2]
        let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
    
        let vec = [vector1, vector2, vector3].map { [SCNVector3](repeating: $0,
                                                                     count: normalsPerFace) }.flatMap{ $0 }
        let normals: [SCNVector3] = vec
    
        let normalSource = SCNGeometrySource(normals: normals)
        let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
        let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
        let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
        let textcoord = SCNGeometrySource(textureCoordinates: [cgp1, cgp2, cgp3])
    
        let element = SCNGeometryElement(indices: indices,
                                   primitiveType: .triangles)
    
        return SCNGeometry(sources: [source, normalSource, textcoord], 
                          elements: [element])
    }
    
    
    let instance = getSquareDrawnLineFrom(pos1: SCNVector3(x: 0, y: 0, z: 0),
                                          pos2: SCNVector3(x: 8, y: 5, z: 0),
                                          pos3: SCNVector3(x:-8, y: 5, z: 0))
    

    但有时可能是法线的方向问题:

    开发人员通常会创建与表面平行的向量,因此会拉伸纹理(纹理的一行像素会沿整个表面复制)。 但几何体的法线必须垂直于表面,而不是平行

    【讨论】:

    • @KalpeshPrajapati 让我们删除所有这些 cmets。
    • 您好 ARGeo,请帮帮我,我在 Sceneview 中设置了“allowsCameraControl = true” 如何禁用某些默认功能。 stackoverflow.com/questions/57476065/…
    猜你喜欢
    • 2019-10-06
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多