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]; 7Here'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.