Search code examples
swiftcamerascenekitglkitorthographic

Camera position in orthographic projection


I'm trying to understand how to use camera with usesOrthographicProjection = true. I need to set it up so when we first see the scene, the object should be viewable in full.

I used the Xcode's SceneKit template, adjust a little bit about the camera (all the code is in viewDidLoad). Using default camera (perspective projection), it looks like this:

cameraNode.position = SCNVector3(x: 0, y: 0, z: ship.boundingBox.max.z + 20)

enter image description here

Next, I tried to set the orthographic projection, now it looks like this:

cameraNode.camera?.usesOrthographicProjection = true
cameraNode.position = SCNVector3(x: 0, y: 0, z: ship.boundingBox.max.z + 20)

enter image description here

No matter how I tried to change the camera position, it still looks the same as the image above. I've tried using GLKMatrix4MakeOrtho to no avail. Nothing works. What should I do the change the first view impression?

cameraNode.camera?.usesOrthographicProjection = true

//    let width = Float(UIScreen.main.bounds.size.width)
//    let width: Float = 9
//    let glMat = GLKMatrix4MakeOrtho(-width/2, 
//                                    width/2, 
//                                    -width/2, 
//                                    width/2, 
//                                    1, 
//                                    1000)

//    let glMat = GLKMatrix4MakeOrtho(ship.boundingBox.min.x,
//                                    ship.boundingBox.max.x,
//                                    ship.boundingBox.min.y,
//                                    ship.boundingBox.max.y,
//                                    ship.boundingBox.min.z,
//                                    ship.boundingBox.max.z)
//    cameraNode.camera?.projectionTransform = SCNMatrix4FromGLKMatrix4(glMat)

cameraNode.position = SCNVector3(x: 0, 
                                 y: 0, 
                                 z: ship.boundingBox.max.z + 20)

Solution

  • Use orthographicScale instance property to control camera’s magnification factor when using an orthographic projection.

    var orthographicScale: Double { get set }
    

    Here's full code version:

    import SceneKit
    
    class GameViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let sceneView = self.view as! SCNView
            sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
            sceneView.allowsCameraControl = true
            sceneView.backgroundColor = UIColor.black
            
            sceneView.pointOfView?.camera!.usesOrthographicProjection = true
            sceneView.pointOfView?.camera!.zNear = 0.1
            sceneView.pointOfView?.camera!.zFar = 50.0
            sceneView.pointOfView?.camera!.orthographicScale = 5.0
        }
    }
    

    Orthographic projection is a means of representing three-dimensional objects in two dimensions. So there's no distance in Z since we are in two dimensions. That's why you have to use an orthographicScale property. No matter how you move the camera with parallel projection beams, the distance to objects will remain unchanged.

    So, take into consideration: in an orthographic projection, equally sized objects appear equally sized regardless of their distance from the camera.

    The only parameter that controls a "distance" in two-dimensional space (there's no Z position in reality in 2D) is an orthographicScale.

    enter image description here