GLSL에서 IFS 쉘핀 스키 카펫
처음에 Mneger Sponge라고 생각했습니다만, 3D보다 2D쪽이 간단할 것이라는 것으로 Menger Sponge의 2D판이라고 하는 느낌의 셰르펜스키의 카펫을 생각해 보았습니다.

실제로 하려고 하면 어떻게 공간을 조작하는지가 어렵고, 반나절 정도 고민했기 때문에 비망록으로서 기사로 했습니다.
스스로 생각한 방법과 iq씨가 이 기사 로 Menger Sponge에 대해 해설하고 있는 방법을 참고로 한 것의 두 가지를 소개합니다.
어느 쪽을 사용해도 결과는 같아야합니다 (아마).
스스로 생각한 방법
부울 연산에서 반복 차이를 취하여 쉘핀 스키 카펫을 만듭니다.
실제 코드와 움직이는 것은 여기 에서 볼 수 있습니다.
float sierpinskiCarpet(vec2 p) {
float s = 1.0;
float f = 1.0 / 3.0;
float d = sdBox(p, vec2(s));
for (int i = 0; i < 4; i++) {
d = max(d, -sdBox(p, vec2(f)) / s);
p = abs(p);
p -= f;
p = abs(p);
p -= f;
p *= 3.0;
s *= 3.0;
}
return d;
}
먼저
float d = sdBox(p, vec2(s));
사각형을 그립니다.거기에서
d = max(d, -sdBox(p, vec2(f)) / s);
로 논리 차이를 취하고 중간에 구멍을 뚫습니다.
다음에 주위 8 근방에 대해서도 구멍을 열 필요가 있습니다만, X축, Y축 각각에 대해 대칭이므로
abs(p);
로 공간을 접습니다. 이것에 의해 $x\geqq 0$ 그리고 $y\geqq 0$ 의 좌표만을 생각하면 좋을 것입니다.
접은 것을 보면, X축, Y축 각각에 대해 $(x, y)=(0.333..., 0.333...)$로 (좌하를 무시하면) 대칭이므로
p -= f;
(x, y)=(0.333..., 0.333...)$를 원점으로 이동시킨 다음 p = abs(p);
에서 공간을 다시 접습니다.
접힌 것을
p -= f;
로 구멍이 가운데가 되도록 좌표를 이동시킵니다.
그 결과, 다음과 같이 되어,
p *= 3.0;
하는 것으로 최초의 화상과 같은 상태로 돌아가므로, 같은 조작을 반복해 구멍을 열어 갈 수 있습니다.
iq씨의 Menger Sponge를 참고로 한 방법
부울 연산에서 반복 곱을 취하여 쉘핀 스키 카펫을 만듭니다.
코드와 실제로 움직이는 것은 여기 로 보입니다.
float sdCross(vec2 p) {
p = abs(p);
return min(p.x, p.y) - 1.0;
}
float sierpinskiCarpet(vec2 p) {
float d = sdBox(p, vec2(1.0));
float s = 1.0;
for (int i = 0; i < 4; i++) {
vec2 a = mod(p * s, 2.0) - 1.0;
vec2 r = 1.0 - 3.0 * abs(a);
s *= 3.0;
float c = sdCross(r) / s;
d = max(d, c);
}
return d;
}
먼저
float d = sdBox(p, vec2(1.0));
로 사각형을 그리는 것은 앞에서 설명한 기법과 동일합니다.vec2 a = mod(p * s, 2.0) - 1.0;
로 좌표를 조작하면 빨간색으로 표시됩니다.
또한
vec2 r = 1.0 - 3.0 * abs(a);
에서 좌표는 다음과 같습니다.
float c = sdCross(r) / s;
는 다음과 같은 형태로 되어 있으며 d = max(d, c);
로 논리적을 취하여 구멍 이외의 부분을 남길 수 있습니다.
여담
iq 씨의 Menger Sponge 기사 은 매우 참고가 됩니다만, 최초의 코드에서는 논리차를 취하는데, 반복이 도입되고 나서는 논리적을 취하게 되기 때문에 기사를 읽어내는데 주의가 필요합니다.

Reference
이 문제에 관하여(GLSL에서 IFS 쉘핀 스키 카펫), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/aa_debdeb/items/03609566ea322a4b764f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)