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 :: Float -> Float -> Float -> side -> side -> Transform
perspective Float
fovRads Float
near Float
far side
width side
height = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Transform
forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 Float
y Float
0 Float
0
Float
0 Float
0 Float
z Float
w23
Float
0 Float
0 Float
w32 Float
1
where
x :: Float
x = Float
cotFoV Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
aspectX
y :: Float
y = -Float
cotFoV
z :: Float
z = Float
far Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
far)
w23 :: Float
w23 = Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
far Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
far)
w32 :: Float
w32 = -Float
1
cotFoV :: Float
cotFoV = Float -> Float
forall a. Fractional a => a -> a
recip (Float -> Float) -> (Float -> Float) -> Float -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Float
forall a. Floating a => a -> a
tan (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
fovRads
aspectX :: Float
aspectX = side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width
infinitePerspective
:: Integral side
=> Float
-> side
-> side
-> Transform
infinitePerspective :: Float -> side -> side -> Transform
infinitePerspective Float
fovRads side
width side
height = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Transform
forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 (-Float
y) Float
0 Float
0
Float
0 Float
0 (-Float
1) Float
w
Float
0 Float
0 (-Float
1) Float
0
where
(Float
x, Float
y) =
if side
width side -> side -> Bool
forall a. Ord a => a -> a -> Bool
> side
height then
( Float
cotFoV Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
camAspect
, Float
cotFoV
)
else
( Float
cotFoV
, Float
cotFoV Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
camAspect
)
camAspect :: Float
camAspect = side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height
cotFoV :: Float
cotFoV = Float -> Float
forall a. Fractional a => a -> a
recip (Float -> Float) -> (Float -> Float) -> Float -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Float
forall a. Floating a => a -> a
tan (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
0.5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
fovRads
w :: Float
w = -Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
near
near :: Float
near = Float
1Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
128
orthoOffCenter :: Integral side => Float -> Float -> side -> side -> Transform
orthoOffCenter :: Float -> Float -> side -> side -> Transform
orthoOffCenter Float
near Float
far side
width side
height = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Transform
forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 Float
y Float
0 Float
0
Float
0 Float
0 Float
z Float
w
Float
0 Float
0 Float
0 Float
1
where
x :: Float
x = Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width
y :: Float
y = Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ side -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height
z :: Float
z = Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
near)
w :: Float
w = Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
far)