繁体   English   中英

SceneKit - 将立方体纹理映射到框

[英]SceneKit - Map cube texture to box

我有一个看起来像立方体的纹理

在此输入图像描述

我想在SceneKit视图中的立方体上使用它。 我正在使用SceneKit几何SCNBox 不幸的是,结果是纹理完全投射在每个面上,而不是仅使用相应的部分:

let videoGeometry = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
videoGeometry.firstMaterial?.isDoubleSided = true
videoGeometry.firstMaterial?.diffuse.contents = UIImage(named: "test")!

我知道我可以在几何体上使用着色器修改器,但我不知道从哪里开始。 由于纹理目前使用了六次,我的直觉是SCNBox几何可能不适应我的目标,但我真的不知道如何改变它。

您可以使用自定义几何体来创建它:创建一个立方体( http://ronnqvi.st/custom-scenekit-geometry/是一个开始的好地方),您可以在顶部添加一些自定义纹理映射。 让索引正确(对我而言)有点棘手,但最后它运行良好:

func getSimpleCubeGeo() -> SCNGeometry {
    let halfSide = Float(0.5)

    /* The cube vertex are like:

        5---------4
       /.        /|
      / .       / |
     7---------6  |
     |  .      |  |
     |  .      |  |
     |  1......|..0
     | .       | /
     |.        |/
     3---------2

     */
    let _positions = [
        SCNVector3(x:-halfSide, y:-halfSide, z:  halfSide),
        SCNVector3(x: halfSide, y:-halfSide, z:  halfSide),
        SCNVector3(x:-halfSide, y:-halfSide, z: -halfSide),
        SCNVector3(x: halfSide, y:-halfSide, z: -halfSide),
        SCNVector3(x:-halfSide, y: halfSide, z:  halfSide),
        SCNVector3(x: halfSide, y: halfSide, z:  halfSide),
        SCNVector3(x:-halfSide, y: halfSide, z: -halfSide),
        SCNVector3(x: halfSide, y: halfSide, z: -halfSide),
    ]

    // points are tripled since they are each used on 3 faces
    // and there's no continuity in the UV mapping
    // so we need to duplicate the points
    //
    // we'll use the first third for the faces orthogonal to the X (left) axis,
    // the second for the Y (top) axis and the third for the Z (front) axis
    let positions = _positions + _positions + _positions

    let X = 0
    let Y = 8
    let Z = 16

    let indices = [
        // bottom
        0 + Y, 2 + Y, 1 + Y,
        1 + Y, 2 + Y, 3 + Y,
        // back
        2 + Z, 6 + Z, 3 + Z,
        3 + Z, 6 + Z, 7 + Z,
        // left
        0 + X, 4 + X, 2 + X,
        2 + X, 4 + X, 6 + X,
        // right
        1 + X, 3 + X, 5 + X,
        3 + X, 7 + X, 5 + X,
        // front
        0 + Z, 1 + Z, 4 + Z,
        1 + Z, 5 + Z, 4 + Z,
        // top
        4 + Y, 5 + Y, 6 + Y,
        5 + Y, 7 + Y, 6 + Y,
    ]

    // get the points in the texture where the faces are split
    var textureSplitPoints = [CGPoint]()
    for i in 0...12 {
        let x = Double(i % 4)
        let y = Double(i / 4)
        textureSplitPoints.append(CGPoint(x: x / 3.0, y: y / 2.0))
    }
    let textCoords = [
        textureSplitPoints[4],
        textureSplitPoints[6],
        textureSplitPoints[5],
        textureSplitPoints[5],
        textureSplitPoints[8],
        textureSplitPoints[10],
        textureSplitPoints[9],
        textureSplitPoints[9],

        textureSplitPoints[5],
        textureSplitPoints[4],
        textureSplitPoints[1],
        textureSplitPoints[0],
        textureSplitPoints[7],
        textureSplitPoints[6],
        textureSplitPoints[11],
        textureSplitPoints[10],

        textureSplitPoints[2],
        textureSplitPoints[1],
        textureSplitPoints[2],
        textureSplitPoints[3],
        textureSplitPoints[6],
        textureSplitPoints[5],
        textureSplitPoints[6],
        textureSplitPoints[7],
    ]

    let vertexSource = SCNGeometrySource(vertices: positions)

    let textSource = SCNGeometrySource(textureCoordinates: textCoords)
    let indexData = NSData(bytes: indices, length: sizeof(Int) * indices.count)
    let elements = SCNGeometryElement(
        data: indexData as Data,
        primitiveType: SCNGeometryPrimitiveType.triangles,
        primitiveCount: indices.count / 3,
        bytesPerIndex: sizeof(Int)
    )
    return SCNGeometry(sources: [vertexSource, textSource], elements: [elements])
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM