Làm thế nào để shader fractal nhỏ này hoạt động?


7

Tôi muốn biết phép thuật đằng sau shader fractal nhỏ bé này; Tôi đã không thực sự hiểu mã và chủ đề được đề cập ...

Có một lời giải thích có thể truy cập?

https://www.shadertoy.com/view/4ttBWM

Câu trả lời:


10

Đây là một phân tích từng dòng của shader của tôi:

#define mainImage(o,p)\
    for( vec2 r = iResolution.xy, q = 2.*(p+p-r)/r.y; o.a++ < 30.; )\
        o += length( q = abs(q)/dot(q,q) - iMouse.xy/r) / 2e2

Đầu tiên, điều quan trọng là phải biết rằng, \ \ ở cuối hai dòng đầu tiên không được tính vào số lượng ký tự và chỉ phục vụ để làm cho mã dễ đọc hơn bằng cách chia nó thành nhiều dòng.

#define mainImage(o,p)

Bắt đầu định nghĩa của hàm thường được viết void mainImage (out FragColor, in FragCoord) {...} Điều này sẽ lưu một vài ký tự.

Phần đầu tiên của vòng lặp:

vec2 r = iResolution.xy, q = 2.*(p+p-r)/r.y;

Thiết lập hai biến loại Vector2:

r là độ phân giải cho phép tôi tham khảo iResolution nhiều lần sau với ít ký tự hơn.

q là tọa độ trong fractal được tính từ FragCoord p và sau đó được lặp lại trong mỗi vòng lặp.

Thay vì FragCoord bắt đầu từ (0,0) ở góc dưới bên trái và mở rộng sang (rx, ry) ở trên cùng bên phải, (p + pr) biến đổi mỗi FragCoord sao cho tâm của màn hình là (0,0) . Điều này nhân đôi giá trị FragCoord và sau đó trừ đi độ phân giải của cửa sổ. Phép chia theo ry phù hợp với tọa độ sao cho đỉnh có giá trị ay bằng 1 và đáy có giá trị ay là -1. Với điều này, x được chia tỷ lệ tương ứng mà không kéo dài. Cuối cùng, phép nhân với 2 chỉ cần thu nhỏ theo hệ số 2.

Sau đó, đối với iterator, tôi sử dụng oa (kênh alpha của o). o là màu đầu ra là vec4. Theo định nghĩa của Shadertoy, o bắt đầu bằng giá trị vec4 (0,0,0,1). Tôi sử dụng điều này để tôi không cần sử dụng các ký tự khai báo float mới như một trình vòng lặp. o.a ++ <30 kết hợp biểu thức kiểm tra và trình vòng lặp trong vòng lặp for.

Nội dung của vòng lặp là một dòng trong đó một số được thêm vào mỗi kênh của màu đầu ra. Đường thẳng này:

o += length( q = abs(q)/dot(q,q) - iMouse.xy/r) / 2e2

Có thể được chia thành một vài phần. Mỗi lần lặp của tọa độ trong fractal xảy ra ở đây:

q = abs(q)/dot(q,q) - iMouse.xy/r

Trong đó iMouse.xy / r là cách chuyển đổi tọa độ chuột từ pixel sang phạm vi (0,0) thành (1,1)

Mỗi lần lặp của hàm này thay đổi giá trị của q sẽ được sử dụng.

Điều tạo ra fractal này là ý tưởng rằng một số giá trị ban đầu cho q sẽ thoát ra vô cùng và những giá trị khác sẽ hội tụ hoặc xoay quanh một vài giá trị nhỏ. Mỗi lần lặp tôi tăng độ sáng của pixel dựa trên khoảng cách q từ (0,0). Độ dài này của q sau đó được chia cho hằng số 2e2 (200) để ngăn o.rgb tăng quá nhanh.

Nội dung của vòng lặp có thể được hiểu là hai bước:

q = abs(q)/dot(q,q) - iMouse.xy/r;
o += length(q) / 2e2;

Cuối cùng, ngay cả khi o chứa một giá trị trong một trong các kênh lớn hơn 1, nó sẽ được Shadertoy kẹp tự động và không cần một dấu chấm phẩy ở dòng cuối cùng.


Tuyệt quá! Làm thế nào bạn tìm thấy công thức này abs(q)/dot(q,q) - iMouse.xy/r? Đây có phải là nghiên cứu thực nghiệm hay bạn có một phương pháp để tìm ra các công thức có tính chất tốt?
arthur.sw

1
@ arthur.sw Tôi tìm thấy công thức này ở đây: link , và sau đó điều chỉnh nó để hoạt động cho shader của tôi.
mathmasterzach

1
Nếu bạn quan tâm đến các kỹ thuật đánh gôn, chúng tôi cũng có một trang dành cho ... Họ đăng các thử thách để thi đấu, nhưng cũng chấp nhận các câu hỏi được gắn thẻ "mẹo" để được tư vấn về việc chơi golf nói chung hoặc giảm một đoạn mã cụ thể.
trichoplax
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.