SceneKit - Map cube texture to box

Guig

I've a texture for a cube that looks like

enter image description here

I'd like to use it on a cube in a SceneKit view. I'm using the SceneKit geometry SCNBox for that. Unfortunately, the result is that the texture is projected entirely on each face, instead of using only the corresponding part:

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

I know I can use shader modifiers on the geometry but I'm not sure where to get started. Since the texture is currently used six times, my intuition is that the SCNBox geometry might not be adapted to my goal, but I don't really know how to change it.

jacobtref

You can get it to work with a custom geometry: create a cube (http://ronnqvi.st/custom-scenekit-geometry/ is a good place to get started) and you can add some custom texture mapping on top. It's a bit tricky to get the indices right (was for me), but at the end it worked fine:

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])
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to set contents of scenekit background to cube map

From Dev

How to programmatically wrap png texture around cube in SceneKit

From Dev

OpenGL : Cube Map texture, no UV mapping

From Dev

OpenGL GL_TEXTURE_CUBE_MAP no textures / black

From Dev

SceneKit painting on texture with texture coordinates

From Dev

Threejs not appying the texture to cube

From Dev

Threejs not appying the texture to cube

From Dev

SceneKit cube rotation with multiple UIPanGestureRecognizers

From Dev

GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT when attaching a cube map texture to a frame buffer object (FBO)

From Dev

Cube map render texture creation works in GL 3.2 but gives an error in 4.3

From Dev

Texture coordinates for custom geometry in Scenekit

From Dev

SceneKit – Concave collision box

From Dev

make a gravestone type carving into a cube (Swift - SceneKit)

From Dev

Light not shining on all sides of cube in SceneKit ios

From Dev

CUDA cube map textures

From Dev

How to texture a "perfect cube" drawn with triangles?

From Dev

Use a texture and a color on a cube three.js

From Dev

Make a solid box (cube) in ILNumerics

From Dev

Make a solid box (cube) in ILNumerics

From Dev

Want to add Image as texture in scenekit ios

From Java

Texture map in R

From Dev

Update texture map in ThreeJS

From Dev

Overlay Picture Box texture and structure

From Dev

SFML texture displaying as a white box

From Dev

Identify face of a cube hit on touches began in Swift - SceneKit

From Dev

Seams on cube edges when using texture atlas with three.js

From Dev

Unable to apply texture on my cube using opengl & sfml

From Dev

Rendering cube on top of square having video feed as texture

From Dev

how can i project a camera onto a cube as a Texture in jMonkeyEngine 3?

Related Related

  1. 1

    How to set contents of scenekit background to cube map

  2. 2

    How to programmatically wrap png texture around cube in SceneKit

  3. 3

    OpenGL : Cube Map texture, no UV mapping

  4. 4

    OpenGL GL_TEXTURE_CUBE_MAP no textures / black

  5. 5

    SceneKit painting on texture with texture coordinates

  6. 6

    Threejs not appying the texture to cube

  7. 7

    Threejs not appying the texture to cube

  8. 8

    SceneKit cube rotation with multiple UIPanGestureRecognizers

  9. 9

    GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT when attaching a cube map texture to a frame buffer object (FBO)

  10. 10

    Cube map render texture creation works in GL 3.2 but gives an error in 4.3

  11. 11

    Texture coordinates for custom geometry in Scenekit

  12. 12

    SceneKit – Concave collision box

  13. 13

    make a gravestone type carving into a cube (Swift - SceneKit)

  14. 14

    Light not shining on all sides of cube in SceneKit ios

  15. 15

    CUDA cube map textures

  16. 16

    How to texture a "perfect cube" drawn with triangles?

  17. 17

    Use a texture and a color on a cube three.js

  18. 18

    Make a solid box (cube) in ILNumerics

  19. 19

    Make a solid box (cube) in ILNumerics

  20. 20

    Want to add Image as texture in scenekit ios

  21. 21

    Texture map in R

  22. 22

    Update texture map in ThreeJS

  23. 23

    Overlay Picture Box texture and structure

  24. 24

    SFML texture displaying as a white box

  25. 25

    Identify face of a cube hit on touches began in Swift - SceneKit

  26. 26

    Seams on cube edges when using texture atlas with three.js

  27. 27

    Unable to apply texture on my cube using opengl & sfml

  28. 28

    Rendering cube on top of square having video feed as texture

  29. 29

    how can i project a camera onto a cube as a Texture in jMonkeyEngine 3?

HotTag

Archive