Calculating the Normalized Device Coordinates from World Coordinates

41 Views Asked by At

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.

0

There are 0 best solutions below