我正在尝试使用 python 和 numpy 计算 MVP 转换,我的代码可能有问题,因为我最终得到 aw=0。我对照 glu 函数检查了我的截头锥体/透视图/lookat,它们似乎是正确的。由于 numpy 数组的 C 顺序,我更改了操作顺序,并按该顺序应用模型、视图和投影。在示例中,转换原点会导致 w=0 的齐次坐标,这当然会阻止我将结果除以 w。
import numpy as np
def frustum(left, right, bottom, top, znear, zfar):
M = np.zeros((4, 4), dtype=np.float32)
M[0, 0] = +2.0 * znear / (right - left)
M[2, 0] = (right + left) / (right - left)
M[1, 1] = +2.0 * znear / (top - bottom)
M[2, 1] = (top + bottom) / (top - bottom)
M[2, 2] = -(zfar + znear) / (zfar - znear)
M[3, 2] = -2.0 * znear * zfar / (zfar - znear)
M[2, 3] = -1.0
return M
def perspective(fovy, aspect, znear, zfar):
h = np.tan(fovy / 360.0 * np.pi) * znear
w = h * aspect
return frustum(-w, w, -h, h, znear, zfar)
def lookat(eye, center, up):
normalize = lambda x: x/np.linalg.norm(x)
M = np.eye(4)
eye = np.asarray(eye)
center = np.asarray(center)
z = normalize(eye-center)
x = normalize(np.cross(up,z))
y = normalize(np.cross(z,x))
M[:3,0], M[:3,1], M[:3,2], M[3,:3] = x, y, z, -eye
return M
proj = perspective(45.0, 1.0, 2.0, 100.0)
model = np.eye(4)
view = lookat([0,0,5], [0,0,0], [0,1,0])
P = [0,0,0,1]
P = proj @ view @ model @ P
print(P) # Probably wrong because P[3] = 0