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?

3 Answers

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]; 
7

Here's a Swift 4 answer.

 let colors = [UIColor.green, // front UIColor.red, // right UIColor.blue, // back UIColor.yellow, // left UIColor.purple, // top UIColor.gray] // bottom let sideMaterials = colors.map { color -> SCNMaterial in let material = SCNMaterial() material.diffuse.contents = color material.locksAmbientWithDiffuse = true return material } materials = sideMaterials 

To change the front material just grab the material and change it's content

let frontMaterial = materials[0] frontMaterial.diffuse.contents = UIColor.white 

thai you for the fast help. i used the code you posed but was unable to use NSColor so i tried uicolor but all i was getting was a black cube so i tried this and i got it working

 let BoxGeometry = SCNBox(width: 0.95, height: 0.95, length: 0.95, chamferRadius: 0.0) let greenMaterial = SCNMaterial() greenMaterial.diffuse.contents = UIImage(named: "g") greenMaterial.locksAmbientWithDiffuse = true; let redMaterial = SCNMaterial() redMaterial.diffuse.contents = UIImage(named: "r") redMaterial.locksAmbientWithDiffuse = true; let blueMaterial = SCNMaterial() blueMaterial.diffuse.contents = UIImage(named: "b") blueMaterial.locksAmbientWithDiffuse = true; let yellowMaterial = SCNMaterial() yellowMaterial.diffuse.contents = UIImage(named: "y") yellowMaterial.locksAmbientWithDiffuse = true; let purpleMaterial = SCNMaterial() purpleMaterial.diffuse.contents = UIImage(named: "p") purpleMaterial.locksAmbientWithDiffuse = true; let WhiteMaterial = SCNMaterial() WhiteMaterial.diffuse.contents = UIImage(named: "w") WhiteMaterial.locksAmbientWithDiffuse = true; BoxGeometry.materials = [greenMaterial, redMaterial, blueMaterial, yellowMaterial, purpleMaterial, WhiteMaterial]; 

g is a jpeg of a green and so on and that has got it working now.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy