geomancy-0.2.2.3: src/Geomancy/Vulkan/Projection.hs
module Geomancy.Vulkan.Projection
( perspective
, infinitePerspective
, orthoOffCenter
) where
import Geomancy.Mat4 (colMajor)
import Geomancy.Transform (Transform(..))
perspective
:: Integral side
=> Float
-> Float -> Float
-> side -> side
-> Transform
perspective fovRads near far width height = colMajor
x 0 0 0
0 y 0 0
0 0 z w23
0 0 w32 1
where
x = cotFoV * aspectX
y = -cotFoV
z = far / (near - far)
w23 = near * far / (near - far)
w32 = -1
cotFoV = recip . tan $ 0.5 * fovRads
aspectX = fromIntegral height / fromIntegral width
infinitePerspective
:: Integral side
=> Float
-> side
-> side
-> Transform
infinitePerspective fovRads width height = colMajor
x 0 0 0
0 (-y) 0 0
0 0 (-1) w
0 0 (-1) 0
where
(x, y) =
if width > height then
( cotFoV / camAspect
, cotFoV
)
else
( cotFoV
, cotFoV * camAspect
)
camAspect = fromIntegral width / fromIntegral height
cotFoV = recip . tan $ 0.5 * fovRads
w = -2 * near
near = 1/128 -- 2048
orthoOffCenter :: Integral side => Float -> Float -> side -> side -> Transform
orthoOffCenter near far width height = colMajor
x 0 0 0
0 y 0 0
0 0 z w
0 0 0 1
where
x = 2 / fromIntegral width
y = 2 / fromIntegral height
z = 1 / (far - near)
w = near * (near - far)