const Mat4 = require('pex-math/Mat4')

function createPerspectiveCamera (opts) {
  // const projectionMatrix = Mat4.perspective([], 60, gl.canvas.width / gl.canvas.height, 0.1, 100)
  // const viewMatrix = Mat4.lookAt([], [2, 2, 2], [0, 0, 0], [0, 1, 0])
  // const modelMatrix = Mat4.create()

  const initialState = {
    projectionMatrix: Mat4.create(),
    viewMatrix: Mat4.create(),
    position: [0, 0, 3],
    target: [0, 0, 0],
    up: [0, 1, 0],
    fov: Math.PI / 3,
    aspect: 1,
    near: 0.1,
    far: 100
  }

  function camera (opts) {
    Object.assign(camera, opts)

    if (opts.position || opts.target || opts.up) {
      Mat4.lookAt(
        camera.viewMatrix,
        camera.position,
        camera.target,
        camera.up
      )
    }

    if (opts.fov || opts.aspect || opts.near || opts.far) {
      Mat4.perspective(
        camera.projectionMatrix,
        camera.fov / Math.PI * 180,
        camera.aspect,
        camera.near,
        camera.far
      )
    }

    return camera
  }

  Object.assign(camera, initialState)

  return camera(opts)
}

module.exports = createPerspectiveCamera

@@ -32,16 +32,978 @@
 Mat4')%0A%0A
+function setFrustumOffset (camera, x, y, width, height, widthTotal, heightTotal) %7B%0A  // console.log('frustum', x, y, width, height, widthTotal, heightTotal)%0A  widthTotal = widthTotal === undefined ? width : widthTotal%0A  heightTotal = heightTotal === undefined ? height : heightTotal%0A%0A  var near = camera.near%0A  var far = camera.far%0A  var fov = camera.fov%0A%0A  var aspectRatio = widthTotal / heightTotal%0A%0A  var top = Math.tan(fov * 0.5) * near%0A  var bottom = -top%0A  var left = aspectRatio * bottom%0A  var right = aspectRatio * top%0A  var width_ = Math.abs(right - left)%0A  var height_ = Math.abs(top - bottom)%0A  var widthNormalized = width_ / widthTotal%0A  var heightNormalized = height_ / heightTotal%0A%0A  var l = left + x * widthNormalized%0A  var r = left + (x + width) * widthNormalized%0A  var b = top - (y + height) * heightNormalized%0A  var t = top - y * heightNormalized%0A%0A  camera.aspect = aspectRatio%0A  Mat4.frustum(camera.projectionMatrix, l, r, b, t, near, far)%0A%7D%0A%0A
 function
@@ -1032,24 +1032,24 @@
 ra (opts) %7B%0A
-
   // const p
@@ -1945,24 +1945,554 @@
    )%0A    %7D%0A%0A
+    if (camera.frustum) %7B%0A      // console.log('pex-cam:perspective', 'setting frustum', camera.frustum)%0A      // console.log('pex-cam:perspective', 'setting frustum before', camera.projectionMatrix)%0A      setFrustumOffset(%0A        camera,%0A        camera.frustum.offset%5B0%5D, camera.frustum.offset%5B1%5D,%0A        camera.frustum.size%5B0%5D, camera.frustum.size%5B1%5D,%0A        camera.frustum.totalSize%5B0%5D, camera.frustum.totalSize%5B1%5D%0A      )%0A      // console.log('pex-cam:perspective', 'setting frustum after', camera.projectionMatrix)%0A    %7D%0A%0A
     return c
@@ -2566,16 +2566,16 @@
 pts)%0A%7D%0A%0A
-
 module.e
@@ -2603,12 +2603,13 @@
 ctiveCamera%0A
+%0A

Add support for perspective frustum offset