After researching, I tried to implement a Vector3 object that represents a 3D point. I want to get the Normalized device coordinates, which if I understood correctly, the x, y, z values should fall in range of [-1, 1]. But my current implementation does not always fall in range. Here is the object:
WIN_SIZE: int = 800 # square window
ASPECT_RATIO: float = 1 # square window
FOV: float = math.radians(60)
SCALING_FACTOR: float = 1 / math.tan(FOV / 2)
Z_FAR: float = 100
Z_NEAR: float = 1
class Vector3:
def __init__(self, x: float, y: float, z: float) -> None:
self.x: float = x
self.y: float = y
self.z: float = z
def xyzw(self) -> np.array:
return np.array([self.x, self.y, self.z, 1])
def projection_matrix(self) -> np.array:
m = np.zeros((4, 4))
m[0, 0] = ASPECT_RATIO * SCALING_FACTOR
m[1, 1] = SCALING_FACTOR
m[2, 2] = Z_FAR / (Z_FAR - Z_NEAR)
m[2, 3] = (-Z_FAR * Z_NEAR) / (Z_FAR - Z_NEAR)
m[3, 2] = 1
return m
def normalized_device_coordinates(self) -> np.array:
result = np.dot(self.projection_matrix(), self.xyzw())
x, y, z, w = result
if w != 0:
result[0] /= w
result[1] /= w
result[2] /= w
return result
A simple test case such as Vector3(6, 0, 10).normalized_device_coordinates()
outputs [ 1.03923048, 0, 0.90909091, 10]
, which shows the x value out of the range of [-1, 1]. Are there problems with maybe my projection matrix representation?
I followed this video for the explaination of the projection matrix and NDC.