Làm thế nào tôi nên xử lý các đỉnh cắt gần mắt hơn so với mặt phẳng clip gần?


13

Tôi đang sử dụng công cụ 3D của riêng mình, bằng JavaScript và chỉ sử dụng bản vẽ canvas, không có WebGL. Đây là một bản sao Minecraft khác; Tôi yêu những chiếc hộp, đừng phán xét tôi.

Cho đến nay, mọi thứ hoạt động tuyệt vời, ngoại trừ một điều: trong 3D, khi một số đỉnh đi phía sau mặt phẳng cắt gần, hình chiếu của chúng trên màn hình xuất hiện kỳ ​​lạ (giả sử các đỉnh khác được sử dụng để theo dõi một mặt phẳng ở phía trước).

Tôi đã thử cắt các điểm này nhưng sau đó tôi có thể thấy các bề mặt sử dụng các đỉnh này. Trong WebGL / OpenGL, card đồ họa sẽ xử lý các điểm này và mặt phẳng được hiển thị chính xác, nhưng tôi không có quyền truy cập vào phần cứng nên tôi phải tự viết mã này.

Tôi không chắc chắn nên làm gì với nó, hiện tại điều cuối cùng xuất hiện là đảo ngược hình chiếu của các điểm phía sau mặt phẳng cắt của người chơi, điều này có vẻ hợp lý vì tôi phải chiếu một điểm lên màn hình phía trước của đỉnh.

Đây là suy nghĩ của tôi:

nhập mô tả hình ảnh ở đây

Dưới đây là một số hình ảnh để minh họa những gì xảy ra:

nhập mô tả hình ảnh ở đây

Từ khoảng cách hộp màu xanh hoàn toàn tốt.

nhập mô tả hình ảnh ở đây

Khi một số đỉnh đi phía sau mặt phẳng cắt của người chơi, tôi thực hiện phép chiếu ngược, nhưng nó không đúng:

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

Lưu ý rằng hộp màu xám phía sau được loại bỏ hoàn toàn vì tất cả các đỉnh được sử dụng để vẽ mặt của nó nằm phía sau trình phát.

nhập mô tả hình ảnh ở đây

Đây là những gì xảy ra khi nhìn lên hoặc xuống.

Tôi không biết phải làm gì với toán học đằng sau điều này, tôi hy vọng ai đó đã gặp phải vấn đề tương tự và có thể giúp tôi.


1
Nếu các điểm ở gần mắt hơn mặt phẳng clip gần, chúng sẽ được cắt bớt - và điều này thực sự có thể cho phép bạn nhìn "xuyên qua" một vật thể. Đây là hành vi điển hình; va chạm thường ngăn chặn tạo tác hình ảnh cụ thể đó. Đó có phải là điều duy nhất sai với giải pháp cắt của bạn?

@JoshPetrie: Tôi hiểu rằng các điểm phải được cắt bớt, nhưng nếu tôi làm vậy thì toàn bộ hình vuông sẽ biến mất khi một hoặc hai đỉnh mà thói quen vẽ phải vượt qua (trong 2d) và người chơi sẽ có thể nhìn thấy qua hình vuông đó. Tôi muốn chúng ở "bên ngoài" khung vẽ (trên hình chiếu) để hình vuông vẫn có thể được vẽ. Tôi không chắc là tôi đủ rõ ràng.
Solenoid

Bạn đang - tôi nói đó là hành vi bình thường và bạn muốn ngăn chặn điều này xảy ra bằng cách ngăn chặn các cầu thủ từ nhận rằng gần một trong những hình khối. Nếu bạn thực sự muốn làm điều này, bạn nên cắt nhưng dựng lại các hình tam giác (có thể). Điều này sẽ vẫn trông bất thường, đặc biệt là nếu bạn có kết cấu. Nếu những gì tôi nói không có ý nghĩa, bạn có thể tham gia với chúng tôi trong cuộc trò chuyện để chúng tôi không tạo ra một chuỗi nhận xét thực sự trò chuyện.

Những gì bạn đang nói có ý nghĩa, việc xây dựng lại mất quá nhiều thời gian nên đó không phải là giải pháp. Tôi hy vọng có một cách để vẫn vẽ đỉnh đó trên mặt phẳng 2d phía sau người chơi để lineTo(x,y)chức năng vẫn có thể được gọi, chỉ tôi không biết nó hoạt động như thế nào ... đó là một chiều kỳ quái, tôi đồng ý.
Solenoid

Câu trả lời:


1

Mục đích của mặt phẳng cắt gần là nó là mặt phẳng cắt . Các hình tam giác nằm ngoài mặt phẳng cắt được cắt bớt : cắt thành từng mảnh sao cho mỗi mảnh còn lại nằm trong vùng cắt.

Bạn có thể cố gắng bỏ qua clip gần nếu bạn muốn. Thật vậy, OpenGL và D3D có cách tắt hoàn toàn gần mặt phẳng (mặc dù bộ đệm sâu vẫn có giá trị gần tối thiểu). Vấn đề không phải là clip gần.

Vấn đề là với các đỉnh nằm phía sau camera.

Bạn không thể kết xuất các hình tam giác phía sau camera. Không phải với một hình chiếu phối cảnh. Các tam giác như vậy không có ý nghĩa theo toán học đằng sau các dự đoán phối cảnh. Hơn nữa, họ cũng ở bên ngoài của sự thất vọng.

Tắt gần cắt biến một sự thất vọng thành một kim tự tháp. Lý do kim tự tháp dừng lại tại điểm là vì các điểm phía trên kim tự tháp nằm phía sau tất cả bốn phía của kim tự tháp. Vì vậy, bất kỳ điểm nào phía sau máy ảnh (đầu của kim tự tháp) ở trên, bên dưới, bên trái và bên phải của khu vực có thể nhìn thấy của màn hình. Tất cả cùng một lúc.

Như tôi đã nói: các đỉnh dưới một hình chiếu phối cảnh phía sau camera không có ý nghĩa gì.

Bạn phải thực hiện cắt. Bạn phải phát hiện khi bất kỳ đỉnh của một hình tam giác, trong không gian clip ( trước khi phân chia phối cảnh) ở phía sau máy ảnh. Nếu có, thì bạn phải cắt hình tam giác đó, chỉ tạo ra các hình tam giác ở phía trước máy ảnh.

Đây không phải là một quá trình đơn giản. Nó sẽ liên quan đến toán học chỉ có ý nghĩa nếu bạn có hiểu biết đầy đủ về các hệ tọa độ đồng nhất. Ngoài ra, bạn có thể chỉ cần loại bỏ thẳng bất kỳ hình tam giác nào nếu có bất kỳ đỉnh nào của nó nằm phía sau máy ảnh.


Cho đến bây giờ tôi đã loại bỏ toàn bộ tam giác, nhưng sau đó tôi nhìn thấy qua mặt phẳng (xem hình trên). Tôi thực sự cần một bức tranh để hiểu tại sao nó không có ý nghĩa về mặt hình học. Giải pháp duy nhất là tính toán giao tuyến của mặt phẳng khi một trong các đỉnh nằm phía sau mặt phẳng cắt và sử dụng giao điểm đó để theo dõi đường thẳng từ đỉnh phía trước, thật không may, điều này rất tốn kém.
Solenoid

0

Nếu một phần của tam giác ở phía sau mặt phẳng gần thì bạn có thể thực hiện kiểm tra theo pixel để xem vị trí pixel có nằm sau mặt phẳng cắt không?

Bạn có thể coi mặt phẳng gần giống như bất kỳ mặt phẳng cắt nào khác. Ví dụ, các mặt phẳng cắt được sử dụng cho những thứ như máy bay nước (cho phản xạ và khúc xạ). Tôi nghĩ rằng mặt phẳng cắt này sẽ hoạt động giống như mặt phẳng cắt gần và kẹp trên cơ sở mỗi pixel.

Tôi biết cách xử lý các mặt phẳng cắt trong HLSL bằng DirectX, nhưng việc triển khai chúng có thể là độc quyền. Nếu bạn có thể nắm giữ thông tin cho rằng nó có thể hữu ích.

Ngoài ra, đây là một liên kết có thể giúp bạn: http://http.developer.nvidia.com/GPUGems2/gpugems2_ch CHƯƠNG42.html


Kiểm tra mỗi pixel là cực kỳ tốn kém trong một ngôn ngữ được dịch như Javascript, hiện tại tôi đang nhận được hầu hết các khung hình / giây.
Solenoid
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.