SceneKit – 将立方体贴图映射到框
我看起来像一个立方体的纹理
我想在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
几何可能不适合我的目标,但是我不知道如何改变它。
您可以使用自定义几何体:创build一个多维数据集( 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]) }