DirectX DirectX sẽ chỉ vẽ các đa giác có [X, Y] từ [-1, -1] đến [1,1] và với Z từ 0 đến 1. Hay, Điều này có nghĩa là gì và làm thế nào để làm việc xung quanh nó?


7

Tôi đã theo dõi các hướng dẫn D3D11 trên Rastertek để mở rộng kiến ​​thức về kết xuất mà tôi sẽ cần khi tôi muốn xây dựng công cụ của riêng mình, như một sở thích.

Cuối cùng, sau khi nhận được một mô hình được hiển thị trên màn hình trong không gian 3D và có thể di chuyển và xoay cả máy ảnh và mô hình, tôi muốn nhập các mô hình FBX tùy chỉnh thay thế, không có trong hướng dẫn. Tôi đã tìm thấy hướng dẫn này trực tuyến trên đó, mà tôi đã làm theo tài liệu của SDK fbx.

Bây giờ nó hoạt động để tải và hiển thị các mô hình FBX, tuy nhiên, các đỉnh khá lộn xộn trên một số mô hình và trên một số, nó hoạt động hoàn hảo, sau đó tôi đọc trong hướng dẫn và tôi trích dẫn:

"Cuối cùng, nếu bạn không sử dụng FBX shitty-bell được đính kèm ở đầu bài đăng này, hãy lưu ý. Ở trạng thái mặc định, DirectX sẽ chỉ vẽ đa giác với [X, Y] từ [-1, -1 ] đến [1,1] và với Z từ 0 đến 1. Nhìn qua các đỉnh trong FBX của bạn và đảm bảo mọi thứ đều nằm trong phạm vi đó! "

Như bạn có thể đoán, "chuông shitty" hoạt động hoàn hảo để vẽ. Dù sao, điều đó có nghĩa là nó sẽ vẽ đa giác trong phạm vi đó, ngoài ra, làm thế nào để tôi làm việc xung quanh điều đó khi làm mô hình?


Tôi không quen với DirectX, nhưng đã sử dụng các thư viện khác, bạn đã thử vẽ một hình tam giác mà một trong các đỉnh của nó giống như trên (2, 0, 0) hay đại loại như thế chưa? Các giới hạn [-1, -1] và [1, 1] có vẻ giống như tọa độ đồng nhất, nhưng những điều này không thể truy cập được đối với người vẽ lưới và nên được thực hiện trong hậu trường. Có một cơ hội bạn hiểu lầm một cái gì đó?
TomTsagk

@TomTsagk Tôi chắc chắn có thể hiểu nhầm một cái gì đó, mặc dù vậy, tôi đã không cố gắng tự vẽ một cái gì đó bằng cách nhập một bộ đệm đỉnh và chỉ mục được tạo thủ công (tôi cũng có trước đây, nhưng điều đó không liên quan gì đến điều này). Chúng cũng không thể truy cập được, tôi chỉ không hiểu chúng là gì, tôi nghĩ rằng tôi phải thay đổi cách máy xay sinh tố xuất FBX để nó hoạt động với D3D tại một thời điểm, nhưng tôi chỉ tự mình bay đi suy nghĩ, và sau khi một số googling tôi đã từ bỏ và đặt câu hỏi của tôi ở đây để thay thế. Rõ ràng, hãy đọc câu trả lời mà Josh đã đăng, câu trả lời đó rất hay!
larssonmartin

Câu trả lời:


15

Mặc dù về mặt kỹ thuật, tuyên bố trong hướng dẫn đó có phần sai lệch và theo một cách thức đáng báo động.

Nói chung, bạn không cần phải lo lắng về điều này.

Dù sao, điều đó có nghĩa là nó sẽ vẽ đa giác trong phạm vi đó?

Các đỉnh mô hình trong đường ống đồ họa trải qua một số giai đoạn khác nhau khi chúng đi qua đường ống đồ họa. Mỗi giai đoạn này là hệ tọa độ riêng của nó và một đỉnh đi qua giữa các hệ tọa độ đó bằng các ma trận biến đổi.

Hướng dẫn này đề cập đến một trong những giai đoạn cuối cùng trong đường ống rằng các đỉnh tồn tại ngay trước khi rasterization, được gọi là không gian màn hình đồng nhất (nhưng lưu ý rằng nó cũng có các tên khác). Mục đích của không gian tọa độ này là thu nhỏ tất cả dữ liệu đỉnh xuống một phạm vi đã biết, chuẩn hóa để có thể ánh xạ tới không gian pixel của cửa sổ đích. Phạm vi điển hình cho các trục trong không gian này trong các API đồ họa khác nhau là -1 đến 1 hoặc 0 đến 1, vì cả hai đều đơn giản để ánh xạ tới không gian pixel 0 đến một số nguyên lớn của cửa sổ đích.

Thông thường, bạn thường định cấu hình mô hình, khung nhìn và ma trận chiếu (cũng như biến đổi khung nhìn nếu cần) một cách thích hợp cho cảnh của bạn. Hướng dẫn bạn liên kết bỏ qua các bước này, có lẽ để cho ngắn gọn. Nếu bạn không thực hiện bất kỳ phép chuyển đổi dữ liệu đỉnh nào trong các shader hoặc tương tự, thì kết quả thực là như thể tất cả các phép biến đổi của bạn là ma trận danh tính, điều đó có nghĩa là tất cả các phép biến đổi được thực hiện bởi đường ống sẽ tự động kết thúc không có ops (ngoại trừ biến đổi khung nhìn) và bạn thực sự có một phạm vi hiển thị phù hợp với phạm vi của không gian màn hình đồng nhất.

Làm thế nào để tôi làm việc xung quanh đó khi làm người mẫu?

Bạn không. Mô hình hóa các đối tượng của bạn theo cách bạn cần, và sau đó điều chỉnh Direct3D theo các nhu cầu đó, như trên, thay vì cách khác. Mặc dù cuối cùng, đúng là tọa độ của bạn sẽ kết thúc ở một dạng biểu mẫu -1-to-1 bình thường ngay trước khi vẽ, bạn có thể định cấu hình D3D để chuyển đổi và chia tỷ lệ bất kỳ phạm vi tọa độ nào bạn muốn trong phạm vi áp chót đó.


11
Điều này cũng không phải là duy nhất cho DirectX. Điều đó đúng với OpenGL và các API đồ họa 3D khác. Bạn có thể thấy bài viết cũ này hữu ích. Các hướng dẫn API đã lỗi thời vì chúng là Direct3D 9, nhưng các khái niệm đều đúng.
Chuck Walbourn

@ChuckWalbourn Cảm ơn bài viết, tôi chắc chắn sẽ đọc nó.
larssonmartin

2
TL: DR khi tác giả hướng dẫn viết "Ở trạng thái mặc định ...", anh ta có nghĩa là "Nếu bạn không đặt chuyển đổi cảnh / máy ảnh", điều gì hy vọng sẽ được giải thích trong các phần tiếp theo.
IMil

13
Ồ, tuyên bố trong hướng dẫn của OP có vẻ chính xác như nói với ai đó "đây là máy ảnh trên giá ba chân - bạn sẽ chỉ có được một bức ảnh đẹp nếu bạn đặt đối tượng của mình ở một vị trí phía trước nó, ở khoảng cách phù hợp lấy nét "- không sai , nhưng bỏ qua ý tưởng di chuyển máy ảnh hoặc điều chỉnh tiêu cự của nó, ngay cả vì đơn giản, loại dẫn đến sự nhầm lẫn chính xác của OP ...
AC

@lMil Được rồi, mà tôi làm trong shader đỉnh của tôi dựa trên các vị trí đỉnh, đã nhận nó, cảm ơn!
larssonmartin

7

Phạm vi [-1 ; 1] x [-1 ; 1] x [0 ; 1]được đề cập trong hướng dẫn đề cập đến khối lượng xem chính tắc . Đây là dữ liệu đỉnh không gian tọa độ cuối cùng được ánh xạ tới trước khi mọi thứ được rasterized lên màn hình của bạn. Để hiểu chính xác điều này có nghĩa là gì, nó giúp xem xét một đường ống kết xuất thường trông như thế nào.

Phối hợp không gian

Không gian tọa độ đề cập đến hệ tọa độ bạn sử dụng để xác định vị trí của các đỉnh trong nó. Như một ví dụ thực tế, hãy tưởng tượng bạn có một bàn làm việc với bàn phím và bạn muốn thể hiện vị trí của bàn phím. Bạn có thể xác định góc phía trước bên trái của bàn là vị trí (0, 0, 0)- đây được gọi là gốc -, trục X nằm dọc theo chiều dài của bàn (trái sang phải), trục Y nằm dọc theo độ sâu của bàn (gần xa) và trục Z được đặt thẳng đứng lên từ bàn. Nếu bàn phím của bạn nằm 50 cm ở bên phải của góc này và cách mép gần nhất 10 cm, thì nó nằm ở vị trí (50, 10, 0).

Ngoài ra, bạn có thể xác định góc của căn phòng của bạn là vị trí (0, 0, 0). Hãy nói rằng bàn của bạn nằm cách bức tường bên trái 200 cm, cách bức tường phía trước 300 cm và bàn làm việc có chiều cao 70cm. Trong trường hợp này, đỉnh bàn của bạn được đặt ở vị trí (200, 300, 70)và bàn phím của bạn được đặt tại (250, 310, 70).

Đây là hai ví dụ về các không gian tọa độ khác nhau và cách chúng ảnh hưởng đến tọa độ vị trí của các đối tượng bên trong chúng. Tương tự, dữ liệu đỉnh trong đường ống kết xuất 3D được chuyển đổi qua các không gian tọa độ khác nhau trước khi kết thúc trên màn hình của bạn.

Phối hợp các không gian trong đường ống kết xuất 3D

Các đối tượng riêng lẻ được mô hình hóa trong phần mềm 3D như Autodesk Maya, Blender .... Chúng thường được mô hình hóa tập trung xung quanh nguồn gốc. Không gian tọa độ này được gọi là không gian mô hình . Nếu bạn kết xuất nhiều đối tượng trong không gian mô hình lại với nhau, tất cả chúng sẽ được xếp chồng lên nhau ở giữa gốc.

Thay vào đó, một không gian tọa độ mới gọi là không gian thế giới được xác định. Hãy nghĩ về điều này như thế giới trò chơi của bạn, với nguồn gốc là trung tâm của thế giới. Khi chuyển đổi không gian mô hình sang tọa độ không gian thế giới, các bản dịch, phép quay, tỷ lệ và các thao tác khác được thực hiện. Ví dụ: nếu bạn muốn kết xuất bàn phím ở vị trí (250, 310, 70)của thế giới của mình, bạn sẽ bù tất cả các đỉnh của nó bằng vectơ này. Về mặt toán học, điều này được thực hiện bằng cách sử dụng ma trận biến đổi . Bạn có thể áp dụng một chuyển đổi khác nhau cho từng đối tượng riêng lẻ để đặt các đối tượng trong thế giới trò chơi của bạn.

Bây giờ bạn có một đống lớn các đỉnh trong đó mọi đối tượng được đặt ở vị trí chính xác. Bây giờ bạn cần xác định phần nào của thế giới bạn muốn xem xét. Điều này được thực hiện bằng cách di chuyển tất cả dữ liệu đỉnh vào không gian camera . Một quy ước thường được sử dụng là đặt camera ở vị trí gốc của không gian camera , để nó nhìn về phía trục Z dương ( vectơ mắt ) và có điểm trục Y dương hướng lên ( vectơ hướng lên ). Khi chuyển đổi từ không gian thế giới sang không gian mô hình, do đó, chúng tôi muốn di chuyển và xoay tất cả dữ liệu đỉnh để các đối tượng tiêu điểm của chúng tôi ở gần điểm gốc và có tọa độ Z dương.

Khi bạn nhìn vào các vật thể trong cuộc sống thực, bạn sẽ nhận thấy một hiện tượng gọi là báo trước . Điều này có nghĩa là các đối tượng ở gần bạn có vẻ lớn hơn (nghĩa là chiếm nhiều góc nhìn của bạn hơn), trong khi các đối tượng ở xa bạn xuất hiện nhỏ hơn (tức là chiếm ít hơn tầm nhìn của bạn). Chúng tôi mô phỏng điều này bằng cách áp dụng chuyển đổi phối cảnh , di chuyển tọa độ đỉnh không gian máy ảnh của chúng tôi sang không gian được chiếu .

Cuối cùng, lưu ý rằng chúng ta có dữ liệu đỉnh 3D, cần được hiển thị trên màn hình 2D (ví dụ: 1920 x 1080 pixel). Do đó, dữ liệu đỉnh trong không gian camera được chuyển thành không gian màn hình . API đồ họa của bạn đảm nhiệm việc hiển thị dữ liệu đỉnh không gian màn hình cho màn hình của bạn. Quá trình chuyển đổi dữ liệu đỉnh thành pixel trên màn hình của bạn được gọi là rasterization . Nhưng tọa độ đỉnh nào kết thúc ở đâu trên màn hình của bạn? Đây là nơi mà khối lượng xem chính tắc phát huy tác dụng.

DirectX chỉ định rằng tọa độ X của đỉnh được ánh xạ tới vị trí nằm ngang trên màn hình. Cụ thể: phạm vi [-1 ; 1]được ánh xạ tới [0 ; 1920](trong trường hợp màn hình 1920 x 1080). Tọa độ Y của đỉnh được ánh xạ tới vị trí thẳng đứng trên màn hình. Cụ thể: phạm vi [-1 ; 1]được ánh xạ tới [0 ; 1080](trong trường hợp màn hình 1920 x 1080). Tọa độ Z được sử dụng để xác định các đỉnh cần được hiển thị ở phía trước hoặc phía sau nhau. Cụ thể, các đỉnh gần 0 nằm gần camera và sẽ được hiển thị ở phía trước. Các đỉnh gần 1 nằm cách xa canera và được hiển thị phía sau. Các đỉnh có tọa độ Z nhỏ hơn 0 nằm sau camera và do đó bị cắt bớt - tức là không được hiển thị. Các đỉnh có tọa độ Z lớn hơn 1 quá xa và cũng bị cắt bớt.

Do đó, chuyển đổi phối cảnh của bạn cần phải di chuyển tất cả các đỉnh bạn muốn hiển thị trên màn hình của bạn bên trong khối lượng xem chính tắc này. Trong hướng dẫn bạn đã làm theo, tất cả các biến đổi này được bỏ qua để giữ cho hướng dẫn đơn giản. Do đó, bạn đang trực tiếp kết xuất với khối lượng xem chính. Đây là lý do tại sao tác giả nói bất cứ điều gì ngoài phạm vi [-1 ; 1] x [-1 ; 1] x [0 ; 1]không thể nhìn thấy.

Người giới thiệu

Đối với một bài viết có hình ảnh để minh họa các không gian tọa độ khác nhau này, hãy xem Ma trận chuyển đổi thế giới, chế độ xem và phép chiếu bằng CodingLabs .


1
Tôi đã đọc rất nhiều toán học và lý thuyết đằng sau các đường ống kết xuất, trong các khóa học ở trường và ở nhà vì tò mò, tuy nhiên, lời giải thích đơn giản của bạn đã đưa ra nhiều hơn những bài báo dài đã làm, dễ dàng đi sâu vào các bài viết khi bạn hiểu cơ bản các khái niệm, trước đây tôi chưa bao giờ nghe về khối lượng xem Canonical, điều đó giải thích sự nhầm lẫn của tôi xung quanh phạm vi nhỏ cho các đỉnh. Cảm ơn đã dành thời gian của bạn với điều này!
larssonmartin
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.