Vector pháp tuyến của mặt phẳng

Một phần của tài liệu Billboard và giả lập mô hình 3D trong thực tại ảo (Trang 33)

Vì ta thường làm việc với các mặt bao quanh đối tượng nên ta cần phân biệt hai mặt của mặt phẳng. Mặt tiếp giáp với phần bên trong của đối tượng ta gọi là mặt trong, mặt kia là mặt ngoài. Nếu các cạnh của đa giác được mô tả theo chiều ngược chiều kim đồng hồ, vector pháp tuyến của mặt phẳng sẽ hướng từ trong ra ngoài (giả sử hệ tọa độ biểu diễn đối tượng là hệ tọa độ bàn tay phải). Ví dụ, trong hình 1.15, vector pháp tuyến của mặt phải của khối lập phương đơn vị (mặt được tô) có phương trình mặt phẳng là x-1=0 và có vector pháp tuyến tương ứng là (1,0,0);

Phương trình mặt phẳng còn có thể dùng để xác định vị trí tương đối giữa một điểm trong không gian với mặt phẳng. Nếu điểm P(x,y,z) không nằm trên mặt phẳng, lúc đó ta có:

Ax + By + Cz + D <> 0

Ta có thể xác định P nằm ở phía trong hay nằm phía ngoài của mặt phẳng nhờ vào dấu của biểu thức Ax + By + Cz + D:

 Nếu Ax + By + Cz + D < 0, điểm P(x,y,z) nằm trong.

 Nếu Ax + By + Cz + D > 0, điểm P(x,y,z) nằm ngoài.

Dấu hiệu kiểm tra trên đúng cho hệ tọa độ bàn tay phải và phương trình mặt phẳng được tính từ tọa độ các đỉnh đa giác cho theo chiều ngược chiều kim đồng hồ.

Đôi khi, sẽ rất hữu ích nếu ta khảo sát các đường và mặt thông qua phương trình tham số của nó.

Phương trình tham số của một mặt là một phương trình có hai tham số u, v. Một điểm bất kì trên mặt sẽ có tọa độ được biểu diễn dưới dạng vector tham số : p(u, v) = (x(u, v), y(u, v), z(u, v)). Với mỗi cặp giá trị (u, v) ta sẽ có một bộ các tọa độ (x, y, z) biểu diễn một điểm trên bề mặt đã cho. Các mặt sẽ được phân biệt với nhau bằng các bộ hàm x(), y(), z() khác nhau.

Để giới hạn không gian của các mặt, thông thường người ta định lại các tọa độ biên sao cho u, v tương ứng biến đổi trong đoạn 0,1 . Ví dụ, một mặt cầu với bán kính r, tâm tại gốc tọa độ có thể biểu diễn bằng các phương trình sau :

x(u, v) = r sin(p u) cos(2p v) y(u, v) = r sin(p u) sin(2p v) z(u, v) = r cos(p u)

Trong đó u, v thay đổi trong đoạn 0,1 .

Một mặt phẳng có thể được xác định bằng một điểm với vector vị trí c và hai vector a, b không cùng phương (xem hình 1.16).

1.16 Minh họa cách xác định mặt phẳng

Nhận xét rằng bất kì điểm nào trên mặt phẳng cũng có thể được biểu diễn bằng một vector tổng sau : p(u, v) = c + au + bv. Đây chính là phương trình tham số của mặt phẳng.

Trong phương trình trên u, v có thể biến đổi trong khoảng ( , ), do đó mặt phẳng sẽ trải dài đến vô tận. Tuy nhiên trong các trường hợp cụ thể ta chỉ muốn dùng một phần của mặt phẳng, một hình bình hành thôi chẳng hạn. Các phần như vậy được gọi là planar patch, lúc đó ta có thể tưởng tượng mặt phẳng như là sự ghép nối của các planar patch này.

Một planar patch được xác định bằng cách giới hạn khoảng biến đổi của các tham số u, v trong phương trình trên. Ví dụ nếu cho u, v biến đổi trong đoạn [0, 1] ta sẽ có một patch như hình vẽ 1.17.

Trong hình vẽ này u, v được biến đổi trong một khoảng không gian gọi là không gian tham số (parametric space), việc ánh xạ tương ứng các giá trị u, v đã được giới hạn trên sẽ tạo ra một patch trong không gian tương ứng gọi là không gian đối tượng.

1.17 Cách tạo ra một patch

Lưới đa giác (polygon meshes)

Một số hệ đồ họa cung cấp một số hàm cho phép mô hình hóa các đối tượng. Một mặt phẳng có thể được diễn tả thông qua một hàm như fillArea. Nhưng khi ta cần lợp nhiều planar patch liên tiếp, dùng các hàm lưới (mesh function) sẽ thuận tiện hơn. Một dạng thông dụng của lưới đa giác là dãy các tam giác (triagle strip). Hàm này vẽ n-2 tam giác kề nhau khi biết n đỉnh. Dạng này của lưới đa giác dùng trong hầu hết các thư viện đồ họa chuẩn hiện nay như OpenGL hay DirectX. Một dạng hàm tương tự là lưới các tứ giác (quardrilateral mesh). Hàm này vẽ một lưới (n-1)x(m-1) tứ giác lồi từ dãy nxm đỉnh.

Khi đa giác được mô tả bởi nhiều hơn ba đỉnh, các đỉnh của nó có thể không đồng phẳng. Điều này có thể dẫn đến các lỗi tính toán. Một phương pháp đơn giản là phân đa giác này thành các tam giác.

1.3. Tổng quan về Billboard

Billboard là kỹ thuật giả lập đối tượng 3D bởi các hình 2D bằng cách định hướng cho đối tượng 2D luôn quay bề mặt về phía mục tiêu, thông thường là camera. Kỹ thuật này rất phổ biến trong các trò chơi và các ứng dụng đòi hỏi phải xử lý một số lượng lớn các hình đa giác. Những người lập trình game 3D luôn phải đối mặt với việc làm sao để thể hiện một số lượng lớn các hình ảnh với một tỷ lệ khung hình hợp lý. Trong thực tế, khả năng xử lý của card đồ họa là có hạn, trong khi yêu cầu của các ứng dụng thì không ngừng được nâng cao. Điều này khiến cho công nghệ chế tạo phần cứng cũng phải liên tục được cải tiến.

Billboard được sử dụng để làm giảm số lượng hình ảnh cần thiết để thiết lập một chuỗi hình ảnh chuyển động liên tiếp bằng cách thay thế các đối tượng hình học bằng một kết cấu giả lập. Một trong những ví dụ phổ biến là hình ảnh về một cái cây. Thử nghĩ xem cần phải có bao nhiêu hình cơ sở để có thể biểu diễn trung thực hình ảnh của một cái cây. Billboard cho phép chúng ta thay thế hình ảnh của cái cây bằng một cấu trúc mặt phẳng đơn giản. Nó đảm bảo rằng cấu trúc hình học này luôn đối mặt với hướng của camera, và theo đó người dùng không bao giờ nhận ra rằng cái cây thực ra chỉ mà một mặt phẳng, người dùng chỉ có thể phát hiện ra điều này khi họ bay lên phía trên của cái cây.

Tuy nhiên, các hiệu ứng chiếu sáng sẽ không được biểu diễn một cách trung thực khi mà ta sử dụng một hình ảnh duy nhất cho mọi hướng của đối tượng. Một cái cây 3D phải thể hiện khác nhau ở các góc nhìn khác nhau, hay ít nhất thì nó cũng phải có sự thay đổi về hiệu ứng chiếu sáng khi góc nhìn có sự thay đổi. Trong trường hợp 2D billboard, khi mà ta sử dụng một hình duy nhất cho mọi hướng của đối tượng, nó có vẻ như là ánh sáng di chuyển cùng với camera. Cũng có thể là người dùng đôi khi không để ý tới sự không nhất quán này, tuy nhiên để khắc phục, có một giải pháp là ta có thể sử dụng nhiều hình cơ sở hơn để biểu diễn đối tượng từ các góc nhìn khác nhau.

Tuy nhiên, trừ khi chúng ta sử dụng một số lượng rất lớn các hình cơ sở, nếu không sẽ xảy ra hiện tượng giật hình khi có sự thay đổi của hai hình cơ sở.

Billboard có thể được sử dụng để giả lập một đối tượng 3D mà không cần đến một lượng lớn các hình ảnh cơ sở của đối tượng. Tuy nhiên kỹ thuật này không chỉ đơn giản là nhằm tiết kiệm số lượng hình cần biểu diễn. Về cơ bản, kỹ thuật này sẽ thực hiện việc xoay mặt đối tượng về phía camera, một đối tượng khác, hoặc đơn giản là về một hướng nào đó trong không gian 3D. Trong một số trường hợp, billboard không chỉ được sử dụng để tiết kiệm số lượng hình biểu diễn mà còn nhằm đáp ứng những mục đích cụ thể của ứng dụng. Chẳng hạn như là trong một trò chơi mà quân địch luôn quay mặt về phía bạn, hay trường hợp cầu thủ luôn đối mặt với quả bóng.

Có hai phương pháp billboard phổ biến là: phương pháp hình trụ và phương pháp hình cầu. Trong phương pháp hình cầu, không có sự giới hạn về hướng của đối tượng, trong khi với phương pháp hình trụ, hướng quay của đối tượng bị dàng buộc bởi một vector, thông thường là hướng của trục Y.

CHƢƠNG 2: CÁC KỸ THUẬT TẠO LẬP BILLBOARD 2.1. Các kỹ thuật billboard trụ

Kỹ thuật billboard trụ là kỹ thuật làm cho đối tượng billboard quay xung quanh một trục nào đó (thường là trục Y) để luôn hướng bề mặt của nó về phía camera.

2.1.1. Kỹ thuật giả billboard trụ

Kỹ thuật giả billboard trụ sẽ thực hiện quay đối tượng billboard quanh một trục sao cho vector pháp tuyến của nó song song với hình chiếu của vector hướng nhìn của camera xuống mặt phẳng xoz.

Các kỹ thuật billboard trình bày trong luận văn này sẽ được thực hiện việc quay đối tượng thông qua việc biến đổi ma trận mẫu sau:

Ba giá trị phía trên của cột bên phải cho biết sự liên quan giữa vị trí hiện tại của đối tượng với vị trí và hướng nhìn của camera. Ma trận con 3x3 M1 chứa các thông tin về tỷ lệ và hướng quay.

Chúng ta sẽ phân tích kỹ hơn về cấu trúc của ma trận con này. Ma trận này chứa 3 cột, và mỗi cột có một ý nghĩa riêng. Cột đầu tiên là right vector, cột thứ hai là up vector và cột thứ ba đại diện cho lookAt vector. Những vector này có liên quan tới hướng của camera. Khi chuyển ma trận con này thành ma trận đơn vị sẽ khiến cho camera được căn theo hệ trục toàn cục. Để thực hiện kỹ thuật giả

billboard trụ, ta chỉ cần quan tâm tới right và lookAt vector, còn up vector là không thay đổi.

Với phương pháp này thì đối tượng billboard sẽ không thay đổi khi camera quay lên trên hoặc quay xuống dưới. Billboard sẽ chỉ quay khi mà camera quay sang bên trái hoặc bên phải.

Kiểu billboard này có thể áp dụng để biểu diễn những cái cây. Những cái cây sẽ không bị uốn cong về phía sau hoặc về phía trước khi mà camera quay xuống dưới hoặc lên trên bởi vì up vector đã được cố định, do đó khả năng thể hiên của nó sẽ không được sinh động. Lưu ý là ảo giác này sẽ thất bại khi mà bạn bay lên phía trên của những cái cây. Khi đó những cái cây này sẽ ngày càng trở lên mảnh hơn và cuối cùng sẽ hoàn toàn bị biến mất. Tuy nhiên, với những ứng dụng mà trong đó bạn luôn được giữ để đứng trên mặt đất thì billboard trụ thực sự là một lựa chọn tốt.

Sau đây là mã nguồn cho phương pháp giả billboard trụ.

float modelview[16]; int i,j;

// save the current modelview matrix glPushMatrix();

// get the current modelview matrix

glGetFloatv(GL_MODELVIEW_MATRIX , modelview); // The only difference now is that

// the i variable will jump over the

// up vector, 2nd column in OpenGL convention for( i=0; i<3; i+=2 )

if ( i==j )

modelview[i*4+j] = 1.0; else

modelview[i*4+j] = 0.0; }

// set the modelview matrix with the // up vector unchanged

glLoadMatrixf(modelview); drawObject();

// restores the modelview matrix glPopMatrix();

Đoạn mã trên cũng được chia làm hai hàm, đó là biểu diễn và vẽ đối tượng. Chức năng thứ nhất là thiết lập ma trận modelview, còn chức năng thứ hai sẽ phục hồi là ma trận hiện thời.

void billboardCheatCylindricalBegin() { float modelview[16];

int i,j;

// save the current modelview matrix glPushMatrix();

// get the current modelview matrix

glGetFloatv(GL_MODELVIEW_MATRIX , modelview); for( i=0; i<3; i+=2 )

if ( i==j )

modelview[i*4+j] = 1.0; else

modelview[i*4+j] = 0.0; }

// set the modelview matrix glLoadMatrixf(modelview); }

void billboardEnd() { // restore the previously // stored modelview matrix glPopMatrix();

}

Đoạn mã biểu diễn đối tượng billboard trở thành:

billboardCheatCylindricalBegin(); drawObject();

billboardEnd();

Với phương pháp này, các phép tỷ lệ theo trục X và Y sẽ bị mất, nhưng phép tỷ lệ theo trục Z thì vẫn được thực hiện. Lựa chọn tốt nhất là thực hiện các phép tỷ lệ sau khi gọi hàm billboardCheatCylindricalBegin().

2.1.2. Billboard trụ thực sự

Billboard trụ thực sự sẽ làm cho đối tượng quay quanh một trục, giống như trong phiên bản giả billboard trụ, nhưng vector lookAt của đối tượng sẽ được quay về phía của camera. Hình sau thể hiện cách thức biến đổi của kỹ thuật billboard trụ.

2.1 Cách quay đối tƣợng trong kỹ thuật billboard trụ thực sự

Lúc này, khi người dùng di chuyển trên mặt đất, những cái cây sẽ thực sự đối mặt với người dùng. Phương pháp sử dụng ở đây đòi hỏi phải biết được vị trí của đối tượng cũng như vị trí của mục tiêu trong hệ trục toàn cục. Thường thì mục tiêu chính là vị trí của camera mà ta đã biết. Tuy nhiên điều tương tự không đúng đối với đối tượng.

Nếu như vị trí của đối tượng được xác định thông qua các phép biến đổi hình học, như là dịch chuyển, phép quay, khi đó giữ được thông tin về vị trí của đối tượng trong hệ trục toàn cục là một nhiệm vụ khá khó khăn

Giả như biết được vị trí của các đối tượng và mục tiêu trong hệ trục toàn cục, khi đó kỹ thuật billboard sẽ trở thành một thao tác biến đổi hình học đơn giản. Vì một lý do đơn giản là giả sử đối tượng có các vector sau:

right vector = [1,0,0] up vector = [0,1,0] lookAt vector = [0,0,1]

Trong thực tế, điều này có nghĩa là đối tượng được vẽ trong hệ trục cục bộ và nhìn về chiều dương của trục Z.

Việc định hướng cho phép quay của đối tượng quanh up vector được xác định thông qua góc giữa lookAt vector và vector từ đối tượng tới camera.

2.2 Xác định góc quay trong billboard trụ thực sự (a)

Vector từ đối tượng tới camera được định nghĩa như sau: objToCam = CamPos – ObjPos.

Vector objToCamProj là chiếu của objToCam lên mặt phẳng XOZ. Vì vậy thành phần Y của nó được đặt bằng 0.

Nếu objToCamProj là normalized khi đó tích giữa lookAt và objToCam sẽ cho phép tính được cosine của góc quay. Tuy nhiên chỉ biết được cosine thì vẫn

chưa đủ, khi mà cos(a) = cos(-a). Việc tính tích có hướng cho phép ta xác định được một góc duy nhất. Vector tích cùng hướng với up vector nếu góc quay là dương và ngược hướng nếu góc quay là âm.

2.3 Xác định góc quay trong billboard trụ thực sự (b)

Các bước cần thực hiện sau khi tính được objToCamProj là: 1. normalize(objToCamProj)

2. angleCosine = innerProduct(lookAt,objToCamProj) 3. upAux = crossProduct(lookAt,objToCamProj)

4. glRotatef(acos(aux)*180/3.14,upAux[0], upAux[1], upAux[2]);

Tương tự như phần trước, một hàm sẽ được xây dựng để thiết lập billboard. Mã nguồn được cho như sau:

void billboardCylindricalBegin( float camX, float camY, float camZ,

float objPosX, float objPosY, float objPosZ) { float lookAt[3],objToCamProj[3],upAux[3];

float modelview[16],angleCosine; glPushMatrix();

// objToCamProj is the vector in world coordinates from the // local origin to the camera projected in the XZ plane objToCamProj[0] = camX - objPosX ;

objToCamProj[1] = 0;

objToCamProj[2] = camZ - objPosZ ;

// This is the original lookAt vector for the object // in world coordinates

lookAt[0] = 0; lookAt[1] = 0; lookAt[2] = 1;

// normalize both vectors to get the cosine directly afterwards

mathsNormalize(objToCamProj);

// easy fix to determine wether the angle is negative or positive

// for positive angles upAux will be a vector pointing in the // positive y direction, otherwise upAux will point downwards // effectively reversing the rotation.

mathsCrossProduct(upAux,lookAt,objToCamProj); // compute the angle

angleCosine = mathsInnerProduct(lookAt,objToCamProj);

// perform the rotation. The if statement is used for stability

reasons

// if the lookAt and objToCamProj vectors are too close together then

// |angleCosine| could be bigger than 1 due to lack of precision

if ((angleCosine < 0.99990) && (angleCosine > -0.9999)) glRotatef(acos(angleCosine)*180/3.14,upAux[0], upAux[1], upAux[2]);

}

Hàm billboardEnd() có thể được gọi sau khi biểu diễn đối tượng.

billboardCylindricalBegin(cx,cy,cz,ox,oy,oz); drawObject();

billboardEnd();

2.1.3. Ƣu điểm và những hạn chế của phƣơng pháp billboard trụ

Phương pháp billboard trụ thực sự phù hợp cho những ứng dụng mà người sử dụng chỉ có thể di chuyển được ở trên mặt đất. Với những ứng dụng như vậy,

các đối tượng billboard sẽ được điều chỉnh để luôn hướng về phía người sử dụng. Và khi người sử dụng không có khả năng di chuyển lên phía bên trên của các đối tượng billboard thì họ sẽ khó có thể phát hiện ra các đối tượng billboard

Một phần của tài liệu Billboard và giả lập mô hình 3D trong thực tại ảo (Trang 33)

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

(65 trang)