zworld-demo/plugin/math/mat4/project.go

68 lines
1.5 KiB
Go
Raw Normal View History

2023-12-22 22:04:27 +08:00
package mat4
import (
"zworld/plugin/math"
"zworld/plugin/math/vec3"
)
// Orthographic generates a left-handed orthographic projection matrix.
// Outputs depth values in the range [0, 1]
func Orthographic(left, right, bottom, top, near, far float32) T {
rml, tmb, fmn := (right - left), (top - bottom), (far - near)
return T{
2 / rml, 0, 0, 0,
0, 2 / tmb, 0, 0,
0, 0, 1 / fmn, 0,
(right + left) / rml,
-(top + bottom) / tmb,
-near / fmn,
1,
}
}
// OrthographicRZ generates a left-handed orthographic projection matrix.
// Outputs depth values in the range [1, 0] (reverse Z)
func OrthographicRZ(left, right, bottom, top, near, far float32) T {
rml, tmb, fmn := (right - left), (top - bottom), (near - far)
return T{
2 / rml, 0, 0, 0,
0, 2 / tmb, 0, 0,
0, 0, 1 / fmn, 0,
-(right + left) / rml,
-(top + bottom) / tmb,
near / fmn,
1,
}
}
// Perspective generates a left-handed perspective projection matrix with reversed depth.
// Outputs depth values in the range [0, 1]
func Perspective(fovy, aspect, near, far float32) T {
fovy = math.DegToRad(fovy)
tanHalfFov := math.Tan(fovy) / 2
return T{
1 / (aspect * tanHalfFov), 0, 0, 0,
0, -1 / tanHalfFov, 0, 0,
0, 0, far / (far - near), 1,
0, 0, -(far * near) / (far - near), 0,
}
}
func LookAt(eye, center, up vec3.T) T {
f := center.Sub(eye).Normalized()
r := vec3.Cross(up, f).Normalized()
u := vec3.Cross(f, r)
M := T{
r.X, u.X, f.X, 0,
r.Y, u.Y, f.Y, 0,
r.Z, u.Z, f.Z, 0,
0, 0, 0, 1,
}
et := Translate(eye.Scaled(-1))
return M.Mul(&et)
}