From a6b06a176da275689d5efe19ce739c084fcd45f4 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Fri, 10 Feb 2023 16:33:18 +0100 Subject: [PATCH] 11 --- 11/README-pl.md | 97 ++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/11/README-pl.md b/11/README-pl.md index 2f25c08..4b58d69 100644 --- a/11/README-pl.md +++ b/11/README-pl.md @@ -3,9 +3,9 @@ ## Szum (ang. "noise") -Czas na przerwę! Bawiliśmy się losowymi funkcjami, które wyglądają jak telewizyjny biały szum, w głowie wciąż się kręci myśląc o shaderach, a oczy są zmęczone. Czas wyjść na spacer! +Czas na przerwę! Bawiliśmy się losowymi funkcjami, które wyglądają jak biało-czarny szum telewizyjny (tzw. "szum biały", ang. "white noise"), w głowie wciąż się kręci od myślenia o shaderach, a oczy są po prostu zmęczone. Czas wyjść na spacer! -Czujemy powietrze na skórze, słońce na twarzy. Świat jest tak żywym i bogatym miejscem. Kolory, tekstury, dźwięki. Podczas spaceru nie możemy nie zauważyć powierzchni dróg, skał, drzew i chmur. +Czujemy powietrze na skórze, słońce na twarzy. Świat jest tak żywym i bogatym miejscem. Kolory, tekstury, dźwięki. Podczas spaceru widzimy powierzchnię dróg, skał, drzew i chmur. @@ -45,7 +45,7 @@ y = rand(i); //rand() is described in the previous chapter W tych liniach robimy coś podobnego do tego, co robiliśmy w poprzednim rozdziale. Dzielimy ciągłą liczbę zmiennoprzecinkową (``x``) na jej składowe całkowitą (``i``) i ułamkową (``f``). Używamy [``floor()``](../glossary/?search=floor) aby uzyskać ``i`` oraz [``fract()``](../glossary/?search=fract) aby uzyskać ``f```. Następnie stosujemy ``rand()`` do części całkowitej ``x``, co daje unikalną wartość losową dla każdej liczby całkowitej. -Po tym widzisz dwie skomentowane linie. Pierwsza z nich interpoluje liniowo każdą wartość losową. +Spójrz na dwie skomentowane linie. Pierwsza z nich interpoluje liniowo każdą wartość losową. ```glsl -float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve -y = mix(rand(i), rand(i + 1.0), u); // using it in the interpolation +float u = f * f * (3.0 - 2.0 * f ); // spersonalizowana funkcja sześcienna +y = mix(rand(i), rand(i + 1.0), u); // interpolacja z jej pomocą ``` -Ta *płynna losowość* jest przełomem dla inżynierów graficznych i artystów - daje możliwość generowania obrazów i geometrii z organicznym uczuciem. Algorytm Szumu Perlina był wielokrotnie implementowany w różnych językach i wymiarach, aby stworzyć hipnotyzujące dzieła dla wszystkich rodzajów kreatywnych zastosowań. +Ta *płynna losowość* jest przełomem dla programistów grafiki i artystów - daje możliwość generowania organicznych obrazów i geometrii. Algorytm Szumu Perlina był wielokrotnie implementowany w różnych językach i wymiarach, aby móc tworzyć hipnotyzujące dzieła w celach kreatywnych. @@ -96,8 +96,6 @@ Teraz twoja kolej: * Skonstruuj "organicznie wyglądające" kształty używając funkcji noise. -* Gdy masz już swoje "stworzenie", spróbuj rozwinąć je w postać, przypisując mu określony ruch. - -## 2D Noise +## Szum 2D ![](02.png) -Teraz, gdy wiemy jak zrobić szum w 1D, czas przejść do 2D. W 2D zamiast interpolować między dwoma punktami linii (``fract(x)`` i ``fract(x)+1. 0``), będziemy interpolować pomiędzy czterema narożnikami kwadratowego obszaru płaszczyzny (``fract(st)``, ``fract(st)+vec2(1.,0.)``, ``fract(st)+vec2(0.,1.)``` oraz ``fract(st)+vec2(1.,1.)``). +Teraz, gdy wiemy jak zrobić szum w 1D, czas przejść do 2D. W 2D zamiast interpolować między dwoma punktami linii (``rand(x)`` i ``rand(x)+1.0``), będziemy interpolować pomiędzy czterema narożnikami kwadratowego obszaru płaszczyzny (``rand(st)``, ``rand(st)+vec2(1.,0.)``, ``rand(st)+vec2(0.,1.)`` oraz ``rand(st)+vec2(1.,1.)``). ![](01.png) -Podobnie, jeśli chcemy uzyskać szum 3D musimy interpolować pomiędzy ośmioma rogami sześcianu. W tej technice chodzi o interpolację losowych wartości, dlatego nazywa się ją **szumem wartościowym**. +Podobnie, jeśli chcemy uzyskać szum 3D musimy interpolować pomiędzy ośmioma rogami sześcianu. W tej technice chodzi o interpolację losowych wartości ang. (ang. "random **value**s"), dlatego nazywa się ją **value noise**. ![](04.jpg) -Podobnie jak w przykładzie 1D, ta interpolacja nie jest liniowa, ale sześcienna, która płynnie interpoluje wszelkie punkty wewnątrz naszej kwadratowej siatki. +Podobnie jak w przykładzie 1D, interpolacja ta nie jest liniowa, ale sześcienna, więc płynnie interpoluje wszelkie punkty wewnątrz naszego kwadratowego obszaru. ![](05.jpg) -Przyjrzyj się następującej funkcji hałasu. +Przyjrzyj się następującej funkcji szumu.
-Zaczynamy od przeskalowania przestrzeni o 5 (linia 45), aby zobaczyć interpolację pomiędzy kwadratami siatki. Następnie wewnątrz funkcji szumu dzielimy przestrzeń na komórki. Przechowujemy całkowitą pozycję komórki wraz z pozycjami ułamkowymi wewnątrz komórki. Używamy pozycji całkowitej do obliczenia współrzędnych czterech narożników i otrzymujemy losową wartość dla każdego z nich (linie 23-26). Na koniec, w linii 35 interpolujemy pomiędzy 4 losowymi wartościami narożników używając pozycji frakcyjnych, które przechowywaliśmy wcześniej. +Zaczynamy od przeskalowania przestrzeni o 5 (linia 45). Następnie wewnątrz funkcji szumu dzielimy przestrzeń na kafellki. Przechowujemy pozycję kafelka jako cześć całkowitą oraz pozycje wewnątrz kafelka jako część ułamkową. Używamy części całkowitej do obliczenia współrzędnych czterech narożników, otrzymując losową wartość dla każdego z nich (linie 23-26). Na koniec, w linii 35 interpolujemy pomiędzy 4 losowymi wartościami narożników używając części ułamkowej. Teraz twoja kolej. Spróbuj wykonać następujące ćwiczenia: -* Zmień mnożnik linii 45. Spróbuj go animować. +* Zmień mnożnik w linii 45. Spróbuj go zanimować. -* Przy jakim poziomie powiększenia szum zaczyna znowu wyglądać jak losowy? +* Przy jakim poziomie powiększenia szum zaczyna znowu wyglądać kompletnie losowo (jak, wspomniany na początku rozdziału, biały szum)? * Przy jakim poziomie powiększenia szum jest niezauważalny? @@ -172,7 +170,7 @@ Teraz twoja kolej. Spróbuj wykonać następujące ćwiczenia: ![Mark Rothko - Three (1950)](rothko.jpg) -## Using Noise in Generative Designs +## Szum a design generatywny Algorytmy szumu zostały pierwotnie zaprojektowane w celu nadania naturalnego *je ne sais quoi* cyfrowym teksturom. Implementacje 1D i 2D, które widzieliśmy do tej pory, były interpolacjami pomiędzy losowymi *wartościami*, dlatego nazywane są **Value Noise**, ale istnieje więcej sposobów na uzyskanie szumu... @@ -180,7 +178,7 @@ Algorytmy szumu zostały pierwotnie zaprojektowane w celu nadania naturalnego *j [ ![Inigo Quilez - Value Noise](value-noise.png) ](../edit.php#11/2d-vnoise.frag) -Jak odkryłeś w poprzednich ćwiczeniach, szum wartości ma tendencję do wyglądania "blokowo". Aby zmniejszyć ten blokowy efekt, w 1985 roku [Ken Perlin](https://mrl.nyu.edu/~perlin/) opracował inną implementację algorytmu o nazwie **Gradient Noise**. Ken wymyślił jak interpolować losowe *gradienty* zamiast wartości. Gradienty te były wynikiem funkcji losowej 2D, która zwraca kierunki (reprezentowane przez ``vec2``) zamiast pojedynczych wartości (``float``). Kliknij na poniższy obrazek, aby zobaczyć kod i sposób jego działania. +Jak odkryłeś w poprzednich ćwiczeniach, value noise ma tendencję do wyglądania "blokowo". Aby zmniejszyć ten blokowy efekt, w 1985 roku [Ken Perlin](https://mrl.nyu.edu/~perlin/) opracował inną implementację algorytmu o nazwie **Gradient Noise**. Ken wymyślił jak interpolować losowe *gradienty* zamiast wartości. Gradienty te były wynikiem funkcji losowej 2D, która zwraca kierunki (reprezentowane przez ``vec2``) zamiast pojedynczych wartości (``float``). Kliknij na poniższy obrazek, aby zobaczyć kod i sposób jego działania. @@ -188,7 +186,7 @@ Jak odkryłeś w poprzednich ćwiczeniach, szum wartości ma tendencję do wygl Poświęć chwilę na przyjrzenie się tym dwóm przykładom autorstwa [Inigo Quilez](http://www.iquilezles.org/) i zwróć uwagę na różnice pomiędzy [value noise](https://www.shadertoy.com/view/lsf3WH) a [gradient noise](https://www.shadertoy.com/view/XdXGW8). -Podobnie jak malarz, który rozumie, jak działają pigmenty jego farb, im więcej wiemy o implementacjach szumu, tym lepiej będziemy mogli z nich korzystać. Na przykład, jeśli użyjemy dwuwymiarowej implementacji szumu do obrócenia przestrzeni, w której renderowane są linie proste, możemy uzyskać następujący efekt swirly, który wygląda jak drewno. Ponownie możesz kliknąć na obrazek, aby zobaczyć, jak wygląda kod. +Podobnie jak malarz, który rozumie, jak działają pigmenty jego farb, im więcej wiemy o implementacjach szumu, tym lepiej będziemy mogli z nich korzystać. Na przykład, jeśli użyjemy dwuwymiarowej implementacji szumu do obrócenia przestrzeni, w której renderowane są linie proste, możemy uzyskać następujący drewno-podobny efekt. Ponownie możesz kliknąć na obrazek, aby zobaczyć, jak wygląda kod. @@ -247,7 +245,7 @@ y = x*x*(3.0-2.0*x); //y = x*x*x*(x*(x*6.-15.)+10.); "> -Zauważ, jak zmieniają się końce krzywej. Więcej na ten temat możesz przeczytać w [słowach własnych Kena](http://mrl.nyu.edu/~perlin/paper445.pdf). +Zauważ, jak zmieniają się końce krzywej. Więcej na ten temat możesz usłyszeć [z ust Kena Perlina](http://mrl.nyu.edu/~perlin/paper445.pdf). @@ -259,8 +257,8 @@ Dla Kena Perlina sukces jego algorytmu nie był wystarczający. Uważał, że mo * Algorytm o mniejszej złożoności obliczeniowej i mniejszej liczbie mnożeń. * Szum, który skaluje się do wyższych wymiarów przy mniejszym koszcie obliczeniowym. * Szum bez artefaktów kierunkowych. -* Szum z dobrze zdefiniowanymi i ciągłymi gradientami, które mogą być obliczane dość tanio. -* Algorytm, który jest łatwy do zaimplementowania w sprzęcie. +* Szum z dobrze zdefiniowanymi i ciągłymi gradientami, o niskim koszcie obliczeniowym. +* Algorytm, który jest łatwy do zaimplementowania w hardware'rze. -Wiem, co myślisz... "Kim jest ten człowiek?" Tak, jego praca jest fantastyczna! Ale poważnie, w jaki sposób ulepszył algorytm? Cóż, widzieliśmy jak dla dwóch wymiarów interpolował 4 punkty (rogi kwadratu); możemy więc poprawnie zgadnąć, że dla [trzech (zobacz implementację tutaj)](../edit.php#11/3d-noise.frag) i czterech wymiarów musimy interpolować 8 i 16 punktów. Prawda? Innymi słowy dla N wymiarów musisz płynnie interpolować 2 do N punktów (2^N). Ale Ken sprytnie zauważył, że chociaż oczywistym wyborem dla kształtu wypełniającego przestrzeń jest kwadrat, najprostszym kształtem w 2D jest trójkąt równoboczny. Zaczął więc od zastąpienia siatki kwadratowej (właśnie nauczyliśmy się jej używać) siatką simplex trójkątów równobocznych. +Wiem, co myślisz... "Kim jest ten człowiek?" Tak, jego praca jest fantastyczna! Ale poważnie, w jaki sposób ulepszył ten algorytm? Cóż, widzieliśmy jak dla dwóch wymiarów interpolował 4 punkty (rogi kwadratu); możemy więc poprawnie zgadnąć, że dla [trzech (zobacz implementację tutaj)](../edit.php#11/3d-noise.frag) i czterech wymiarów musimy interpolować 8 i 16 punktów. Prawda? Innymi słowy dla N wymiarów musisz płynnie interpolować 2 do N punktów (2^N). Ale Ken sprytnie zauważył, że chociaż oczywistym wyborem dla kształtu wypełniającego przestrzeń jest kwadrat, najprostszym kształtem w 2D jest trójkąt równoboczny. Zaczął więc od zastąpienia siatki kwadratowej (niedawno nauczyliśmy się jej używać) siatką trójkątów równobocznych (inaczej zwaną *siatką sympleksową*). ![](simplex-grid-00.png) -Kształt simplex dla N wymiarów to kształt z N + 1 narożami. Innymi słowy jeden mniejszy narożnik do obliczenia w 2D, 4 mniej narożniki w 3D i 11 mniej narożników w 4D! To ogromna poprawa! +Kształt dla N wymiarów to kształt z N + 1 wierzchołkami. Innymi słowy jeden wierzchołek mniej do obliczenia w 2D, 4 wierzchołki mniej w 3D i 11 wierzchołków mniej w 4D! To ogromna poprawa! -W dwóch wymiarach interpolacja odbywa się podobnie do zwykłego szumu, poprzez interpolację wartości narożników odcinka. Ale w tym przypadku, dzięki zastosowaniu siatki simplex, musimy tylko interpolować sumę 3 narożników. +W dwóch wymiarach interpolacja odbywa się podobnie do zwykłego szumu, poprzez interpolację wartości wierzchołków odcinka. Ale w tym przypadku, dzięki zastosowaniu siatki sympleksowej, musimy tylko interpolować sumę 3 wierzchołków. @@ -296,23 +294,24 @@ Jak powstaje siatka simplex? W kolejnym błyskotliwym i eleganckim posunięciu, In the following code you can uncomment line 44 to see how the grid is skewed, and then uncomment line 47 to see how a simplex grid can be constructed. Note how on line 22 we are subdividing the skewed square into two equilateral triangles just by detecting if ```x > y``` ("lower" triangle) or ```y > x``` ("upper" triangle). --> -Wtedy, jak opisuje [Stefan Gustavson w tej pracy](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): _"...patrząc na części całkowite przekształconych współrzędnych (x,y) dla punktu, który chcemy ocenić, możemy szybko określić, która komórka dwóch prostopadłościanów zawiera ten punkt. Porównując również wielkości x i y, możemy określić, czy punkt znajduje się w górnej czy dolnej prostej i przemierzyć właściwe trzy punkty narożne."_. -W poniższym kodzie możesz odkomentować linię 44, aby zobaczyć jak siatka jest przekrzywiona, a następnie odkomentować linię 47, aby zobaczyć jak można skonstruować siatkę simpleksową. Zauważ jak w linii 22 dzielimy przekrzywiony kwadrat na dwa trójkąty równoboczne tylko poprzez wykrycie czy ``x > y`` (dolny" trójkąt) lub ``y > x`` (górny" trójkąt). + + +W poniższym kodzie możesz odkomentować linię 44, aby zobaczyć jak siatka jest przekrzywiona, a następnie odkomentować linię 47, aby zobaczyć siatkę simpleksową. Zauważ jak w linii 22 dzielimy przekrzywiony kwadrat na dwa trójkąty równoboczne poprzez wykrycie czy ``x > y`` (dolny" trójkąt) lub ``y > x`` (górny" trójkąt).
-Wszystkie te ulepszenia skutkują algorytmicznym arcydziełem znanym jako **Simplex Noise**. Poniżej znajduje się implementacja GLSL tego algorytmu wykonana przez Iana McEwana i Stefana Gustavsona (i przedstawiona w [tym artykule](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)), która jest nadmiernie skomplikowana w celach edukacyjnych, ale z przyjemnością klikniesz na nią i przekonasz się, że jest mniej krypto niż można by się spodziewać, a kod jest krótki i szybki. +Wszystkie te ulepszenia skutkują algorytmicznym arcydziełem, jakim jest **Simplex Noise**. Poniżej znajduje się implementacja GLSL tego algorytmu wykonana przez Iana McEwana i Stefana Gustavsona (i przedstawiona w [tym artykule](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)), która jest nadmiernie skomplikowana w celach edukacyjnych, ale przekonasz się, że jest mniej enigmatyczna niż można by się spodziewać, a kod jest krótki i szybki. [ ![Ian McEwan of Ashima Arts - Simplex Noise](simplex-noise.png) ](../edit.php#11/2d-snoise-clear.frag) -Cóż... dość technicznych rozważań, czas na wykorzystanie tego zasobu we własny, ekspresyjny sposób: +Cóż... dość technicznych rozważań, czas na wykorzystanie tego narzędzia we własny, ekspresyjny sposób: -* Kontempluj, jak wygląda każda implementacja szumu. Wyobraź sobie je jako surowy materiał, jak marmurowy kamień dla rzeźbiarza. Co możesz powiedzieć o "uczuciu", jakie ma każda z nich? Zmruż oczy, aby uruchomić wyobraźnię, tak jak wtedy, gdy chcesz znaleźć kształty w chmurze. Co widzisz? Co ci się przypomina? W co wyobrażasz sobie, że każda realizacja hałasu mogłaby zostać wykonana? Podążając za swoimi wnętrznościami i spróbuj zrealizować to w kodzie. +* Kontempluj, jak wygląda każda implementacja szumu. Wyobraź sobie je jako surowy materiał, jak marmurowy kamień dla rzeźbiarza. Co możesz powiedzieć o "uczuciu", jakie ma każda z nich? Zmruż oczy, aby uruchomić wyobraźnię, tak jak wtedy, gdy chcesz znaleźć kształty w chmurze. Co widzisz? Co ci się przypomina? W co każda implementacja szumu mogłaby zostać przeobrażana? Podążając za swoją intuicją, spróbuj zrealizować to w kodzie. -* Zrób shader, który rzutuje iluzję przepływu. Jak lampa lawowa, krople atramentu, woda itp. +* Zrób shader, który tworzy iluzję przepływu. Jak lampa lawowa, krople atramentu, woda itp.