Điều gì chính xác gây ra một bề mặt chồng lên nhau?


10

Tôi thực sự không thể tìm ra nguyên nhân khiến một bề mặt chồng lên nhau. Trong một công cụ 3D tôi đang tạo, kỹ thuật của tôi bị lỗi trong các trường hợp cạnh.

Phương pháp của tôi là sắp xếp các bề mặt được sơn từ xa nhất đến gần nhất. Để xác định mức độ gần gũi, tôi đang so sánh các giá trị z trung bình. Tuy nhiên, đôi khi, một bề mặt chồng lấp có giá trị z trung bình cao hơn bề mặt chồng lấp. Do đó, bề mặt xa hơn được vẽ trên bề mặt gần hơn - dẫn đến kết xuất kỳ quái như thế này:

Hình vuông màu tím lớn với một phần màu đỏ ở bên cạnh

Những gì người ta có nghĩa là chỉ nhìn thấy mặt trước màu tím của khối lập phương, trong khi mặt màu đỏ được sơn lên trên mặt màu tím. Giá trị z trung bình của bề mặt màu tím cao hơn và do đó 'xa hơn'. Vì vậy, tôi có một số nghi ngờ về việc liệu kỹ thuật này là chính xác.

Những gì tôi cũng đã cố gắng là đưa khoảng cách từ máy ảnh (tức là nguồn gốc) lên bề mặt, nhưng sau đó tôi cần một điểm. Tôi đã chọn giữa mỗi bề mặt nhưng điều này dường như không phải lúc nào cũng hoạt động vì không phải tất cả các bề mặt đều lớn như nhau.

Vì vậy, một cách đáng tin cậy để xác định thứ tự đóng của các bề mặt đối với nguồn gốc là gì?

Câu trả lời:


11

Có vẻ như bạn đang cố gắng thực hiện Thuật toán Họa sĩ . Tôi đoán bạn đang cố gắng viết rasteriser từ đầu như một bài tập học tập, vì hầu hết phần cứng 3D hiện đại sử dụng những gì Bart đã đề cập (bộ đệm Z / Depth). Để thuật toán họa sĩ hoạt động trong mọi trường hợp, bạn cần chuẩn bị chia nhỏ các bề mặt khi chúng được hiển thị để giải quyết các tình huống có thể xảy ra (chẳng hạn như vấn đề đa giác chồng chéo được hiển thị trên trang Wikipedia).

Bằng cách hiển thị từ xa nhất đến gần nhất, bạn cũng dành thời gian kết xuất các pixel mà sau này có thể bị các đa giác khác chặn lại, khi bạn bắt đầu đặt họa tiết và đổ bóng phức tạp lên các đa giác sẽ làm lãng phí các chu kỳ quý giá. Đây là lý do phần cứng hiện đại muốn bạn kết xuất từ ​​trước ra sau, sử dụng bộ đệm độ sâu để xác định xem pixel sẽ được hiển thị có xa hơn so với pixel trên màn hình hay không (và do đó có thể bị loại bỏ).

Ngay cả với hầu hết các phần cứng tăng tốc hiện đại, bạn vẫn sẽ cần sắp xếp và kết xuất từ ​​trước ra trước bất kỳ đa giác bán trong suốt nào, chỉ hiển thị điều này một khi tất cả các đa giác mờ đã được hiển thị.


Bạn đã đúng khi nói rằng tôi đang tạo một trình kết xuất đơn giản. Vấn đề là tôi không sử dụng bất kỳ thư viện 3D nào. Tôi đang tự mình thực hiện tất cả các phép tính chiếu và sau đó vẽ các đường bằng thư viện vẽ 2D. Đây không phải là nhanh nhất ngoài đó và tôi không làm gì trên cơ sở mỗi pixel. Tôi chỉ có 4 điểm của mỗi bề mặt và tô màu hình chữ nhật bằng một màu. Vì tôi đang vẽ một bề mặt hoàn chỉnh cùng một lúc, tôi có đúng không khi nói rằng tôi phải vẽ lại phía trước?
pimvdb

Âm thanh như rất nhiều niềm vui và một cách tuyệt vời để học hỏi. Quay lại phía trước là cách duy nhất của bạn nếu bạn đang làm điều này mà không có bất kỳ hình thức đệm sâu nào. Tôi nghĩ rằng bạn sẽ phải tìm ra tất cả các tọa độ màn hình của đa giác của bạn và sau đó kiểm tra xem có sự chồng chéo nào không. Khi chúng trùng nhau theo chiều sâu, bạn có khả năng sẽ cần phải cắt các đa giác để kết xuất, do đó bạn thực sự có thể giải quyết việc sắp xếp chính xác. Bạn cũng có thể muốn nhìn vào Back Face Culling như một cách để loại bỏ các đa giác không nhất thiết phải nhìn thấy
Roger Perkins

Roger Perkins đã đúng. Bạn sẽ không thể đạt được cách sắp xếp z chính xác theo cách đó (có nghĩa là bạn sẽ luôn có một số trường hợp cạnh), trừ khi bạn cắt các đa giác. Điều đó có thể trở nên khá chậm mặc dù.
bummzack

Tôi đã làm cho nó hoạt động! Những gì tôi đã làm là sự kết hợp của việc loại bỏ backface và sắp xếp: trong một khối lập phương, một số khuôn mặt không thể nhìn thấy trong khi những khuôn mặt khác (tối đa là 3). Vì vậy, tôi đã vẽ những phần không nhìn thấy trước và những phần có thể nhìn thấy trên chúng. Điều này hoạt động giống như một lá bùa, nếu tôi loại bỏ một hoặc nhiều mặt, chúng chồng chéo nhưng vẫn được vẽ theo đúng thứ tự. Cảm ơn!
pimvdb

1
Điều đó sẽ chỉ làm việc cho các hình dạng lồi đơn giản, như hình khối. Tôi rất vui vì nó hiện đang làm việc cho bạn, nhưng nó không phải là một giải pháp chung.
Richard Fabian

3

Những gì bạn có là một vấn đề tầm nhìn . Một giải pháp là sử dụng bộ đệm z .


Cảm ơn, nhưng bộ đệm z yêu cầu hiển thị theo pixel nếu tôi không nhầm. Tôi không làm điều đó - Tôi đang vẽ các đường thẳng giữa các điểm được chiếu của khối lập phương. Là đệm z vẫn có thể?
pimvdb

Ngay cả khi bạn đang vẽ các đường thẳng, tại một số điểm trước khi hình ảnh xuất hiện trên màn hình (hoặc tệp bitmap), nó sẽ ở định dạng pixel.
Bart van Heukelom

Điều đó đúng nhưng thư viện vẽ của tôi quá chậm để thực hiện kết xuất pixel với 20 khung hình / giây. Cảm ơn mặc dù.
pimvdb

2

Sắp xếp các mặt theo giá trị z trung bình của chúng không hoạt động, bởi vì giá trị z trung bình không cung cấp thông tin về giá trị z thực tế của các đỉnh hoặc thậm chí các pixel bề mặt.

Ví dụ (cảnh báo, nghệ thuật ASCII phía trước):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

Có hai mặt A và B. Từ góc nhìn của máy ảnh A ở phía trước B. Tuy nhiên, giá trị z trung bình của B nhỏ hơn. Hãy xem xét các giá trị z khác:

  • giá trị z tối thiểu của A là 4
  • giá trị z tối đa của A là 11
  • do đó giá trị z trung bình của A là 7,5
  • giá trị z tối thiểu của B là 6
  • giá trị z tối đa của B là 8
  • do đó giá trị z trung bình của B là 7

Bạn có thể cố gắng sắp xếp chúng theo các giá trị z tối thiểu của chúng nhưng cũng có trường hợp nó không hoạt động. Không có cách nào để sắp xếp chính xác các mặt tùy ý bằng cách chỉ sử dụng một giá trị z.

Trong thuật toán của Newell http://en.wikipedia.org/wiki/Newell 's_alacticm những gì bạn làm là sắp xếp các phạm vi tối thiểu / tối đa của các giá trị z. Nếu phạm vi của hai mặt không trùng nhau, bạn có thể biết chắc chắn mặt nào ở phía trước. Nếu họ làm, đôi khi bạn hoàn toàn phải chia khuôn mặt. Đôi khi nó sẽ đủ để raytrace mỗi đỉnh cho tắc hoặc một số kỹ thuật khác.


Sơ đồ đó là một cái nhìn từ trên cao về những gì tôi sẽ đoán đang diễn ra trong ảnh chụp màn hình của anh ấy.
jhocking

1

Thật tốt khi bạn đang học về kết xuất bằng cách thực hiện. Thanh danh. Trong trường hợp này, không có giải pháp "thuật toán họa sĩ", thay vì cố gắng khắc phục bằng cách sắp xếp, trên PS1, chúng tôi thường cố gắng giữ các đa giác có cùng kích thước khi chúng ở cạnh nhau (mà bạn đang làm như xa như tôi có thể nói), và backface cull (điều mà bạn không làm)

Loại bỏ backface đang kiểm tra bề mặt bình thường trong không gian màn hình để tìm hướng của nó (chỉ cần lấy dấu của phần tử độ sâu từ không gian màn hình biến đổi bình thường (trong trường hợp của chúng tôi là z của bình thường) hoặc sản phẩm chéo của hai vectơ của tam giác tức là chéo (v1-v0, v2-v0))

Nếu bạn thực hiện loại bỏ backface, bạn cũng sẽ giảm số lần rasterising bạn đang làm .. thắng gấp đôi.


Cám ơn phản hồi của bạn. Tôi đã đọc về loại bỏ backface nhưng vấn đề là tôi muốn có thể loại bỏ một bên. Với một khối lập phương vững chắc, điều này có thể hoạt động rất tốt, nhưng nếu tôi loại bỏ một bên thì sẽ có sự xuất hiện - vì vậy tôi vẫn cần phải sắp xếp chúng tôi đoán. Dù sao, tôi đã nảy ra ý tưởng bắn một tia từ gốc tọa độ qua điểm giữa của một bề mặt. Nếu tia đó đi qua một bề mặt khác sau đó, thì bề mặt thứ nhất chồng lên bề mặt thứ hai. Bạn có thể cho tôi biết ý kiến ​​đó có đúng không? Cảm ơn!
pimvdb

Mặc dù ý tưởng của bạn sẽ hoạt động cho trường hợp ví dụ của bạn, có rất nhiều trường hợp khác mà nó sẽ không hoạt động. Ví dụ, cùng một cảnh bạn có ở đó, nhưng với máy ảnh nghiêng để trung tâm của hình tứ giác hiển thị không chính xác không bị chồng chéo. Tôi nghĩ bạn sẽ phải sắp xếp các nguyên thủy của mình thành các phần nhỏ hơn.
Richard Fabian
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.