(91) 350-9520 support@omarine.org M-F: 7 AM - 7 PM; Weekends: 9 AM - 5 PM

Môi trường lập trình Android, phần 1: Lập trình OpenGL ES, bài 1: Các ma trận biến đổi, mục 3: Ma trận biến đổi phép chiếu (projection transformation matrix)

frustum

Biến đổi phép chiếu thực hiện chiếu các đỉnh của đối tượng trong không gian camera xuống mặt phẳng clip gần (near clipping plane). Mặt phẳng clip gần và mặt phẳng clip xa (far clipping plane) là hai mặt phẳng vuông góc với trục z, cách camera (hay mắt người xem) các khoảng n, f tương ứng, về phía màn ảnh (theo hướng nhìn của người xem, ngược với hướng của trục z). Cảnh xem được cắt, giới hạn vào trong một hình chóp cụt, xuất phát từ một hình chữ nhật của mặt phẳng clip gần. Hình chữ nhật này ở tọa độ -n trên trục z. Theo quan sát của người xem, đỉnh góc trên, bên trái của hình chữ nhật có tọa độ theo chiều ngang (trục x) là l, có tọa độ theo chiều cao (trục y) là t. Đỉnh góc trên, bên phải có tọa độ theo chiều ngang là r, có tọa độ theo chiều cao là t. Đỉnh góc dưới, bên trái có tọa độ theo chiều ngang là l, có tọa độ theo chiều cao là b. Đỉnh góc dưới, bên phải có tọa độ theo chiều ngang là r, có tọa độ theo chiều cao là b. Tất cả các tọa độ này là trong không gian camera. Đơn vị tọa độ (độ dài của các vector cơ sở) cũng giống như trong không gian toàn cảnh vì biến đổi camera chỉ đổi cơ sở và tịnh tiến, không có scale như trong biến đổi mô hình.

Đường thẳng nối điểm camera (gốc tọa độ của không gian camera) với các đỉnh của hình chữ nhật của mặt phẳng clip gần cắt mặt phẳng clip xa tại các điểm tương ứng, cùng với các đỉnh của hình chữ nhật của mặt phẳng clip gần tạo nên một hình chóp cụt, gọi là hình chóp cụt view (view frustum). Biến đổi phép chiếu sẽ giới hạn cảnh xem trong hình chóp cụt view, những cảnh bên ngoài sẽ được cắt bỏ.

Để thực hiện điều đó, phép chiếu ánh xạ các tọa độ x, y, z vào trong các khoảng [-1,1] và loại bỏ các giá trị bên ngoài.

Ánh xạ các tọa độ x, y vào các khoảng [-1,1]

frustum2

Một điểm (xp, yp, zp) (điểm biểu diễn bởi vector (xp, yp, zp), gọi là điểm (xp, yp, zp) cho gọn) được chiếu xuống mặt phẳng clip gần bằng cách lấy giao điểm của mặt phẳng clip gần với đường thẳng đi qua điểm đó và gốc tọa độ. Gọi giao điểm đó là (xn, yn, zn). Hiển nhiên zn = -n. Chiếu không gian xuống mặt phẳng Oyz, hình chiếu tương ứng của các điểm (xp, yp, zp) và (xn, yn, -n) là (0, yp, zp) và (0, yn, -n). Chúng ta có

projection1

Khi yn = t, giá trị ánh xạ mong muốn là yp’ = 1

Khi yn = b, giá trị ánh xạ mong muốn là yp’ = -1

yp’ có thể được biểu diễn dưới dạng một ánh xạ tuyến tính theo yn như sau

yp’ = Ayn + B

Chúng ta có một hệ phương trình tuyến tính

At + B = 1

Ab + B = -1

Nhân phương trình thứ hai với -1 rồi cộng phương trình thứ nhất vào phương trình thứ hai, chúng ta được hệ phương trình đã ở dạng ma trận hệ số tam giác trên

At + B = 1

A(t – b) = 2

Từ đó

A = 2/(t – b)

B = 1 – At = 1 – 2t/(t – b) = -(t + b)/(t – b)

Vậy

projection2

Phân tích tương tự đối với tọa độ x, chúng ta được

projection3

Ánh xạ tọa độ z vào khoảng [-1,1]

Khi zp = -f, giá trị ánh xạ mong muốn là zp’ = 1

Khi zp = -n, giá trị ánh xạ mong muốn là zp’ = -1

Ánh xạ cho zp’ tuyến tính trực tiếp theo biến zp là không tiện cho biểu diễn ánh xạ theo phép nhân ma trận sau này. Chúng ta ánh xạ tới zp’ theo biến 1/zp

zp’ = A(1/zp) + B

Chúng ta có hệ phương trình tuyến tính

-A(1/f) + B = 1

-A(1/n) + B = -1

Biến đổi hệ phương trình tương tự như trên chúng ta được

-A(1/f) + B = 1

A(f – n)/fn = 2

Kết quả là

A = 2fn/(f – n)

B = 1 + 2fn(1/f)/(f – n) = 1 + 2n/(f – n) = (f + n)/(f – n)

Vậy

projection4

Các ánh xạ trên được biểu diễn dưới dạng tích ma trận như sau

projection5

Ma trận vuông cấp 4 ở trên chính là ma trận phép chiếu

projection6

Như vậy

projection7

Suy ra

projection8

Công thức trên có thể được diễn giải như sau: Khi chúng ta nhân bên trái tọa độ camera với ma trận Mprojection, kết quả được tọa độ vế trái, tọa độ này được gọi là tọa độ clip

projection9

Trong chương trình, người lập trình sẽ đặt tọa độ clip vào biến gl_Position của OpenGL. Biến này là một vector 4 chiều (kiểu vec4 trong OpenGL). Thành phần thứ tư của nó là gl_Position.w sẽ chứa giá trị wc ở trên. OpenGL thực hiện phép chia phối cảnh bằng cách chia các thành phần của gl_Position bởi gl_Position.w, và được tọa độ thiết bị chuẩn hóa

projection10

Như đã phân tích lý thuyết ở trên, tọa độ thiết bị chuẩn hóa mới là tọa độ trong khoảng [-1,1], làm tọa độ đầu vào cho biến đổi viewport sau này.

Ma trận phép chiếu theo góc nhìn (fovy)

Ma trận phép chiếu thường được sử dụng trong thực tế là ma trận phép chiếu theo góc nhìn, là trường hợp đặc biệt của ma trận trên. Khi hình chữ nhật của mặt phẳng clip gần (và do đó của mặt phẳng clip xa) được bố trí cân đối thì tâm của nó nằm trên trục z. Trong trường hợp này, l + r = t + b = 0. Ngoài ra, (t – b)/2/n = tan(fovy/2). Trong đó, fovy là góc nhìn theo chiều thẳng đứng. Nếu tỉ lệ màn hình là a (a = chiều rộng/chiều cao) thì (r – l)/2/n = a*(t – b)/2/n = a*tan(fovy/2). Gọi d = 1/tan( fovy/2), chúng ta có

2*n/(r-l) = d/a

2*n/(t-b) = d

Ma trận phép chiếu trở thành

projection11

Phép chiếu trực giao (orthographic projection)

Phép chiếu trực giao là phép chiếu đơn giản. Các tọa độ x, y kết quả không phụ thuộc vào tọa độ z đầu vào. Tuy nhiên, đây không phải là phép chiếu giống như chúng ta chiếu một đường thẳng vuông góc xuống một mặt phẳng, tọa độ z vẫn được xử lý và vẫn được ánh xạ vào khoảng [-1,1]. Hình chóp cụt trở thành hình hộp. Tọa độ clip cũng là tọa độ thiết bị chuẩn hóa. Ma trận của biến đổi này như sau

projection12

 

Advertisements

Gửi phản hồi

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.

%d bloggers like this: