OpenGL - Phát hiện các cạnh


11

Tôi muốn tải các mắt lưới tùy ý và vẽ các đường đen dày dọc theo các cạnh để có được vẻ ngoài toon-like. Tôi quản lý để vẽ một hình bóng màu đen xung quanh các đối tượng bằng cách sử dụng bộ đệm stpson. Bạn có thể xem kết quả ở đây:

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

Nhưng những gì còn thiếu là các đường màu đen trong chính đối tượng. Tôi nghĩ về việc kiểm tra sự không liên tục bình thường: Kiểm tra xem một pixel lân cận có vectơ bình thường khác với hiện tại không. Nếu có, một cạnh đã được tìm thấy. Thật không may, tôi không biết làm thế nào tôi có thể thực hiện cách tiếp cận này, trong OpenGL cũng như trong shader đỉnh / phân đoạn GLSL.

Tôi rất vui vì một số trợ giúp về phương pháp này hoặc bất kỳ cách nào khác liên quan đến phát hiện cạnh.

Chỉnh sửa: Tôi không sử dụng bất kỳ kết cấu cho lưới của tôi.

Nói chính xác hơn, tôi muốn tạo một giải pháp CAD / CAM trông giống nhất có thể như thế này (được lấy từ Top Solid https://www.youtube.com/watch?v=-qTJZtYUDB4 ):

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


Tôi tin rằng bạn cần xác định "cạnh" chi tiết hơn. Nó khác với một khung dây đơn giản như thế nào? Trong câu trả lời cifz có một mô tả tốt về quá trình hậu không gian màn hình, nhưng từ câu hỏi của bạn, rất khó để xác định nếu nó được áp dụng.
Andreas

Vâng, với cạnh tôi có nghĩa là "nếp gấp" và "đường vân" tạo thành chất rắn. Một khung dây sẽ hiển thị tất cả các mặt tam giác, đó không phải là điều tôi muốn.
enne87

Ok, chính xác những gì tôi yêu cầu :-) Tôi sẽ tạo ra một khung dây từ những nếp gấp và đường vân đó. Phần khó khăn vẫn là xác định nếp gấp / sườn là gì. Bạn có bất cứ ý tưởng làm thế nào để làm điều đó?
Andreas

1
Các chương trình cad không làm điều này với một shader chủ yếu. Thay vào đó, họ biết các cạnh cứng từ mô hình và vẽ một đường trên đầu của mẫu lưới thông tin đó.
joojaa

joojaa bạn có thêm thông tin nào về kỹ thuật này không? Những gì được thực hiện trong trường hợp bề mặt dạng tự do cong đôi? Tôi cũng không chắc điều gì sẽ xảy ra khi bạn có một hình nón hoặc hình trụ đang bị cắt / tỉa bởi một hình thức tự do nào đó. stackoverflow.com/questions/43795262/ từ
Dusan Bosnjak 'pailhead'

Câu trả lời:


17

Nói chung, phát hiện cạnh sôi xuống để phát hiện các khu vực của hình ảnh có giá trị độ dốc cao.

Trong trường hợp của chúng tôi, chúng tôi có thể xem độ dốc là đạo hàm của hàm hình ảnh, do đó độ lớn của độ dốc cung cấp cho bạn thông tin về mức độ hình ảnh của bạn thay đổi cục bộ (liên quan đến các pixel / tex lân cận).
Bây giờ, một cạnh là như bạn nói một dấu hiệu của sự gián đoạn, vì vậy bây giờ chúng tôi đã xác định độ dốc rõ ràng rằng thông tin này là tất cả những gì chúng tôi cần. Khi chúng tôi tìm thấy độ dốc của hình ảnh, vấn đề chỉ là áp dụng ngưỡng cho nó để có được giá trị nhị phân cạnh / không cạnh.

Làm thế nào để bạn tìm thấy gradient này thực sự là những gì bạn đang hỏi và tôi vẫn chưa trả lời :)

Rất nhiều cách! Đây là một cặp :)

Được xây dựng trong các chức năng đổ bóng

Cả hlsl và glsl đều cung cấp các hàm phái sinh. Trong GLSL, bạn có dFdx và dFdy cung cấp cho bạn thông tin độ dốc tương ứng theo hướng x và y. Thông thường các chức năng này được đánh giá trong một khối các mảnh 2x2.
Trừ khi bạn quan tâm đến một hướng duy nhất, một cách tốt để có một kết quả nhỏ gọn cho biết độ dốc trong vùng là băng thông mạnh đến mức nào mang lại cho bạn không gì khác ngoài tổng giá trị tuyệt đối của dFdy và dFdy.
Bạn có thể quan tâm đến một cạnh trên hình ảnh tổng thể hơn là trên một kênh cụ thể, vì vậy bạn có thể muốn chuyển đổi chức năng hình ảnh của mình thành luma. Với ý nghĩ này, khi phát hiện ra cạnh, trình tạo bóng của bạn có thể bao gồm một cái gì đó giống như:

  float luminance = dot(yourFinalColour,vec3(0.2126, 0.7152, 0.0722));
  float gradient = fwidth(luminance );
  float isEdge = gradient > threshold;

Với ngưỡng cao, bạn sẽ tìm thấy các cạnh thô hơn và bạn có thể bỏ lỡ một số, ngược lại, với ngưỡng thấp, bạn có thể phát hiện các cạnh sai. Bạn phải thử nghiệm để tìm ra ngưỡng phù hợp hơn với nhu cầu của bạn.

Lý do tại sao các chức năng này hoạt động là đáng nói nhưng tôi không có thời gian cho nó bây giờ, tôi có thể cập nhật câu trả lời này sau :)

Không gian màn hình hậu xử lý

Bạn có thể thích hơn thế này, bây giờ lĩnh vực phát hiện Edge trong xử lý hình ảnh là vô cùng lớn. Tôi có thể trích dẫn cho bạn hàng chục cách hay để phát hiện cạnh theo nhu cầu của bạn, nhưng bây giờ hãy giữ nó đơn giản, nếu bạn quan tâm tôi có thể trích dẫn cho bạn nhiều lựa chọn hơn!

Vì vậy, ý tưởng sẽ tương tự như ở trên, với sự khác biệt là bạn có thể nhìn vào một vùng lân cận rộng hơn và sử dụng một tập các trọng số trên các mẫu sorrounding nếu bạn muốn. Thông thường, bạn chạy một tích chập trên hình ảnh của bạn với một hạt nhân cung cấp cho bạn kết quả là một thông tin độ dốc tốt.
Một lựa chọn rất phổ biến là nhân Sobel

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

Mà tương ứng cung cấp cho bạn độ dốc theo hướng x và y:

                                  Từ một bản pdf cũ tôi đã viết cách đây rất lâu.

Bạn có thể lấy giá trị đơn ra khỏi gradient như GrmộtdTôientMmộtgnTôitbạnde= =(GrmộtdTôientx)2+(GrmộtdTôienty)2

Sau đó, bạn có thể ngưỡng như cách tôi đã đề cập ở trên.

Hạt nhân này như bạn có thể thấy mang lại nhiều trọng lượng hơn cho pixel trung tâm, do đó, tính toán hiệu quả độ dốc + một chút làm mịn mà theo truyền thống sẽ giúp (thường hình ảnh được làm mờ gaussian để loại bỏ các cạnh nhỏ).

Những điều trên hoạt động khá tốt, nhưng nếu bạn không thích làm mịn, bạn có thể sử dụng hạt nhân Prewitt:

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

(Lưu ý tôi đang vội, sẽ viết văn bản có định dạng phù hợp thay vì hình ảnh sớm!)

Thực sự có rất nhiều hạt nhân và kỹ thuật để tìm phát hiện cạnh theo cách xử lý hình ảnh thay vì đồ họa thời gian thực, vì vậy tôi đã loại trừ các phương thức phức tạp hơn (chơi chữ không có ý định) vì có lẽ bạn sẽ ổn với các chức năng dFdx / y .


Cifz giải thích rất hay, nhưng nếu không nhìn thấy độ dốc trong một tình huống nhất định thì sao? Ví dụ, không có nguồn sáng ở mặt sau của khối và do đó, không thể nhìn thấy độ dốc. Sau đó, quá trình phát hiện cạnh dựa trên hình ảnh này mà bạn mô tả sẽ không hoạt động, phải không?
enne87

Nếu bạn sử dụng trình kết xuất hoãn lại, bạn có thể thực hiện tương tự nhưng trên bộ đệm thông thường hoặc một lần nữa, nếu bạn có một bước chuẩn bị, bạn có thể áp dụng thuật toán cho độ sâu. Tuy nhiên, bạn vẫn đúng, một cách tiếp cận không gian màn hình có thể không lý tưởng trong mọi trường hợp :) Giải pháp nào khả thi phụ thuộc rất nhiều vào ngân sách của bạn cho hiệu ứng này, mức độ phức tạp của cảnh quay của bạn.
cifz

Có khả năng nếu điều này thực sự là trung tâm cho trò chơi của bạn, rất dễ, nhưng có khả năng đánh thuế, sẽ tính toán một độ dốc trên các quy tắc lân cận của bạn cho mỗi đỉnh (ngoại tuyến khi tải) và chuyển yếu tố này làm thuộc tính đỉnh bổ sung.
cifz

Thắng một lần nữa cifz giúp đỡ của bạn. Chà, điều tôi muốn đạt được là phát triển giải pháp CAD / CAM trông giống như thế này: youtube.com/watch?v=-qTJZtYUDB4 Và tôi thực sự muốn biết làm thế nào họ quản lý nó để hiển thị tất cả các cạnh đen, nếp gấp và những rặng núi. Cifz, bạn có nghĩ là một chuyên gia lập trình đồ họa mà họ đạt được giao diện này bằng cách sử dụng một trong các phương pháp tiếp cận không gian màn hình của bạn không? Hoặc có thể bằng cách tính toán một độ dốc trên các quy tắc lân cận? Tôi thực sự muốn biết làm thế nào điều này có thể được thực hiện. Cảm ơn một lần nữa!
enne87

1
Không cần phải trả tiền cho bất cứ ai, chỉ cần bắt đầu đọc một vài hướng dẫn trực tuyến, mua một số sách và học tập chăm chỉ :) Cuối cùng sẽ rất bổ ích!
cifz

3

Chỉ trong trường hợp bất cứ ai Elso cũng cần phải phát hiện cạnh: Đây là một bài viết đẹp như thế nào để hiển thị một wireframe và này bài viết giải thích như thế nào để chỉ hiển thị các cạnh.

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.