Khóa luận Nghiên cứu và xây dựng thử nghiệm 3D Engine - Phần 6

light vector. Vector hướng ánh sáng trong không gian tiếp tuyến (tangent

space), vector này được tính trong Vertex Shader và được truyền vào Pixel Shader

đểsửdụng.

view vector. Vector tính từmắt đến điểm nhìn (tọa độtrong không gian tiếp

tuyến), vector này được tính trong Vertex Shader và truyền vào Pixel Shader đểsử

dụng.

specular constant. Hằng phản chiếu, giá trịcàng lớn thì vùng phản chiếu

càng nhỏ.

pdf17 trang | Chuyên mục: Mạng Máy Tính | Chia sẻ: dkS00TYs | Lượt xem: 1545 | Lượt tải: 0download
Tóm tắt nội dung Khóa luận Nghiên cứu và xây dựng thử nghiệm 3D Engine - Phần 6, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
 liệu 3D đặc trưng cần phải nạp từ tập tin md5 phải 
tổ chức thành các dữ liệu cấu trúc: 
 Các dữ liệu về khớp: chỉ số, tên, chỉ số khớp cha, tên khớp cha, vector chỉ vị 
trí ban đầu, quaternion xác định góc quay ban đầu. 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 85 - 
 Dữ liệu về các đỉnh: u, v (tọa độ texture), chỉ số trọng số và số trong số kết 
nối với đỉnh. 
 Dữ liệu về các mặt: gồm chỉ số của 3 đỉnh hình thành nên một mặt. 
 Dữ liệu về trọng số: chỉ số của khớp và trọng số tương ứng. 
 Dữ liệu mesh: tên, danh sách đỉnh, danh sách mặt, danh sách các trong số. 
 Dữ liệu cho các khung hình: bao gồm vector và quaternion cho mỗi khung 
hình. 
 Dữ liệu diễn hoạt: khớp hiện tại, khớp cha, danh sách khung hình diễn hoạt, 
khung hình cơ sở, thuộc tính md5 của khớp (nhằm xác định sự thay đổi dữ liệu các 
các khung hình so với khung hình cơ sở). 
 Việc lưu lại thông tin nạp từ tập tin một cách tinh tế, hiệu quả còn giúp cho ta 
tiết kiệm bộ nhớ rất lớn. Giả sử như ta có 2 con quái vật giống hệt nhau cùng xuất 
hiện trong màn Game thì 2 con quái vật này phải cùng truy xuất đến một dữ liệu đã 
nạp. Có nghĩa là nếu dữ liêu cho con quái vật đã nạp từ trước thì ta không cần nạp 
nữa mà chỉ truy xuất đến dữ liệu dùng chung đã nạp mà thôi. Nếu ta không chú ý 
đến vấn đền này thì sẽ gây lãng phí rất lớn về bộ nhớ và thời gian nạp dữ liệu. Để 
giải quyết thì ta chỉ thực hiện nạp dữ liệu một lần (vào lần đầu tiên yêu cầu dữ 
liệu), khi cần dùng ta dùng các con trỏ chỉ đến dữ liệu và xử lý. Ta không được 
thay đổi các dữ liệu gốc nạp từ tập tin để đảm bảo không ảnh hưởng đến các đối 
tượng đang sử dụng chung dữ liệu. 
 Việc đọc dữ liệu sẽ được đọc theo trình tự bố trí dữ liệu trong tập tin md5 với sự 
hỗ trợ của một công cụ cho phép ta phân tích tập tin để tìm thông tin chính xác và 
nhanh. 
5.2.2. Vấn đề về khung xương 
5.2.2.1. Giới thiệu về khung xương 
 Các đối tượng mà hệ thống diễn hoạt điều khiển thông thường có cấu trúc là một 
khung xương. Khung xương là một cấu trúc cây trong đó mỗi nút tương ứng với 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 86 - 
một khớp xương. Mỗi nút trong khung xương sẽ có một nút cha (trừ nút đầu tiên) và 
có thể có nhiều nút con. Hình dưới là một ví dụ về khung xương: 
Hình 5-1 Ví dụ cấu trúc khung xương 
 Khi đối tượng chuyển động thì các xương của nó chuyển động. Trong cấu trúc 
khung xương thì chuyển động chủ yếu là chuyển động quay ví dụ như ta đưa tay lên 
thật chất là ta quay xương cánh tay quanh khuỷ tay một góc. Trong cấu trúc khung 
xương có một tính chất biến đổi quan trọng là sự chuyển động của một khớp sẽ 
được kế thừa chuyển động từ khớp cha của nó. Như vậy khi cần cập nhật lại khung 
xương thì ta phải cập nhật từ nút gốc trở đi. Nếu ta thực hiện biến đổi trên nút gốc 
thì biến đổi đó ảnh hưởng toàn khung xương, ví dụ như ta dịch chuyển nút gốc đi vị 
trí khác thì toàn bộ khung xương sẽ bị dịch theo. 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 87 - 
5.2.2.2. Tổ chức dữ liệu 
 Vấn đề đầu tiên là ta phải tổ chức dữ liệu cho khung xương làm sao để ta có thể 
tách rời các phần của cơ thể ví dụ như phần thân, phần đầu ra thành các phần độc 
lập nhau? Việc phân tách giúp ta có thể điều khiển từng thành phần riêng biệt và 
đặc biệt ta có thể thay đổi hình dạng cho nhân vật. Chúng ta có thể gắn các đầu khác 
nhau vào trong cùng một thân hình để tạo ra các nhân vật khác nhau. Và làm sao ta 
có thể gắn thêm các phần khác vào trong cấu trúc khung xương? Ví dụ như khi nhân 
vật cầm một khẩu súng thì làm sao ta có thể gắn khẩu súng này vào tay nhân vật và 
chuyển động của khẩu súng khớp với chuyển động của tay. 
 Để giải quyết được vấn đề này ta sẽ cho các nút trong cấu trúc cây của khung 
xương kế thừa từ một cấu trúc dữ liệu đặc biệt chỉ chứa các dữ liệu biến đổi. Việc tổ 
chức dữ liệu này tương tự như khái niệm Scene Graph được dùng rất nhiều trong 
việc quản lý Game. Một nút biến đổi (transform node) sẽ lưu các thông tin sau: 
 Tên. 
 Nút cha của nó. 
 Vị trí và góc quay ban đầu. 
 Vị trí và góc quay trong mối quan hệ với nút cha. 
 Vị trí, góc quay và ma trận biến đổi so với thể giới (vị trí và góc quay thật sự 
trong cảnh 3D). 
 Việc biến đổi của các khớp xương chính là sự biến đổi của các nút biến đổi. Bây 
giờ ta có thể tạo ra các cấu trúc khung xương riêng cho phần thân, phần đầu. Sau đó 
ta sẽ gắn đầu vào thân bằng cách ta thực hiện viện gán nút đều tiên của đầu là nút 
con của đốt xương cổ của phần thân. 
 Tương tự như vậy, nếu ta muốn cho nhân vật cầm một cây súng thì ta cũng tạo 
ra một cầu trúc khung xương cho cây súng. Sau đó ta thực thực việc thiết lập nút 
cha của cây súng là một khớp xương ở tay, bây giờ biến đổi của cây súng sẽ phụ 
thuộc vào biến đổi của khớp xương tay. 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 88 - 
 Rõ ràng việc tổ chức dữ liệu như vậy giúp ta giải quyết được nhiều vấn đề và 
giúp ta quản lý các đối tượng dễ dàng và thống nhất. Một cách tổng quát, ta có thể 
tạo một cây kế thừa kết nối tất cả các đối tượng có cấu trúc khung xương. Việc tìm 
kiếm, cập nhật và hiển thị sẽ đều thực hiện trên cây chung này. Đây cũng chính là ý 
tưởng và cách thức thực hiện của một Scene Graph. 
 Vấn đề tiếp theo là làm sao ta có thể thực hiện việc cập nhật và truy xuất các 
khớp trong khung xương nhanh chóng và phù hợp với việc tổ chứa dữ liệu trên tập 
tin md5? 
 Dựa vào đặc điểm tập tin md5 lưu các khớp trong một khung xương theo một 
trình tự tăng dần của các khớp xương ta có thể có cách tổ chức dữ liệu tương ứng. 
Nếu ta tổ chức các khớp trong khung xương là các cấu trúc trong đó có các con trỏ 
chỉ đển các nút con thì đây là cách tổ chức sát với khái niệm của cấu trúc xương. 
Tuy nhiên việc tổ chức như vậy thì cứ mỗi lần cập nhật hoặc tìm kiếm một khớp 
xương theo tên hoặc theo chỉ số định danh ta cần phải duyệt cây theo đệ quy. Do 
thao tác tìm kiếm và duyệt như vậy dùng với tần suất rất lớn sẽ làm cho chi phí tăng 
nhanh. Để khắc phục vấn đề này, ta đơn giản sẽ tổ chức các khớp của khung xương 
thành một mảng. Khi đó việc tìm kiếm một khớp xương theo chỉ số ta sẽ thực hiện 
truy xuất thẳng đến phần tử có thỉ số tương ứng trong mảng. Như vậy, với một cải 
tiến nhỏ ta đã giảm đi được rất nhiều chi phí trong việc tìm kiếm. 
5.2.2.3. Cập nhật và di chuyển khung xương 
 Mỗi một nhân vật là một cấu trúc khung xương. Trong cấu trúc khung xương 
này ta có một nút là nút gốc (nút này không có nút cha). Mọi thao tác xử lý trên 
khung xương phải được bắt đầu từ nút gốc này. 
 Việc cập nhật lại khung xương phải được thực hiện thường xuyên để phù hợp 
với diễn hoạt. Việc cập nhật đơn giản ta sẽ thực hiện việc cập nhật lại vị trí và góc 
quay hay là ma trận biến đổi cho tứng khớp trong khung xương bắt đầu từ nút gốc. 
Biến đổi của một nút sẽ bằng biến đổi của nút cha nhân với biến đổi của nó với nút 
cha. 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 89 - 
 Bên cạnh việc biến đổi trong cấu trúc khung xương thì ta cần toàn bộ khung 
xương biến đổi như di chuyển vị trí, thay đổi góc quay so với lại thế giới trong 
Game. Để thực hiện việc đó ta phải có các biến để lưu vị trí và góc quay hiện thời 
của nút gốc. Ta sẽ thực hiện việc cập nhật toàn bộ khung xương với từ nút gốc với 
vị trí và gốc quay là vị trí và góc quay hiện thời đang lưu. 
5.2.3. Đường dẫn định hướng cho diễn hoạt 
5.2.3.1. Giới thiệu về đường định hướng 
 Bên cạnh việc xây dựng diễn hoạt cho bản thân khung xương, trong nhiều tình 
huống ta cần áp đặt nhân vật di chuyển theo một lộ trình nào đó. Để có thể thực 
hiện được ta sẽ qui định ra một lộ trình trong đó gồm nhiều con đường kết nối với 
nhau. Việc sử dụng đường định hướng cho nhân vật là tuỳ chọn. 
5.2.3.2. Cập nhật biến đổi trên các đường cơ bản 
 Như đã nói, một lộ trình cho nhân vật đi theo sẽ bao gồm trong đó nhiều đường 
cơ bản. Trong hệ thống diễn hoạt của mình, chúng tôi đã xây dựng các 2 loại đường 
cơ bản là đường thẳng và đường cong Bezier. 
 Để nhân vật di chuyển theo đường thì ta sẽ tính vị trí và vector pháp tuyến cho 
nhân vật vào từng thời điểm dựa theo thời gian đã trôi qua kể từ khi nhân vật di 
chuyển. Sau khi đã biết vị trí và góc quay hiện tại của nhân vật ta sẽ thiết lập vào 
giá trị vị trí và góc quay của nút gốc của cấu trúc cây của khung xương. 
¾ Đối với đường thẳng: 
Hình 5-2 Ví dụ đường đi thẳng 
Dựa vào quảng đường đi được của đối tượng từ điểm đầu tiên ta tính được 
 s = khoảng cách / độ dài quảng đường 
 vị trí hiện tại = vị trí đầu + s*(vị trí cuối - vị trí đầu) 
 Còn hướng là là hướng của đường thẳng (vector cuối – vector đầu) 
 Chương 5. Hệ thống diễn hoạt (Animation System) 
 - 90 - 
¾ Đối với đường cong Bezier: 
 Một đường cong Bezier được xác định bằng 4 điểm: điểm đầu, điểm cuối và 2 
điểm điều khiển. Ví dụ ta có đường cong Bezier sau: 
Hình 5-3 Ví dụ đường đi Bezier 
 Ở đây chúng tôi không đi sâu vào đường cong Bezier về mặt toán học mà chỉ đề 
cập đến các công thức dùng trong lập trình. Phương trình toán của đường cong 
Bezier như sau: 
C(s) = P1*(1-s)3 + P2*3*s*(1-s)2 + P3*3*s2*(1-s) + P4*s3 với s là hệ số 
tỉ lệ: 
 s = khoảng cách đền điểm đầu tiên / khoảng cách cả đường cong. 
 Khoảng cách cả đường cong được xác định gần đúng như sau: 
 Gọi length1 = Khoảng cách từ điểm P1 đến P2. 
 length2 = Khoảng cách từ điểm P2 đến P3. 
 length3 = Khoảng cách từ điểm P3 đến P4. 
 length4 = Khoảng cách từ điểm P1 đến P4. 
Khoảng cách quảng đường = (length1 + length2 + length3)*0.5 + length4*0.5 
 Giả sử ta đã có 4 vector cho biết vị trí của các điểm là P1, P2, P3, P4 là vec1, 
vec2, vec3, vec 4 và ta cần tính vector hiện tại của một điểm cách điểm đầu một 
khoảng nào đó, ta thực hiện như sau: 
 Ta tính s dựa trên công thức ở trên. 
 Gọi vecOut là vector vị trí của điểm hiện tại ta có: 
 vecOut = vec1*(1-s)3 + vec2*s*(1-s)2 + vec3*s2*(1-s) + vec4*s3. 
 Và tiếp tuyến được tính bằng cách lấy đạo hàm của phương trình đường cong. 

File đính kèm:

  • pdfthu_nghiem_3d_engine_6.pdf
Tài liệu liên quan