From 10b35823b5240d5f5516ccc0fd07bfe11a418e81 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Tue, 17 Jan 2023 16:35:27 +0100 Subject: [PATCH] 06 --- 06/README-pl.md | 219 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 06/README-pl.md diff --git a/06/README-pl.md b/06/README-pl.md new file mode 100644 index 0000000..95bd046 --- /dev/null +++ b/06/README-pl.md @@ -0,0 +1,219 @@ +![Paul Klee - Color Chart (1931)](klee.jpg) + +## Kolory + + +Nie mieliśmy zbytnio okazji porozmawiać o typach wektorowych w GLSL. +Zanim przejdziemy dalej, ważne jest żebyśmy dowiedzieli się o nich więcej, a temat kolorów może być w tym bardzo pomocny. + + + +Jeżeli paradgymat programowania obiektowego jest ci bliski, to prawdopodobnie zauważyłeś, że proces wyciągania danych z wektorów wygląda podobnie przy C-podobnych `struct`'ach. + + + +```glsl +vec3 red = vec3(1.0,0.0,0.0); +red.x = 1.0; +red.y = 0.0; +red.z = 0.0; +``` + +Definiowanie kolor za pomocą notacji *x*, *y* i *z* jest trochę mylące, prawda? Właśnie dlatego istnieją inne sposoby dostępu do tej samej informacji, ale za pomocą różncyh nazw. Wartości `.x`, `.y` i `.z` mogą być również uzyskane za pomocą `.r`, `.g` i `.b`, jak i `.s`, `.t` i `.p` (`.s`, `.t` i `.p` są zwykle używane przy współrzędnych tekstur, które zobaczymy w następnych rozdziałach). Możesz również uzyskać dane wektora za pomocą indeksów `[0]`, `[1]` i `[2]`. + + + +Następujący kod przedstawia wszystkkie sposoby uzysakania tych samych danych: + + + +```glsl +vec4 vector; +vector[0] = vector.r = vector.x = vector.s; +vector[1] = vector.g = vector.y = vector.t; +vector[2] = vector.b = vector.z = vector.p; +vector[3] = vector.a = vector.w = vector.q; +``` + +Ta mnogość metod uzyskiwania tych samych danych jest tylko po to, aby ułatwić pisanie zrozumiałego kodu. Ta elastyczność wbudowana w język shadingowy stanowi też okazję, żebyś zaczął myśleć o współrzędnych koloru i przestrzeni jako zamiennych. + + + +Inną świetną własnością typów wektorowych w GLSL jest to, że współrzędne mogą być mieszane w dowolnej kolejności, co ułatwia castowanie i mieszanie wartości. Właśność ta nazywana jest *swizzle*'owaniem. + + + +```glsl +vec3 yellow, magenta, green; + +// Tworzenie żółtego +yellow.rg = vec2(1.0); // Przypisanie 1. do kanału czerwonego i zielonego +yellow[2] = 0.0; // Przypisanie 0. do kanału niebieskiego + +// Tworzenie magenty +magenta = yellow.rbg; // Przypisanie wektora z przestawionym kanałem zielonym i niebieskim + +// Tworzenie zielonego +green.rgb = yellow.bgb; // Przypisanie kanału niebieskiego do kanału czerwonego i niebieskiego +``` + + +### Mieszanie koloru + +Teraz, gdy już wiesz jak definiuje się kolory, pora na połączenie tego z naszą wcześniejszą wiedzą. W GLSL istnieje bardzo przydatna funkcja [`mix()`](../glossary/?search=mix), która pozwala mieszać dwie wartości wobec określonego stosunku wyrażonego w procentach. Potrafisz zgadnąć jaki jest zakres procentów? Oczywiście, że 0.0 i 1.0! Czas na wykorzystanie naszego shadingowego karate! + + + +![](mix-f.jpg) + +Sprawdź linijkę 18 poniższego kodu i zoabcz jak używamy wartości bezwględnej z sinusa od czasu, aby mieszać `colorA` i `colorB`. + + + +
+ +Pokaż na co cie stać: + + + +* Stwórz ekspresywną tranzycje między kolorami. Pomyśl o konkretnej emocji. Jaki kolor najlepiej ją reprezentuje? Jak wygląda? Jak zanika? Pomyśl o innej emocji i pasującym do niej kolorze. Zmień `colorA` i `colorB` w kodzie powyżej, aby pasowały do tych emocji. Następnie zanimuj tę tranzycję za pomocą funkcji kształtujących. Robert Penner stworzył serię popularnych funkcji kształtujących, z zasotoswaniami w animacji komputerowej, zwanych [easing functions](http://easings.net/), skorzystaj z [tego przykładu](../edit.php#06/easing.frag) jako inspiracji, ale najlepsze rezultaty osiągniesz tworząc własne tranzycje. + + + +### Zabawa z gradientem + +Funkcja [`mix()`](../glossary/?search=mix) ma więcej do zaoferowania. Zamiast pojedynczego `float`a, możemy podać zmienną tego samego typu, co dwa pierwsze argumenty; w naszym wypadku jest to `vec3`. W ten sposób zdobywamy kontrolę nad stosunkiem mieszania każdego indywidualnego kanału koloru, `r`, `g` i `b`. + + + +![](mix-vec.jpg) + +Spójrz na poniższy przykład. Tak jak w przykładach z poprzedniego rozdziału, podłączamy tranzycję do znormalizowanej współrzędnej `x` i wizualizujemy za pomocą linii. Aktualnie, wszystkie kanały leżą na tej samej linii. + + +Odkomentuj linjkę 25 i zobacz, co się stanie. Następnie odkomentuj linijki 26 i 27. Pamiętaj, że linie wizualizują stosunek mieszania każdego z kanałów wektorów `colorA` i `colorB`. + + + +
+ +Prawdopodobnie rozpoznajesz trzy funkcje kształtującego, które używamy w linijkach 25 i 27. Baw się nimi! Czas pokazać swoje umiejętności z poprzednich rozdziałów, tworząc interesujące gradienty. Spróbuj następujących ćwiczeń: + +![William Turner - The Fighting Temeraire (1838)](turner.jpg) + +* Skomponuj gradient przypominający zachód słońca Williama Turnera. + +* Zanimuj tranzycje między wschodem i zachodem za pomocą `u_time`. + +* Czy potrafisz stworzyć tęczę korzystając z tego, czego nauczyliśmy się dotychaczas? + +* Użyj `step()`, by stworzyć kolorową flagę. + + + +### HSB + +Nie da się mówić o kolorze bez poruszenia tematu przestrzeni barw. Jak prawdopodobnie wiesz, istnieją też inne sposoby reprezentacji koloru poza RGB (z kanałem czerwonym, zielonym i niebieskim). + +[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) oznacza Hue (pol. "barwa"), Saturation (pol. "nasycenie") i Brightness (pol. "jasność) i jest o wiele bardziej intuicyjną reprezentacją koloru niż RGB. Czasem zamiast Brightness używa sie Value, stąd zamiast HSB można spotkać się też z HSV. Przyjrzyj się funkcjom `rgb2hsv()` i `hsv2rgb()` w następującym kodzie: + + + + + +Mapując pozycję na osi x do barwy i pozycję na osi y do jasności, otrzymujemy spektrum widzialnych kolorów. O wiele bardziej intuicyjnie wybiera się kolor HSB niż RGB. + + + +
+ +### HSB we współrzędnych biegunowych + +Oryginalnie, HSB miało być reprezentowane z pomocą współrzędnych biegunowych (opartych na kącie i promieniu), a nie kartezjańskich (opartych na x i y). By zpamować naszą funkcję HSB do współrzędnych biegunowych, musimy otrzymać kąt i dystans wektora od centrum kanwy do współrzędnej piksela. W tym celu użyjemy funkcje [`length()`](../glossary/?search=length) i [`atan(y,x)`](../glossary/?search=atan) (który jest odpowiednikami `atan2(y,x)` w GLSL). + + + + + + + +**Uwaga:** Jest weięcej funkcji geometrycznych poza [`length`](../glossary/?search=length) jak: [`distance()`](../glossary/?search=distance), [`dot()`](../glossary/?search=dot), [`cross`](../glossary/?search=cross), [`normalize()`](../glossary/?search=normalize), [`faceforward()`](../glossary/?search=faceforward), [`reflect()`](../glossary/?search=reflect) i [`refract()`](../glossary/?search=refract). Ponadto, GLSL ma specjalne funkcje do porównywania wektorów: [`lessThan()`](../glossary/?search=lessThan), [`lessThanEqual()`](../glossary/?search=lessThanEqual), [`greaterThan()`](../glossary/?search=greaterThan), [`greaterThanEqual()`](../glossary/?search=greaterThanEqual), [`equal()`](../glossary/?search=equal) i [`notEqual()`](../glossary/?search=notEqual). + + + +Gdy już zdobędziemy kąt i promień, musimy znormalizować ich wartości do zakresu od 0.0 do 1.0. W linijce 27, [`atan(y,x)`](../glossary/?search=atan) zwróci kąt w radianach między -PI a PI (-3.14 a 3.14), więc musimy podzielić tę liczbę przez `TWO_PI` (zdefiniowane na górze kodu), uzyskując wartości między -0.5 i 0.5, które, przez proste dodawanie, mapujemy dalej do zakresu od 0.0 do 1.0. Promień ma długość 0.5 (ponieważ liczymy odległość od środka TODO kanwy), więc musimy podwoić ten zakres (mnożąc przez 2), by uzyskać 1.0. + + + +Jak widzisz, sedno leży w transformowaniu i mapowaniu zakresów do 0.0 i 1.0. + + + +
+ +Spróuj poniższych ćwiczeń: + + + +* Zmodyfikuj przykład ze współrzędnymi biegunowymi, aby uzyskać kręcące się (jak w ikonce czekania myszki) koło barw. + +* Użyj funkcji kształtującej razem z funkcją konwersji z HSB do RGB, aby rozszerzyć jedną barwę i zwężyć inną. + + + + +![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg) + +* Jeśli przyjrzysz się uważnie kołom barw używanym w narzędziach do wybierania koloru (ang "color picker") (spójrz na obrazek poniżej), zobaczysz, że używają innego sepktrum koloru, zgodnego z przestrzenią barw RYB. Przykładowo, kolorem przeciwnym do czerwonego powienien być zielony, ale w naszym przykładzie jest cyjan. Czy potrafiłbyś zrekonstruować poniższy obrazek? [Wskazówka: to dobry moment, by użyć funkcji kształtujących] + + + +![](colorwheel.png) + +* Przeczytaj [książkę Josefa Albersa _Interaction of Color_](http://www.goodreads.com/book/show/111113.Interaction_of_Color) i przestudiuj poniższe przykłady shaderów. + + + +
+ +#### Uwaga o funkcjach i ich argumentach + +Zanim przeskoczysz do następnego rozdziału, zatrzymajmy się na chwilę. Wróć do funkcji `hsb2rgb` z poprzedniego interaktywnego przykładu. Zauważysz `in` przed typem argumentu. Jest to [*kwalifikator*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) (ang. "qualifier") i akurat ten oznacza, że zmienna jest tylko do odczytu. W przyszłości zobaczymy, że jest również możliwe, by poprzedzić argumenty kwalifikatorami `out` i `inout`. `out` określa, że argument jest tylko do zapisu, natomiast `inout` działa podobnie jak przekazywanie argumentu przez referencje, co umożliwia modyfikowanie go. + + + +```glsl +int newFunction(in vec4 aVec4, // read-only + out vec3 aVec3, // write-only + inout int aInt); // read-write +``` + +Może w to nie uwierzysz, ale mamy wszystkie składniki potrzbne do tworzenia fajnych rysunków. W następnym rozdziale nauczymy się jak połączyć wszystkie poznane tricki, by stworzyć geometryczne formy przez *blendowanie* przestrzeni. Dobrze słyszysz... *blendowanie* przestrzeni. + +You may not believe it but now we have all the elements to make cool drawings. In the next chapter we will learn how to combine all our tricks to make geometric forms by *blending* the space. Yep... *blending* the space.