Video 360 in OpenGL (iOS) part 2 – First Person Camera

Video 360 blogpost header

We already know how to build a 3d scene with a static camera and a skybox background. In this part we will learn how to revive our camera so that user can look at any direction.

Let’s start with camera’s parameters. FOV (field of view), aspect ratio, nearZ and farZ are the most common attributes of a perspective camera. The code of initialization camera may look like this:

init(fovRadians: Float = GLKMathDegreesToRadians(65.0),
         aspect: Float = (320.0 / 480.0), 
          nearZ: Float = 0.1,
           farZ: Float = 100)
    self.fovRadians = fovRadians
    self.aspect = aspect
    self.nearZ = nearZ
    self.farZ = farZ

Then we will setup a projection matrix…

private func updateProjectionMatrix()
    self.projectionMatrix = GLKMatrix4MakePerspective(self.fovRadians, self.aspect, self.nearZ, self.farZ)

…and a simple view matrix.

private func updateViewMatrix()
    // Look in the direction of z+ axis
    self.viewMatrix = GLKMatrix4MakeLookAt(0, 0, 0, 0, 0, 1, 0, 1, 0)

For spherical video player we don’t need our camera to change its position but only orientation. To do this, we will add yaw and pitch properties to our Camera class.

Camera rotations by Fisnik Hasani

Camera rotations by Fisnik Hasani

var yaw: Float = 0.0
    didSet { self.updateViewMatrix() }

var pitch: Float = 0.0
    didSet { self.updateViewMatrix() }

private func updateViewMatrix()
    let cosPitch = cosf(self.pitch)
    let sinPitch = sinf(self.pitch)
    let cosYaw = cosf(self.yaw)
    let sinYaw = sinf(self.yaw)

    let xaxis = GLKVector3(v: (cosYaw, 0, -sinYaw))
    let yaxis = GLKVector3(v: (sinYaw * sinPitch, cosPitch, cosYaw * sinPitch))
    let zaxis = GLKVector3(v: (sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw))

    self.viewMatrix = GLKMatrix4(m:
        xaxis.x, yaxis.x, zaxis.x, 0,
        xaxis.y, yaxis.y, zaxis.y, 0,
        xaxis.z, yaxis.z, zaxis.z, 0,
        0, 0, 0, 1

Then we will create UIPanGestureRecognizer and add it to the main view. Each time the user performs a finger move, the orientation of camera will be updated. Now we can enjoy the beauty of our skybox.

In case you need to move your camera, you may want to extract position vector from camera’s view matrix. This SO question may save you some time.

Download the project’s repo from here. In the next post we will focus on drawing a sky sphere.