1

I am trying to create custom geometry shape in SceneKit and my shape turn out fine. The only problem is that it is black and even though I changed the color, it still remain black. I have tested with other primitive shapes in SceneKit and they turned out normal. I thought I have to calculate the surface normal but according to other tutorials and code samples online, unless I want my shape to be certain way, I don't have to calculate the surface normal and the framework will default it for me. I can't figure out why my shape is black and I have looked at different topic on here and I could not find an answer that work for me. I am pretty new to SceneKit and Swift. Here is my code:

import UIKit
import SceneKit
import QuartzCore

class GameViewController: UIViewController {
    var scnView: SCNView!
    var scnScene: SCNScene!
    var cameraNode: SCNNode!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
        setupScene()
        setupCamera()
        spawnShape()
    }

    func shouldAutorotate() -> Bool {
        return true
    }

    func prefersStatusBarHidden() -> Bool {
        return true
    }
    func setupView() {
        scnView = self.view as! SCNView
        // 1
        scnView.showsStatistics = true
        // 2
        scnView.allowsCameraControl = true
        // 3
        scnView.autoenablesDefaultLighting = true
    }
    func setupScene() {
        scnScene = SCNScene()
        scnView.scene = scnScene
        scnView.backgroundColor = UIColor.white
    }

    func setupCamera() {
        // 1
        cameraNode = SCNNode()
        // 2
        cameraNode.camera = SCNCamera()
        // 3
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
        // 4
        scnScene.rootNode.addChildNode(cameraNode)
    }

Here is where I create my custom shape. I have tested with other primitive shapes and they work fine, but my custom shape turn out black for some reasons I don't know:

func spawnShape() {
        // 1
        var geometry:SCNGeometry
        let positions = [
            SCNVector3(0, 1, 0),
            SCNVector3(-0.5, 0, 0.5),
            SCNVector3(0.5, 0, 0.5),
            SCNVector3(0.5, 0, -0.5),
            SCNVector3(-0.5, 0, -0.5),
            SCNVector3(0, -1, 0),
        ]
        let source = SCNGeometrySource(vertices: positions)
        let indices:[UInt32] = [
            0, 1, 2,
            2, 3, 0,
            3, 4, 0,
            4, 1, 0,
            1, 5, 2,
            2, 5, 3,
            3, 5, 4,
            4, 5, 1
            ]
        let element = SCNGeometryElement(indices: indices, primitiveType:.triangles)
        // 4
        geometry = SCNGeometry(sources: [source], elements: [element])
        geometry.firstMaterial?.diffuse.contents = UIColor.white
        let geometryNode = SCNNode(geometry: geometry)
        // 5
        scnScene.rootNode.addChildNode(geometryNode)
    }
}

Much appreciated if someone could help me understand. Thank you

Anh Trần
  • 83
  • 1
  • 1
  • 7
  • I played around with this and was able to get the color to change to green using this link. From there I'm not sure exactly how it works, but maybe this will point you in the right direction: https://stackoverflow.com/questions/32821653/scenekit-per-vertex-color – Voltan Nov 13 '18 at 21:53

1 Answers1

0

Adding

    geometry.firstMaterial?.lightingModel = .constant 

made a difference for me.

JKaz
  • 765
  • 6
  • 18