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

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 45)

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 đó thực chất chỉ là một mặt phẳng. Trong trường hợp người sử dụng có khả năng bay lên phía trên cao thì phương pháp này không còn phù hợp, vì khi đó người dùng sẽ nhận ra đối tượng billboard là một mặt phẳng.

2.2. Các kỹ thuật billboard cầu

Khắc phục nhược điểm của kỹ thuật billboard trụ trong trường hợp người sử dụng di chuyển lên phía trên của các đối tượng billboard. Kỹ thuật billboard cầu thực hiện quay đối tượng billboard quanh một tâm sao cho bề mặt của nó luôn hướng về phía camera. Với kỹ thuật này đối tượng billboard luôn hướng bề mặt về phía camera tại bất kì vị trí và góc nhìn nào của camera. Và người sử dụng chỉ phát hiện ra các đối tượng billboard là một mặt phẳng khi so sánh và phát hiện ra sự bất hợp lý về hình dạng của đối tượng tại các vị trí nhìn khác nhau.

2.2.1. Kỹ thuật giả billboard cầu

Kỹ thuật giả billboard cầu sẽ thực hiện quay đối tượng billboard quanh một tâm sao cho vector pháp tuyến của nó song song với vector hướng nhìn của camera. (adsbygoogle = window.adsbygoogle || []).push({});

Hình ảnh sau đây chỉ mang tính chất minh họa. Nó thể hiện một người tuyết và một vài cái cây được áp dụng kỹ thuật billboard. Thật khó để có thể nói rằng những cái cây không hướng về phía của camera. Nhưng thực tế là, người ta làm cho bề mặt của cái cây hướng vuông góc với hướng nhìn của camera.

2.5 Phƣơng pháp giả billboard cầu

Sơ đồ dưới đây thể hiện điều gì đã thực sự xảy ra. Vòng tròn màu đen ở phía dưới biểu diễn cho camera. Vector xuất phát từ camera chỉ hướng nhìn hiện tại của camera. Vector này chỉ ra phương của mặt phẳng vuông góc với hướng nhìn của camera. Các đối tượng trong các tình huống từ O1 tới O3 được quay sao cho vector pháp tuyến của chúng luôn hướng về phía mặt phẳng này. Điều này khiến cho đối tượng dường như là được đặt vào một hệ trục cục bộ và bề mặt của nó thì luôn hướng về phía chiều dương của trục Z.

2.6 Bản chất của phƣơng pháp giả billboard cầu

Để thực hiện được kỹ thuật này người ta cũng sử dụng một ma trận mẫu như ở phần trước. Ma trận này lưu trữ thông tin về các biến đổi hình học, hướng quay, tỷ lệ và vị trí của đối tượng billboard.

Khi ma trận con M1 được chuyển thành ma trận đơn vị, các phép tỷ lệ và quay sẽ bị loại bỏ, theo đó hướng nhìn của camera sẽ được căn theo trục Z của hệ trục toàn cục, vector up và right của camera cũng được căn theo các trục của hệ trục tọa độ toàn cục. Dạng billboard này hoạt động theo kiểu giả billboard cầu, tâm của billboard là gốc tọa độ cục bộ. Nếu sử dụng kiểu billboard này cho những cái cây, thì khi người dùng nhìn lên trên hoặc xuống dưới, những cái cây sẽ bị kéo về phía trước hoặc phía sau.

Trong thực tế, khi chuyển ma trận con này thành ma trận đơn vị có nghĩa là đối tượng sẽ không chịu một phép quay nào khi nó được biểu diễn. Do đó nó sẽ được biểu diễn giống như khi mà camera hướng về phía chiều âm của trục tọa độ Z. Chú ý là phép tỉ lệ cũng sẽ bị phá vỡ, vì vậy các phép tỷ lệ cần phải được thực hiện sau khi thực hiện các phép biến đổi trên mà trận mẫu.

Đầu tiên, ma trận mẫu hiện tại sẽ được lưu lại. Sau đó ma trận này sẽ được đem ra biến đổi, ma trận con 3x3 ở góc trên bên trái sẽ được chuyển thành ma trận đơn vị. Ma trận này sẽ được nạp vào cho máy trạng thái OpenGL, và biểu diễn đối tượng tại gốc trục tọa độ cục bộ. Cuối cùng mà trận mẫu gốc sẽ được phục hồi.

float modelview[16]; int i,j;

// save the current modelview matrix glPushMatrix();

// get the current modelview matrix

glGetFloatv(GL_MODELVIEW_MATRIX , modelview); // undo all rotations

// beware all scaling is lost as well for( i=0; i<3; i++ )

for( j=0; j<3; j++ ) { if ( i==j ) modelview[i*4+j] = 1.0; else modelview[i*4+j] = 0.0; }

// set the modelview with no rotations and scaling glLoadMatrixf(modelview);

drawObject();

// restores the modelview matrix glPopMatrix();

Với đoạn mã trên, đối tượng sẽ quay để luôn đối mặt với mặt phẳng trực giao với hướng nhìn của camera. Tâm quay chính là gốc của hệ trục cục bộ. Đoạn mã trên thực hiện hai chức năng, đó là chức năng biểu diễn và vẽ đối tượng. Chức năng đầu tiên sẽ thiết lập ma trận modelview, và chức năng thứ hai sẽ phục hồi lại ma trận hiện thời.

void billboardCheatSphericalBegin() { float modelview[16];

int i,j;

// save the current modelview matrix glPushMatrix();

// get the current modelview matrix

// undo all rotations

// beware all scaling is lost as well for( i=0; i<3; i++ )

for( j=0; j<3; j++ ) { if ( i==j ) modelview[i*4+j] = 1.0; else modelview[i*4+j] = 0.0; }

// set the modelview with no rotations glLoadMatrixf(modelview);

}

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

}

Mã nguồn để biểu diễn đối tượng billboard sẽ trở thành: (adsbygoogle = window.adsbygoogle || []).push({});

billboardCheatSphericalBegin(); drawObject();

billboardEnd();

Như đã nói ở trên, các thao tác tỷ lệ sẽ bị mất khi thiết lập ma trận modelview. Nếu muốn thực hiện các phép tỷ lệ trên đối tượng, bạn cần phải thực

hiện nó sau khi thực hiện các cài đặt cho đối tượng billboard bằng đoạn mã ở trên. billboardCheatSphericalBegin(); glScalef(1,2,1); drawObject(); billboardEnd()

Phương pháp giả billboard trụ hoạt động hoàn toàn giống như phương pháp giả billboard cầu trong trường hợp người dùng chỉ thực hiện được các thao tác quay sang phải hoặc sang trái. Phương pháp này chỉ có sự khác biệt khi người dùng thực hiện các thao tác quay lên trên hoặc xuống dưới. Khi này, đối tượng billboard sẽ bị kéo về phía trước hay đẩy về phía sau.

2.2.2. Billboard cầu thực sự

Billboard cầu là một cải tiến của phương pháp billboard trụ, nhằm mục đích khiến cho đối tượng thực sự đối diện với hướng của camera. Billboard cầu thực sự thực hiện thêm một phép quay đối tượng quanh right vector.

2.7 Phép quay đối tƣợng quanh right vector

Khi biết được góc quay, cosine của nó có thể được xác định bằng việc nhân vô hướng objToCamProj với objToCam.

Giống như trong kỹ thuật billboard ở trên, một hàm được sử dụng để thiết lập billboard. Với mã nguồn như sau:

void billboardSphericalBegin(

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]); (adsbygoogle = window.adsbygoogle || []).push({});

// so far it is just like the cylindrical billboard. The code for the

// second rotation comes now

// The second part tilts the object so that it faces the camera

// objToCam is the vector in world coordinates from // the local origin to the camera

objToCam[1] = camY - objPosY; objToCam[2] = camZ - objPosZ;

// Normalize to get the cosine afterwards mathsNormalize(objToCam);

// Compute the angle between objToCamProj and objToCam, //i.e. compute the required angle for the lookup vector angleCosine = mathsInnerProduct(objToCamProj,objToCam); // Tilt the object. The test is done to prevent instability // when objToCam and objToCamProj have a very small

// angle between them

if ((angleCosine < 0.99990) && (angleCosine > -0.9999)) if (objToCam[1] < 0)

glRotatef(acos(angleCosine)*180/3.14,1,0,0); else

glRotatef(acos(angleCosine)*180/3.14,-1,0,0); }

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

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

billboardEnd();

2.2.3. Ƣu điểm và nhƣợc điểm của phƣơng pháp billboard cầu

Phương pháp billboard cầu khắc phục được nhược điểm của phương pháp billboard trụ trong trường hợp người sử dụng quay lên trên hoặc xuống dưới.

Ngay cả trong trường hợp người dùng có thể đi lên phía trên của đối tượng, thì trong một giới hạn nhất định phương pháp billboard cầu vẫn phát huy được tác dụng đánh lừa thị giác. Tuy nhiên không phải đối tượng nào cũng có thể áp dụng được kỹ thuật billboard. Trong trường hợp ví dụ với những cái cây. Khi người dùng có thể đi chuyển lên phía bên trên của cái cây thì ngay cả với phương pháp billboard cầu thực sự. Người dùng cũng dễ dàng phát hiện những cái cây chỉ là đối tượng hai chiều.

CHƢƠNG 3: ỨNG DỤNG BILLBOARD TRONG GIẢ LẬP ĐỐI TƢỢNG 3D

3.1. Mô tả ứng dụng

Trong ứng dụng này, các kỹ thuật billboard đã được trình bày ở trên được sử dụng để biểu diễn những cái cây. Ứng dụng cho phép lựa chọn kỹ thuật billboard, thay đổi vị trí đứng, góc nhìn để có thể nhận thấy cách thức hoạt động, cũng như ưu, nhược điểm của từng kỹ thuật.

Những cái cây trong ứng dụng thực chất là đối tượng 2 chiều, chỉ có những người tuyết là đối tượng 3 chiều.

Trong trường hợp không sử dụng kỹ thuật billboard, khi người dùng thay đổi góc nhìn thì sẽ phát hiện ra những cái cây thực chất chỉ là các hình 2 chiều. Khi áp dụng kỹ thuật billboard, những cái cây luôn được quay sao cho đối mặt với hướng nhìn của người dùng. Nếu người dùng không quan sát kỹ thì khó có thể phát hiện ra chúng thực ra không phải là hình 3D.

Dưới đây là một số hình ảnh kết quả chạy chương trình với những cặp hình được chụp tại cùng vị trí nhằm mục đích so sánh ưu, nhược điểm giữa các kỹ thuật với nhau.

3.2. Một số kết quả

Trường hợp không sử dụng kỹ thuật billboard

3.1 Những cái cây khi chƣa áp dụng kỹ thuật billboard

Khi chưa áp dụng kỹ thuật billboard, tại vị trí được chọn để chụp hình, ta có thể phát hiện ra một số cái cây thực ra chỉ là một mặt phẳng.

Trường hợp sử dụng kỹ thuật giả billboard trụ

So sánh giữa phương pháp giả billboard trụ với billboard trụ thực sự:

3.3 Áp dụng phƣơng pháp giả billboard trụ (adsbygoogle = window.adsbygoogle || []).push({});

Có thể nhận thấy sự khác biệt giữa phương pháp billboard trụ thực sự và phương pháp giả billboard trụ qua 2 bức ảnh ở trên. Cái cây trong khung hình chữ nhật lớn ở cả hai phương pháp gần như không có sự khác biệt do nó ở vị trí trực diện với người quan sát. Tuy nhiên cái cây trong khung hình chữ nhật nhỏ thì có sự khác biệt khá lớn. Trong trường hợp giả billboard trụ, vector pháp tuyến của những cái cây chỉ song song với hình chiếu của vector hướng nhìn của camera lên mặt phẳng xoz, do đó tại những vị trí có góc nhìn hẹp thì những cái cây sẽ bị thu hẹp lại. Còn trong trường hợp của billboard trụ thực sự, vector pháp tuyến của những cái cây luôn hướng về phía đặt camera, do đó những cái cây hoàn toàn không bị thay đổi khi người sử dụng chỉ thực hiện các thao tác quay sang trái hoặc sang phải.

So sánh giữa phương pháp giả billboard cầu với billboard cầu thực sự:

3.5 Áp dụng phƣơng pháp giả billboard cầu

Trên đây là hình ảnh chụp hai phương pháp giả billboard cầu và billboard cầu thực sự. Ta có thể thấy rằng trong phương pháp giá billboard cầu, kích thước của cái cây trong khung hình chữ nhật lớn hơn kích thước của cái cây đó trong phương pháp billboard cầu thực sự theo cả chiều dọc và chiều ngang. Điều này được lý giải dựa trên cách thức biến đổi đối tượng billboard của hai phương pháp. Trong phương pháp giả billboard cầu, vector pháp tuyến của đối tượng billboard được giữ sao cho song song với vector hướng nhìn của camera. Do đó, khi camera hướng lên phía trên hoặc xuống dưới, đối tượng billboard bị quay kéo về phía trước hoặc phía sau. Điều này khiến cho khoảng cách giữa đối tượng billboard bị thu hẹp lại khi camera quay lên trên hoặc xuống dưới. Khi khoảng cách giữa đối tượng tới camera bị thu hẹp lại thì kích thước của đối tượng sẽ được tăng lên theo phép tỷ lệ.

Trong phương pháp billboard cầu thực sự, đối tượng billboard được quay sao cho lookat vecter của nó hướng về vị trí của camera. Điều này khiến cho khi camera quay theo các hướng thì khoảng cách từ camera tới đối tượng billboard vẫn không thay đổi. Do đó kích thước của đối tượng billboard không bị thay đổi khi camera thay đổi góc nhìn.

PHẦN KẾT LUẬN 1. Kết quả luận văn đã đạt đƣợc

Sự phát triển của công nghệ thông tin đã đẩy nhanh sự phát triển nhiều lĩnh vực của đời sống xã hội. Trong số đó phải kể đến lĩnh vực thể hiện hình ảnh 3 chiều và thực tại ảo. Với sự phát triển không ngừng của công nghệ chế tạo phần cứng, máy tính ngày càng trở lên mạnh mẽ và đáp ứng tốt hơn những yêu cầu tính toán, xử lý thông tin của con người.

Tuy nhiên trong lĩnh vực đồ họa máy tính, đặc biệt là đồ họa 3D – lĩnh vực đòi hỏi phải xử lý một số lượng lớn các đối tượng đồ họa có kích thước lớn, nhưng vẫn phải đảm bảo thỏa mãn các yêu cầu về mặt thời gian thì thực sự máy tính cũng chưa thể đáp ứng một cách đầy đủ “không gian” cho việc xử lý hình ảnh. Vấn đề đặt ra là cần giảm thiểu không gian lưu trữ đối tượng, để có thể tích hợp đối tượng vào những không gian lớn phục vụ cho việc điều khiển sau này.

Luận văn đã tập trung nghiên cứu các kỹ thuật billboard để giả lập đối

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 45)