Thiết kế chức năng

Một phần của tài liệu Xây dựng game engine đa nền tảng quản lý khung cảnh (Trang 28 - 41)

Chức năng chính của module này là render toàn bộ cây khung cảnh. Quá trình render trải qua những bước sau :

- Bước 1 – prepare-render : duyệt cây theo chiều sâu, tại mỗi node, thực hiện tất cả các animation, kiểm tra trạng thái của node để xác định xem có cần tính lại các ma trận biến đổi không.

- Bước 2 – Tính lại BVHs : Duyệt cây theo thứ tự sau (postfix) ,kiểm tra cờ trạng thái, tính lại tree bounding volume của node nếu cần thiết.

- Bước 3 – Tính lại các ma trận biến đổi của Camera và tính khung nhìn. - Bước 4 – view frustum culling : phát hiện các node nằm bên ngoài khung nhìn và loại chúng ra khỏi quá trình render.

- Bước 5 - Render từng render-list : tùy vào các trạng thái render nằm trong render context, các node trong render-list có thể sẽ được sắp xếp theo khoảng cách đến camera, thực hiện occlusion culling mới được render.

Hình 18: Biều đồ hoạt động của giai đoạn prepare-render. Quá trình prepare-render trải qua các bước như sau :

- Bước 1 : Đi đến node tiếp theo theo chiều sâu.

- Bước 2 : Gọi hàm animated() của node. Hàm này sẽ thực thi tất cả các animation có trong animationList của node này.

- Bước 3 : Kiểm tra các cờ trạng thái liên quan đến ma trận biến đổi và tính lại các ma trận nếu cần thiết. Trong đó :

+ UPDATE_SCALE_MATRIX : khi cờ này được bật, nghĩa là node này bị thay đổi về độ phóng to ( hoặc thu nhỏ ) so với khung hình trước, do đó sẽ phải tính lại ma trận phóng của node.

+ UPDATE_ROTATION_MATRIX : khi cờ này được bật, nghĩa là node này bị thay đổi về góc quay ( hoặc độ quay ) so với khung hình trước, do đó phải tính lại ma trận quay của node.

+ UPDATE_TRANSLATE_MATRIX : khi cờ này được bật, nghĩa là node này bị dịch chuyển vị trí so với khung hình trước, do đó phải tính lại ma trận dịch của node.

+ PARENT_MATRIX_CHANGE : khi cờ này được bật nghĩa là ma trận biến đổi của node cha bị thay đổi, hay chính là không gian của node cha bị thay đổi.

Nếu một trong các cờ trên được bật, thì node sẽ phải tính lại modelMatrix theo công thức như trong hình vẽ.

modelMatrix là ma trận biến đổi không gian của node sang không gian thế giới, được sử dụng trong quá trình render vật thể.

- Bước 4 : Nếu node này phải tính lại modelMatrix ( nghĩa là không gian của nó bị thay đổi so với khung hình trước ) ta phải bật một số cờ ở các node con và node tổ tiên ( node cha, node ông.. ) của node này.

Cụ thể :

+ Bật cờ PARENT_MATRIX_CHANGE ở các node con ( thông báo không gian của node cha bị thay đổi )

+ Bật cờ UPDATE_TREE_BOUNDING_VOLUME ở các node tổ tiên, thông báo các node đó sẽ phải tính lại tree bounding volume trong quá trình Tính lại BVHs ( xem chi tiết trong phần b của chương này ).

3.3.2. Tính lại BVHs

Hình 19: Biều đồ hoạt động của giai đoạn Tính lại BVHs.

Quá trình tính lại BVHs như sau : duyệt cây Scene Graph theo thứ tự sau ( do phải có tree bounding volume của node con mới tính được tree bounding volume của node cha ) :

- Tại mỗi node, kiểm tra cờ UPDATE_TREE_BOUNDING_VOLUME. Cờ này được bật khi một trong những node con bị biến đổi về không gian hoặc khi thêm bớt node con ( so với khung hình trước ).

- Nếu cờ được bật, tính lại tree bounding volume của node theo công thức : tree BV = tổng ( tree BV của tất cả các node con ) + BV của node này.

3.3.3. Tính lại các ma trận biến đổi của Camera và tính khung nhìn

Camera là đối tượng mô phỏng mắt người trong Scene Graph. Tức là chúng ta sẽ thu hình ảnh ở vị trí đặt camera.

Camera sẽ lưu trữ và tính toán 2 ma trận biến đổi view matrix và project matrix :

+ View matrix : là ma trận biến đổi không gian thế giới sang không gian nhìn.

+ Project matrix : là ma trận biến đổi từ không gian nhìn sang không gian chiếu.

b.Quá trình tính lại view matrix và project matrix

Trước tiên, ta kiểm tra các cờ trạng thái của active camera để xác định xem có cần tính lại các ma trận biến đổi hay không :

+ Nếu cờ UPDATE_VIEW_MATRIX hoặc PARENT_MATRIX_CHANGE

được bật : tính lại view matrix từ vị trí đặt, vector up và hướng nhìn của camera.

+ Nếu cờ UPDATE_PROJECTION_MATRIX được bật : tính lại projection matrix từ các thuộc tính m_Near,m_Far, m_Bottom, m_Top, m_Right, m_Left của camera ( Xem lại lớp Camera trong 4.2.1.d.Các loại node cơ bản ).

c.Tính khung nhìn

Khái niệm khung nhìn : là không gian mà chỉ những đối tượng nằm trong ( hoặc một phần nằm trong ) mới được nhìn thấy bởi camera. Ở đây camera hoạt động theo phép chiếu phối cảnh nên khung nhìn là một hình chop cụt do 6 mặt phẳng ghép lại : near, far, top, bottom, right, left.

Hình 20: Ví dụ minh họa khung hình.

Chúng tôi sử dụng phương pháp tính 6 mặt phẳng tạo nên khung nhìn từ view matrix và projection matrix theo [2].

3.3.4. View frustum culling

a. Khái niệm view frustum culling

Ta đã biết chỉ các vật thể nằm trong ( hoặc một phần nằm trong ) khung nhìn mới được nhìn thấy. Như vậy, nếu xác định được node nào nằm bên ngoài view frustum, ta có thể loại nó ra khỏi quá trình render.

Để đơn giản hóa việc kiểm tra xem một node có nằm ngoài khung nhìn hay không, ta sử dụng Bounding Volume của nó để kiểm tra ( do Bounding Volume có hình dạng rất đơn giản hơn nhiều so với bản thân vật thể).

View frustum culling là việc phát hiện các node nằm bên ngoài frustum đựa vào BVHs là loại chúng ra khỏi quá trình render.

b. Quá trình thực hiện view frustum culling

Hình 21: Biều đồ hoạt động giai đoạn view frustum culling.

Thực hiện view frustum culling như sau : Duyệt cây khung cảnh theo chiều sâu - Tại mỗi node, kiểm tra vị trí của tree bounding sphere so với khung nhìn ( tree bounding sphere là một trong hai loại tree BV của mỗi SceneNode ) :

+ Nếu nằm trong : toàn bộ nhánh cây với gốc là node này nằm trong khung nhìn, không cần duyệt các node thuộc nhánh này nữa. + Nếu nằm ngoài : toàn bộ nhánh cây với gốc là node này nằm ngoài khung nhìn, toàn bộ node trong nhánh nằm bị bật cờ trạng thái FRUSTUM_CULLED ( đánh dấu đã bị cắt ) và không cần duyệt đến các node thuộc nhánh này nữa.

+ Nếu giao : kiểm tra vị trí của tree bounding box so với khung nhìn ( vì bounding box bó sát vật thể hơn nhiều so với bounding sphere ).

# Nằm trong : toàn bộ nhánh cây với gốc là node này nằm trong khung nhìn, không cần duyệt các node thuộc nhánh này nữa.

# Nằm ngoài : toàn bộ nhánh cây với gốc là node này nằm ngoài khung nhìn, toàn bộ node trong nhánh nằm bị bật cờ trạng thái FRUSTUM_CULLED ( đánh dấu đã bị cắt ) và không cần duyệt đến các node thuộc nhánh này nữa.

# Giao : không kết luận gì, đi đến node tiếp theo.

c. Thuật toán kiểm tra vị trí của bounding sphere so với khung nhìn

Để kiểm tra ví trị của một bounding sphere so với frustum, ta thực hiện như sau :

Với từng mặt phẳng của Frustum :

+ Tính khoảng cách d từ tâm đến mặt phẳng

+ Nếu d < -R. Kết luận: bounding sphere nằm bên ngoài frustum + Nếu R > d > -R. Kết luận: bounding sphere giao với frustum Ngược lại, kết luận bounding sphere nằm bên ngoài Frustum ( R là bán kính của bounding sphere )

Hình 22: Ví dụ một Bounding Sphere có d > R.

d. Thuật toán kiểm tra vị trí của bounding box với khung nhìn

Thuật toán cơ bản để kiểm tra ví trí của bounding box với frustum là kiểm tra vị trí của 8 đỉnh của bounding box so với khung nhìn :

- Nếu tất cả các đỉnh đều nằm trong thì kết luận bounding box nằm trong.

- Nếu tất cả các đỉnh nằm ngoài thì kết luận bounding box nằm ngoài.

- Các trường hợp còn lại kết luận bounding box giao với khung nhìn.

Có nhiều tối ưu cho thuật toán trên và chúng tôi đã triển khai các tối ưu trong [3]

3.3.5. Render các render-list

a. Khái niệm render-list

Một render-list là tập hợp các Scene Node có chung các trạng thái render. Các trạng thái render ở đây là các trạng thái của openGL và một số trạng thái khác của GEM. Việc tập trung các Scene Node thành các render list sẽ hạn chế tối đa

việc chuyển các trạng thái render, giúp tăng hiệu suất hệ thống. Một Scene Node có thể cùng lúc ở nhiều render-list.

b. Các render list của GEM

Trong GEM có 16 render list sau :

- ERL_SKY_BOX : Render list đặc biệt dành cho SkyboxSceneNode, do loại node này phải đặt một số trạng thái render đặc biệt.

- ERL_LIGHT : Render list đặc biệt dành cho các nguồn chiếu sáng (LightSceneNode và DLightSceneNode ).

- ERL_SOLID : Render list mặc định dành cho các loại node có dạng đặc ( không nhìn xuyên qua được ).

- ERL_TRANLUCENT : Render list mặc định dành cho các loại node có dạng trong suốt ( hình xuyên qua được ).

- ERL_USER_DEFINE0 -> 9 : 10 Render list dành sẵn cho người sử dụng tùy biến.

- ERL_SHADOW_VOLUME : Render list đặc biệt dành để render bóng của vật thể.

- ERL_OCCLUSION_TEST : Render list dùng trong quá trình occlusion culling.

Hình 23: Biều đồ hoạt động của giai đoạn render từng render-list. Quá trình render các render list như sau :

- Bước 2 : bật các trạng thái render cần thiết được lưu trong render context của list ( gọi hàm pushState() của RenderContext )

- Bước 3: Sắp xếp list theo khoảng cách đến camera theo thứ tự từ xa đến gần hoặc ngược lại ( nếu trong render context có trạng thái yêu cầu sắp xếp các node ).

- Bước 4 : Loại bỏ các node có cờ FRUSTUM_CULLED được bật ( do các node nằm ngoài khung nhìn ).

- Bước 5 : Kiểm tra xem list có thực hiện occlusion culling hay không : + Nếu không : render toàn bộ các node trong list.

+ Nếu có : thực hiện thuật toán occlusion culling/

+ Bước 6 : Phục hồi toàn bộ các trạng thái render được bật trong bước 2 ( gọi hàm popState() của RenderContext )

e.Occlusion culling

Occlusion culling là việc phát hiện các vật thể bị chắn hoàn toàn bởi các vật thể khác và loại chúng ra khỏi quá trinh render.

Hình 24: Ví dụ minh họa một vật thể bị chắn hoàn toàn.

Chúng tôi triển khai thuật toán occlusion culling được trình bày trong [4].

Chương 4. Tổng kết

Một phần của tài liệu Xây dựng game engine đa nền tảng quản lý khung cảnh (Trang 28 - 41)

Tải bản đầy đủ (DOC)

(47 trang)
w