SCNBox different colour or texture on each face

may19c19 picture may19c19 · Dec 16, 2014 · Viewed 14.8k times · Source

I'm new to iOS development and I've got myself stumped. I am trying to render a cube using SceneKit that has a different colour for each face.

This is what I've got so far:

func sceneSetup() {
    // 1
    let scene = SCNScene()

    // 2
    let BoxGeometry = SCNBox(width: 0.9, height: 0.9, length: 0.9, chamferRadius: 0.0)

    BoxGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
    let cube = SCNNode(geometry: BoxGeometry)
    cube.position = SCNVector3(x: 0, y: 0, z: -1)
    scene.rootNode.addChildNode(cube)

    // 3
    sceneView.scene = scene
    sceneView.autoenablesDefaultLighting = true
    sceneView.allowsCameraControl = true

But I'd like each face to have a different colour. How do I do that?

Answer

David Rönnqvist picture David Rönnqvist · Dec 16, 2014

The box is composed out of six different elements (one for each side). You may also have noticed that a geometry object has one property for the first material but also a property for an array of materials.

An object with multiple elements and multiple materials will pick the increment the material (and wrap) for each element.

For example 4 elements and 1 material

Element   1  2  3  4
Material  1  1  1  1

or 4 elements and 2 materials

Element   1  2  3  4
Material  1  2  1  2  // note that they are repeating 

For example 4 elements and 7 materials

Element   1  2  3  4
Material  1  2  3  4  // (5, 6, 7) is unused

In the case of the box this means that you can use an array of six materials to have a unique material on each side of the box. I have an example of this in the sample code for one of the chapters for my Scene Kit book (in Objective-C):

// Each side of the box has its own color
// --------------------------------------
// All have the same diffuse and ambient colors to show the
// effect of the ambient light, even with these materials.

SCNMaterial *greenMaterial              = [SCNMaterial material];
greenMaterial.diffuse.contents          = [NSColor greenColor];
greenMaterial.locksAmbientWithDiffuse   = YES;

SCNMaterial *redMaterial                = [SCNMaterial material];
redMaterial.diffuse.contents            = [NSColor redColor];
redMaterial.locksAmbientWithDiffuse     = YES;

SCNMaterial *blueMaterial               = [SCNMaterial material];
blueMaterial.diffuse.contents           = [NSColor blueColor];
blueMaterial.locksAmbientWithDiffuse    = YES;

SCNMaterial *yellowMaterial             = [SCNMaterial material];
yellowMaterial.diffuse.contents         = [NSColor yellowColor];
yellowMaterial.locksAmbientWithDiffuse  = YES;

SCNMaterial *purpleMaterial             = [SCNMaterial material];
purpleMaterial.diffuse.contents         = [NSColor purpleColor];
purpleMaterial.locksAmbientWithDiffuse  = YES;

SCNMaterial *magentaMaterial            = [SCNMaterial material];
magentaMaterial.diffuse.contents        = [NSColor magentaColor];
magentaMaterial.locksAmbientWithDiffuse = YES;


box.materials =  @[greenMaterial,  redMaterial,    blueMaterial,
                   yellowMaterial, purpleMaterial, magentaMaterial];