Có cách nào để tạo các nguyên hàm trong một shader hình học mà không có bất kỳ hình học đầu vào nào không?


17

Vài năm trước, tôi đã cố gắng triển khai GPU Gem này trong OpenGL để tạo địa hình thủ tục 3D bằng cách sử dụng Marching Cubes . Bài viết gợi ý để thực hiện Marching Cubes trong một shader hình học để đạt hiệu quả tối đa. Điều này có nghĩa là tôi cần chạy shader một lần cho mỗi voxel trong miền và nó sẽ tạo ra toàn bộ hình học trong ô đó.

Một vấn đề tôi vấp phải là làm thế nào để trình tạo bóng hình học chạy mà không thực sự có bất cứ thứ gì để hiển thị bên ngoài trình đổ bóng đó. Giải pháp của tôi (có vẻ khá khó khăn) là kết xuất một điểm trong mỗi ô, loại bỏ nó bằng trình đổ bóng hình học và thay vào đó phát ra các hình tam giác của tôi. Tôi không bao giờ tìm thấy một giải pháp thích hợp và cách giải quyết này vẫn nằm trong mã cuối cùng.

Vì vậy, có cách nào để nói với OpenGL để bắt đầu chuyển kết xuất từ ​​trình đổ bóng hình học mà không có bất kỳ hình học đầu vào nào không? Hoặc tôi sẽ luôn phải gửi một số điểm giả cho GPU để mọi thứ hoạt động.

Câu trả lời:


15

Không, thực sự không có cách nào để làm điều đó.

Một lời gọi shader hình học đòi hỏi một nguyên thủy đầu vào và tạo ra 0 hoặc nhiều hơn các nguyên hàm đầu ra. Nếu không có nguyên thủy đầu vào, thực sự không có cách nào để thực sự gọi trình đổ bóng hình học . Tất nhiên, bạn có thể kéo dài giới hạn số lượng nguyên thủy đầu ra tối đa của trình tạo hình cho mỗi nguyên thủy đầu vào (không biết giới hạn thực tế ngay bây giờ, nên theo thứ tự hàng nghìn có thể). Vì vậy, bạn có thể có thể tạo 1024 tam giác cho mỗi điểm, nhưng bạn luôn phải có một số nguyên hàm đầu vào.

Tuy nhiên, cái bạn không cần là một khái niệm thực tế về hình học. Bạn không thực sự phải hiển thị các điểm 3D ở bất kỳ vị trí hợp lý nào, chúng cũng có thể chỉ có một số chỉ số trừu tượng hoặc tọa độ kết cấu hoặc bất cứ thứ gì là thuộc tính và không nhất thiết phải là một vị trí 3D có ý nghĩa. Không ai ra lệnh những gì thuộc tính đỉnh của bạn có. Và bạn thậm chí có thể kết xuất các đỉnh mà không cần bất kỳ thuộc tính nào . Nhưng bạn phải đưa ra một số nguyên thủy để gọi trình đổ bóng hình học trên chúng, ngay cả khi các nguyên thủy đó không có bất kỳ thuộc tính thực tế nào (cách bạn tính toán hình học đầu ra của mình trong trình đổ bóng hình học là một câu hỏi khác).

Nhưng những gì bạn thực sự đã làm, hiển thị một điểm cho mỗi ô lưới và tạo ra các hình tam giác diễu hành cho ô đó từ đó, chính xác là cách tiếp cận đơn giản. Tất nhiên những thuộc tính mà ô này chứa là tùy thuộc vào bạn, nó có thể là vị trí 3D, texcoord thành kết cấu 3D, bất cứ thứ gì, nhưng đó là những ô lưới mà bạn kết xuất. Nói một cách thuần túy về mặt ngữ nghĩa, bạn không thực sự "loại bỏ" những điểm đó và sau đó "thay thế" chúng bằng các hình tam giác, bạn "chuyển đổi" mỗi điểm thành một tập hợp các hình tam giác. Đó chính xác là những gì shader hình học dành cho và không có gì "hacky" hoặc "không đúng" về nó. Noone nói rằng shader hình học phải tạo ra kiểu nguyên thủy đầu ra giống như đầu vào là "đúng" .


Những gì bạn có thể làm để đạt được cách hiển thị lưới voxel phần lớn không cần đầu vào (và đây có thể là những gì bạn thực sự yêu cầu) sẽ chỉ là vẽ một tập hợp các điểm không liên quan. Điều này có nghĩa là bạn hoàn toàn không cần bất kỳ mảng thuộc tính nào và chỉ cần vô hiệu hóa tất cả chúng và gọi đơn giản glDrawArraysvới số lượng ô bạn cần. Sau đó, trong shader đỉnh hoặc shader hình học, bạn có thể tạo chỉ mục ô lưới 3D cần thiết với một chút ma thuật chỉ mục từ ID đỉnh đầu vào (nghĩa gl_VertexIDlà thông tin duy nhất bạn có) và sau đó tính toán hình học diễu hành của bạn từ tra cứu vào kết cấu khối lượng 3D (hoặc bất kỳ cơ sở hạ tầng nào).

Vì vậy, khi nhìn lại, tôi nên xác định lại câu lệnh của mình ngay từ đầu: Bạn không thể tạo ra các nguyên hàm mà không có bất kỳ nguyên hàm đầu vào nào , nhưng bạn có thể tạo chúng mà không cần bất kỳ hình dạng đầu vào nào .

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.