Tôi hiện đang phát triển một công cụ trò chơi sử dụng các trường khoảng cách đã ký như một kỹ thuật kết xuất để hiển thị hình học thủ tục trơn tru (được tạo ra với các nguyên thủy đơn giản như các liên kết trong liên kết của bạn bây giờ, tìm cách triển khai các fractals Julia và IFS trong tương lai). Vì động cơ của tôi tập trung vào việc tạo thủ tục và phải xác định các số liệu theo cách làm cho chúng thân thiện với tia sáng, tôi cho rằng tôi là một nơi tốt để trả lời câu hỏi này: P.
Liên quan đến phát trực tuyến, giải pháp đơn giản là sử dụng bộ đệm được gõ một số loại và ném nó lên GPU khi bạn muốn thực hiện di chuyển tia. Mỗi phần tử của bộ đệm là một loại phức tạp (ví dụ: struct trong C / C ++) và mỗi loại chứa các thành phần xác định chức năng nào bạn nên sử dụng để thể hiện nó, đó là vị trí, góc quay, tỷ lệ, v.v. và màu trung bình. Quá trình sau đó đơn giản hóa thành:
- Đưa cảnh của bạn vào một tập hợp con có thể quản lý được (lưu ý rằng việc loại bỏ bực bội và loại bỏ tắc nghẽn được thực hiện một phần tự động bằng thuật toán di chuyển bằng tia dù sao)
- Truyền tập hợp con vào bộ đệm kết xuất đầu vào của bạn
- Truyền bộ đệm cho GPU nếu nó chưa có, sau đó kết xuất cảnh của bạn bằng cách di chuyển bằng tia truyền thống thông thường. Bạn sẽ cần thực hiện một số loại tìm kiếm theo từng bước để đánh giá mục nào trong bộ đệm đầu vào gần nhất với mỗi tia cho mỗi lần lặp của tia-marcher và bạn sẽ cần áp dụng các phép biến đổi cho các tia (trong trường hợp này bạn sẽ cần đảo ngược các góc quay trước khi chúng chạm tới GPU) hoặc chính các chức năng khoảng cách (di chuyển nguồn gốc chức năng để thay đổi vị trí, điều chỉnh độ dài cạnh khối để thay đổi tỷ lệ, v.v.) Cách tiếp cận đơn giản nhất là chỉ sửa đổi các tia trước bạn chuyển chúng cùng với chức năng khoảng cách lõi thực tế.
Về màu sắc hình, hãy nhớ rằng các shader cho phép bạn xác định các loại phức tạp cũng như nguyên thủy;). Điều đó cho phép bạn ném mọi thứ vào cấu trúc kiểu C, sau đó chuyển các cấu trúc đó trở lại từ chức năng khoảng cách của bạn.
Trong công cụ của tôi, mỗi cấu trúc chứa một khoảng cách, một màu và một ID liên kết nó với định nghĩa hình tương ứng trong bộ đệm đầu vào. Mỗi ID được suy ra từ bối cảnh xung quanh của hàm khoảng cách có liên quan (do hàm ánh xạ của tôi lặp qua bộ đệm đầu vào để tìm con số gần nhất với mỗi tia cho mỗi bước, tôi có thể xử lý một cách an toàn giá trị của bộ đếm vòng lặp khi mỗi SDF được gọi làm ID hình cho chức năng đó), trong khi các giá trị khoảng cách được xác định bằng SDF lõi tùy ý (ví dụ:point - figure.pos
đối với hình cầu) và màu sắc được xác định từ màu trung bình của phần tử thích hợp trong bộ đệm hình (do đó tại sao việc giữ ID hình xung quanh) hoặc thông qua màu thủ tục có trọng số đối với mức trung bình được lưu trữ (một ví dụ có thể được lấy số lần lặp cho một số điểm trên Mandelbulb, ánh xạ "màu trung bình" của bạn từ không gian màu FP sang không gian màu số nguyên, sau đó sử dụng màu được ánh xạ làm bảng màu bằng cách XOR so với số lần lặp).
Hoạ tiết thủ tục là một cách tiếp cận khác, nhưng bản thân tôi chưa bao giờ sử dụng chúng. iq đã thực hiện khá nhiều nghiên cứu trong lĩnh vực đó và đăng một số cuộc biểu tình thú vị trên Shadertoy, vì vậy đó có thể là một cách để thu thập thêm một số thông tin.
Bất kể màu của bạn là tĩnh đối với mỗi hình, được tạo theo thủ tục hoặc được lấy mẫu một cách kỳ diệu từ kết cấu thủ tục, logic cơ bản là như nhau: Tóm tắt các hình thành một loại phức tạp trung gian (ví dụ: struct), lưu trữ cả khoảng cách cục bộ và cục bộ màu trong một thể hiện của loại đó, sau đó chuyển loại phức tạp thành giá trị trả về từ hàm khoảng cách của bạn. Tùy thuộc vào việc triển khai của bạn, màu đầu ra sau đó có thể chuyển trực tiếp đến màn hình hoặc theo điểm va chạm vào mã chiếu sáng của bạn.
Tôi không biết những điều trên có đủ rõ ràng hay không, vì vậy đừng lo lắng về việc liệu có bất cứ điều gì không có ý nghĩa hay không. Tôi thực sự không thể đưa ra bất kỳ mẫu mã bóng mờ GLSL / pixel nào kể từ khi tôi làm việc với HLSL và tính toán độ bóng, nhưng tôi rất vui khi thử và xem qua bất cứ điều gì tôi không viết đúng ở vị trí đầu tiên :).