Xoay biển quảng cáo về phía camera


7

Tôi đang cố gắng tạo ra một hệ thống hạt trong OpenGL và do đó tôi cần sử dụng biển quảng cáo.

Tôi cần những biển quảng cáo này để đối mặt với máy ảnh mọi lúc.

Các hướng dẫn mà tôi đã theo dõi chỉ xoay bảng quảng cáo trên 1 trục, chẳng hạn như biển quảng cáo được sử dụng làm cỏ hoặc cây, nhưng tôi cần một phương pháp xoay hình tứ giác để luôn đối diện với máy ảnh, ngay cả khi nhìn xuống.


Cảnh gốc: Trước khi quay

Cảnh mong muốn: Cảnh mong muốn

Trong khi tìm kiếm câu trả lời, tôi chỉ thực sự tìm thấy kỹ thuật biến thành phần mat3 của ma trận chế độ xem / mô hình của máy ảnh thành ma trận nhận dạng. Đây không phải là thứ tôi cần, vì vị trí của điểm trong không gian không bao giờ thay đổi.

Cảnh không chính xác: Xoay không chính xác


Làm cách nào tôi có thể tính toán một ma trận xoay mới sẽ xoay thành công một hình tứ giác về phía máy ảnh hoặc sửa đổi một ma trận hiện có?

Trong trình tạo bóng hình học, tôi có quyền truy cập vào vị trí của máy ảnh, ma trận phối cảnh và ma trận chế độ xem / mô hình.

Tôi đã không bao gồm bất kỳ mã shader nào vì nó thực sự tầm thường; Tôi tạo các đỉnh là phần bù của vị trí của điểm mong muốn dựa trên kích thước mong muốn. Vì vậy, nếu hình tứ giác phải là 50 x 50, thì đỉnh là vị trí bù 25 trên X và Y, nhân với ma trận Phối cảnh x của máy ảnh.


Giải pháp:

mat4 VP = pMatrix * vMatrix;       
vec3 CameraRight = vec3(vMatrix[0][0], vMatrix[1][0], vMatrix[2][0]);
vec3 CameraUp = vec3(vMatrix[0][1], vMatrix[1][1], vMatrix[2][1]);

vec3 Pos = gl_in[0].gl_Position.xyz;  // The desired point for the billboard

vec4 v1 = VP * vec4(Pos + CameraRight * 0.5 * Size + CameraUp * -0.5 * Size, 1.0);  
vec4 v2 = VP * vec4(Pos + CameraRight * 0.5 * Size + CameraUp * 0.5 * Size, 1.0);     
vec4 v3 = VP * vec4(Pos + CameraRight * -0.5 * Size + CameraUp * -0.5 * Size, 1.0); 
vec4 v4 = VP * vec4(Pos + CameraRight * -0.5 * Size + CameraUp * 0.5 * Size, 1.0);  

Đã kết thúc


Ngoài ra, tôi đã tìm thấy các câu hỏi tương tự được đăng trước khi liên quan đến các công cụ khác như Unity, tuy nhiên tôi đang sử dụng công cụ của riêng mình và hơn nữa điều này cần được thực hiện trong GLSL, vì vậy tôi không có tất cả các chức năng tìm kiếm ưa thích sẽ đơn giản hóa các vấn đề .
Yattabyte

Tôi dường như nhớ lại rằng các tên người chơi của Minecraft được kết xuất bằng các cuộc gọi OpenGL thuần túy và các cuộc gọi luôn đối diện với máy ảnh (và được đặt trong không gian phối cảnh). Tuy nhiên, tôi đang ở xa môi trường modding của mình, vì vậy tôi sẽ không thể đào xung quanh nó cho đến khi ... eesh, có lẽ là thứ bảy. Điều đó nói rằng, bạn có thể tự tìm thấy nó từ mô tả đó.
Draco18 không còn tin tưởng SE

Câu trả lời:


3

Tôi nghĩ rằng bài viết này là những gì bạn đang tìm kiếm.

Bài viết từ hướng dẫn opengl

Về cơ bản, bạn sẽ phải tìm xoay camera ma trận và áp dụng một hình thức dẫn xuất cho lưới của bạn.

Hy vọng nó giúp!


Đúng! Đây chính xác là những gì tôi cần. Cảm ơn bạn rât nhiêu!
Yattabyte

Liên kết đến phiên bản tiếng Anh của cùng một hướng dẫn: opengl-tutorial.org/inter liền
particles / từ

1

Tôi chỉ để điều này ở đây cho một giải pháp tổng quát hơn cho vấn đề. Những gì bạn muốn làm là giữ lại bản dịch / xoay / tỷ lệ "toàn cầu" của đối tượng / bảng quảng cáo để nó ở đúng vị trí thế giới, nhưng xoay cục bộ lại để nó đối diện với máy ảnh. Đó là, bạn muốn ma trận khung nhìn mô hình cha, nhưng áp dụng nghịch đảo của phần xoay của nó cho đối tượng / bảng quảng cáo. Đây là những gì tôi đã làm (mã giả cho các lớp toán Qt, nhưng bạn sẽ có ý tưởng):

// Calculate object->world tranform with inverse parent->world rotation
QMatrix4x4 objectTransform;
objectTransform.setToIdentity();
objectTransform.translate(objectPosition);
// Get length of first row as scale factor. See: /programming/27655885/get-position-rotation-and-scale-from-matrix-in-opengl
float scaleFactor = parentModelView.row(0).toVector3D().length();
// get upper left 3x3 sub-matrix and unscale
QMatrix3x3 parentRotation = parentModelView.toGenericMatrix<3,3>();
parentRotation *= 1.0f / scaleFactor;
// convert to quaternion and invert
QQuaternion inverseParentRotation = QQuaternion::fromRotationMatrix(parentRotation).inverted();
// set as rotation
objectTransform.rotate(inverseParentRotation);
objectTransform.scale(objectScaleFactor); 

// Now for drawing calculate the combined object->world transform:
QMatrix4x4 objectModelView = parentModelView * objectTransform;

Hãy cẩn thận: Chỉ hoạt động cho quy mô đồng đều và không có biến đổi cắt, như đã nêu ở đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.