iosscenekitscnmaterial

SCNBox – Map a texture onto five of six sides


I'm trying to create something like canvas in SceneKit using an SCNBox, with a UIImage "wrapped" around from one surface and onto the four others adjacent to it.

The only way I can currently think to do this would be to chop up the UIImage into five separate images and put those onto the sides as materials, but I'm sure there must be an easier way.

Can anyone steer me in the right direction here? The box will have a separate texture/material on the side opposite the "front".

enter image description here


Solution

  • You can use contentsTransform property from SCNMaterialProperty, for adjust needed texture coordinates from your image to SCNBox

    Some explanations with simplified example:

    Lets suppose that you are using cube and you have a texture like this enter image description here

    By dividing it into rectangles, you will have enter image description here

    You want to skip rectangles 1, 3, 7, 9 and cover your cube with this texture. For this just normalize the size of side from your SCNBox between 0 and 1, and use it to set the scale and transform in contentsTransform matrix.

    I have a cube with equal sides in my example - so it will be the third part of the whole texture. For taking the 5 rectangle from the texture

    let normalizedWidth = 1/3
    let normilizedHeight = 1/3
    
    let xOffset = 1 //skip 1,4,7 line
    let yOffset = 1 //skip 1,2,3 line
    let sideMaterial = SCNMaterial()
    sideMaterial.diffuse.contents = textureImage
    let scaleMatrix = SCNMatrix4MakeScale(normalizedWidth, normilizedHeight, 0.0)
    sideMaterial.diffuse.contentsTransform = SCNMatrix4Translate(scaleMatrix, 
    normalizedWidth * xOffset, yOffset * yOffset, 0.0)
    

    You can fill 5 sides with configured materials, and the last on (on the back) just with the color and set them to materials property of your SCNBox. In the result you will have

    enter image description here