pull/389/head
Wojtek Pachowiak 1 year ago
parent 8a24def06f
commit 7e6a6c233a

@ -0,0 +1,74 @@
## Hello World
Zazwyczaj przykład "Hello world!" stanowi pierwszy krok przy nauce nowego języka. Jest to prosty jednolinijkowy programy, który zwraca pełną entuzjazmu wiadomość powitalną i tym samym zapowiada nadchodzące przygody.
Usually the "Hello world!" example is the first step to learning a new language. It's a simple one-line program that outputs an enthusiastic welcoming message and declares opportunities ahead.
W świecie GPU renderowanie tekstu jest jednak zbyt skomplikowanym zadaniem dla żółtodzioba. Zamiast tego wybierzemy jasny, serdeczny kolor by wykrzyczeć naszą ekscytację!
In GPU-land rendering text is an overcomplicated task for a first step, instead we'll choose a bright welcoming color to shout our enthusiasm!
<div class="codeAndCanvas" data="hello_world.frag"></div>
Jeżeli czytasz tę książkę w przeglądarce: powyższy blok kodu jest interaktywny. Oznacza to, że możesz edytować dowolną linijkę kodu w celach eksploracyjnych. Shader kompiluje się na bieżąco, więc zmiany widoczne będą natychmiast. Spróbuj pozmieniać wartości w linijce 8.
If you are reading this book in a browser the previous block of code is interactive. That means you can click and change any part of the code you want to explore. Changes will be updated immediately thanks to the GPU architecture that compiles and replaces shaders *on the fly*. Give it a try by changing the values on line 8.
Choć kod jest prosty, to możemy wyciągnąć z niego ważne wnioski:
1. Podobnie jak w C, język shadingowy ma jedną funkcje `main`. Pod koniec zwraca ona kolor.
2. Finalny kolor piksela przypisywany jest do zarezerowanej zmiennej globalnej `gl_FragColor`.
3. Ten C-podobny język ma wbudowane *zmienne* (jak `gl_FragColor`), *funkcje* i *typy*. W aktualnym przykładzie występuje jedynie typ `vec4`, oznaczający czterowymiarowy wektor zmiennoprzecinkowy ("float vector"). Później zobaczymy również takie typy jak `vec3`, `vec2` oraz znajome `float`, `int` i `bool`.
4. Patrząc na typ `vec4`, możemy wywnioskować, że jego cztery argumenty odnoszą się do kanałów CZERWONEGO, ZIELONEGO, NIEBIESKIEGO i ALPHA. Widać też, że jego wartości są *znormalizowane*, więc znajdują się w zakresie od `0.0` do `1.0`. Później zobaczymy, jak normalizowanie wartości pomaga w *mapowaniu* wartości między zakresami.
5. Kolejnym ważną C-podobną własnością w tym przykładzie jest obecność makr preprocessora. Dzięki nim można definiować zmienne globalne za pomocą `#define` oraz operacje warunkowe za pomocą `#ifdef` ("if defined"), `#ifndef` ("if not defined") i `#endif`. Wszystkie makra zaczynają się od płotka `#` kompilacją wszystkie ... W naszym powyższym przykładzie linijka 2 kompilowana jest tylko wtedy, gdy zmienna `GL_ES` jest zdefiniowana (jest na urządzeniach mobilnych i w przeglądarkach).
Although these simple lines of code don't look like a lot, we can infer substantial knowledge from them:
1. Shader Language has a single `main` function that returns a color at the end. This is similar to C.
2. The final pixel color is assigned to the reserved global variable `gl_FragColor`.
3. This C-flavored language has built in *variables* (like `gl_FragColor`), *functions* and *types*. In this case we've just been introduced to `vec4` that stands for a four dimensional vector of floating point precision. Later we will see more types like `vec3` and `vec2` together with the popular: `float`, `int` and `bool`.
4. If we look closely to the `vec4` type we can infer that the four arguments respond to the RED, GREEN, BLUE and ALPHA channels. Also we can see that these values are *normalized*, which means they go from `0.0` to `1.0`. Later, we will learn how normalizing values makes it easier to *map* values between variables.
5. Another important *C feature* we can see in this example is the presence of preprocessor macros. Macros are part of a pre-compilation step. With them it is possible to `#define` global variables and do some basic conditional operation (with `#ifdef` and `#endif`). All the macro commands begin with a hashtag (`#`). Pre-compilation happens right before compiling and copies all the calls to `#defines` and check `#ifdef` (is defined) and `#ifndef` (is not defined) conditionals. In our "hello world!" example above, we only insert the line 2 if `GL_ES` is defined, which mostly happens when the code is compiled on mobile devices and browsers.
6. Typy zmiennoprzecinkowe są kluczowe w shaderach, więc ich poziom precyzji (ang. *precision*) jest kluczowy. Niższa precyzja oznacza szybsze renderowanie, ale kosztem jakości. Możesz być wybredny i określać precyzję każdej zmiennej zmiennoprzecinkowej z osobna. W linijce 2 (`precision mediump float;`) ustawiamy średnią precyzję zmiennych zmiennoprzecinkowych ("mediump", bo "medium precision"). Możemy też ustawić ją jako niską (`precision lowp float;`) lub wysoką (`precision highp float;`).
7. Ostatni i chyba najważniejszy szczegół specyfikacji GLSL: nie ma gwaracji, że zmienne będą automatycznie castowane (np. z `int` do `float` przy dzieleniu liczby 5 przez 2). Producenci GPU mogą stosować przeróżne optymalizacje w kartach graficzncyh, ale muszą przy tym przestrzegać pewnych wytycznych. Automatyczne castowanie nie jest jednym z nich. W naszym przykładzie `vec4` ma precyzję zmiennoprzecinkową i dlatego jego argumenty wymagają `float`ów. Przezwyczaj się do stawiania kropek (`.`) we `float`ach (`1.` lub `1.0`, a nie `1`), jeżeli nie chcesz spędzić godzin przy debugowaniu. Poniższy kod nie zawsze będzie działa:
```glsl
void main() {
gl_FragColor = vec4(1,0,0,1); // ERROR
}
```
Czas
* Spróbuj zamienić `float`y na `int`y. Jeśli kod się nie kompiluje, to twoja karta graficzna nie toleruje
* Zakomentuj linię 8
* Stwórz osobną funckję, która zwraca dowolny kolor i użyj jej w `main()`. Wskazówka: poniższy kod zwraca kolor czerwony:
```glsl
vec4 red(){
return vec4(1.0,0.0,0.0,1.0);
}
```
* Jest wiele sposobów tworzenia typu `vec4` - spróbuj je znaleźć. Jeden z nich wygląda tak:
```glsl
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
Choć przykład ten nie jest zbyt ekscytujący
W następnych rozdziałach zobaczymy, jak zmienić kolor piksela z pomocą inputu przestrzennego (położenie piksela na ekranie) i temporalnego (okres czasu od momentu załadowania się strony)

@ -0,0 +1,98 @@
## Uniformy
Do tej pory widzieliśmy jak GPU zarządza wieloma równoległymi wątkami, z który każdy odpowiada za kolor części renderowanego obrazu. Choć wątki nie komunikują się między sobą, to jednak muszą jakoś otrzymywać input z CPU. Ze względu na architekturę karty graficznej taki input musi być jednakowy (ang. *uniform*) dla wszystkich wątków i, z konieczności, tylko do odczytu. Innymi słowy, każdy wątek otrzymuje takie same dane, które może odczytać, ale nie nadpisać, zmienić.
~~So far we have seen how the GPU manages large numbers of parallel threads, each one responsible for assigning the color to a fraction of the total image. Although each parallel thread is blind to the others, we need to be able to send some inputs from the CPU to all the threads. Because of the architecture of the graphics card those inputs are going to be equal (*uniform*) to all the threads and necessarily set as *read only*. In other words, each thread receives the same data which it can read but cannot change.~~
Inputy te nazywamy `uniform`ami i mogę być większości wspieranych typów: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `sampler2D` i `samplerCube`. Uniformy definiowane są zwykle na górze shaderu zaraz po przypisaniu domyślnej precyzji floatów.
~~These inputs are called `uniform` and come in most of the supported types: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `sampler2D` and `samplerCube`. Uniforms are defined with the corresponding type at the top of the shader right after assigning the default floating point precision.~~
```glsl
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution; // wielkość/rozdzielczość kanwy (szerokość, wysokość)
uniform vec2 u_mouse; // pozycja myszy na kanwie (wyrażona w pikselach)
uniform float u_time; // czas w sekundach od załadowania shadera
```
Wyobraź sobie te uniformy jak małe mosty między CPU i GPU. Ich nazwy bywają różne, ale w tej książce używam: `u_time`, `u_resolution` i `u_mouse` (przeczytaj komentarze w kodzie, aby wiedzieć, co robią). Podążam za konwencją dodawnaia `u_` przed nazwą uniformów, aby było wiadomo, że nie są to zwykłe zmienne, ale ostatecznie jest to kwestia gustu. Przykładowo, [ShaderToy.com](https://www.shadertoy.com/) używa takich samych uniformów, ale z następującym nazewnictwem:
~~You can picture the uniforms like little bridges between the CPU and the GPU. The names will vary from implementation to implementation but in this series of examples Im always passing: `u_time` (time in seconds since the shader started), `u_resolution` (billboard size where the shader is being drawn) and `u_mouse` (mouse position inside the billboard in pixels). Im following the convention of putting `u_` before the uniform name to be explicit about the nature of this variable but you will find all kinds of names for uniforms. For example [ShaderToy.com](https://www.shadertoy.com/) uses the same uniforms but with the following names:~~
```glsl
uniform vec3 iResolution;
uniform vec4 iMouse;
uniform float iTime;
```
(zwróć uwagę, że `iResolution` jest typu `vec3`, a `iMouse` typu `vec4`; uniformy te zawierają po prostu dodatkowe informacje, np.: stosunek szerokości do wysokości pikseli na ekranie, czy któryś z przycisków myszy został kliknięty albo czy jest przytrzymywany)
Koniec gadania, czas zobaczyć uniformy w akcji. W pożniszym kodzie używamy `u_time` (liczby sekund od uruchomienia shadera) razem z funkcją sinus, aby stworzyć animację przejścia od koloru czerwonego do czarnego.
<!-- Enough talking, let's see the uniforms in action. In the following code we use `u_time` - the number of seconds since the shader started running - together with a sine function to animate the transition of the amount of red in the billboard. -->
<div class="codeAndCanvas" data="time.frag"></div>
Jak widać GLSL skrywa wiele niespodzianek, na przykład w postaci specjalnych, zaimplementowanych w hardware'rze, funkcji trygonometryczne czy wykładniczych. Tutaj podaję część z nich: [`sin()`](../glossary/?search=sin), [`cos()`](../glossary/?search=cos), [`tan()`](../glossary/?search=tan), [`asin()`](../glossary/?search=asin), [`acos()`](../glossary/?search=acos), [`atan()`](../glossary/?search=atan), [`pow()`](../glossary/?search=pow), [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log), [`sqrt()`](../glossary/?search=sqrt), [`abs()`](../glossary/?search=abs), [`sign()`](../glossary/?search=sign), [`floor()`](../glossary/?search=floor), [`ceil()`](../glossary/?search=ceil), [`fract()`](../glossary/?search=fract), [`mod()`](../glossary/?search=mod), [`min()`](../glossary/?search=min), [`max()`](../glossary/?search=max) i [`clamp()`](../glossary/?search=clamp).
<!--
As you can see GLSL has more surprises. The GPU has hardware accelerated angle, trigonometric and exponential functions. Some of those functions are: [`sin()`](../glossary/?search=sin), [`cos()`](../glossary/?search=cos), [`tan()`](../glossary/?search=tan), [`asin()`](../glossary/?search=asin), [`acos()`](../glossary/?search=acos), [`atan()`](../glossary/?search=atan), [`pow()`](../glossary/?search=pow), [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log), [`sqrt()`](../glossary/?search=sqrt), [`abs()`](../glossary/?search=abs), [`sign()`](../glossary/?search=sign), [`floor()`](../glossary/?search=floor), [`ceil()`](../glossary/?search=ceil), [`fract()`](../glossary/?search=fract), [`mod()`](../glossary/?search=mod), [`min()`](../glossary/?search=min), [`max()`](../glossary/?search=max) and [`clamp()`](../glossary/?search=clamp). -->
Pobawmy się powyższym kodem:
* Zmniejsz częstotliwość tak bardzo, aby zmiany koloru stały się nie zauważalne.
* Zwiększ częstotliwość do takiego stopnia, aby ujrzeć stały kolor bez migotania.
* Wstaw funkcje sinus o różnych częstotliowściach do pozostałych kanałów (zielonego i niebieskiego), aby uzyskać ciekawe efekty.
<!-- Now it is time again to play with the above code.
* Slow down the frequency until the color change becomes almost imperceptible.
* Speed it up until you see a single color without flickering.
* Play with the three channels (RGB) in different frequencies to get interesting patterns and behaviors. -->
## gl_FragCoord
GLSL daje nam nie tylko domyślny output `vec4 gl_FragColor`, ale również domyślny input w postaci `vec4 gl_FragCoord`, który przechowuje współrzędne *piksela* (inaczej: *fragmentu*), nad którym aktualnie pracuje wątek - dzięki `vec4 gl_FragCoord` wiemy, gdzie wątek pracuje wewnątrz kanwy. Nie nazywamy go `uniform`em, ponieważ jego wartość różni się między wątkami. Zamiast tego `gl_FragCoord` nazywamy *varying* (z ang. "zmieniający się", "różniący się").
<!-- In the same way GLSL gives us a default output, `vec4 gl_FragColor`, it also gives us a default input, `vec4 gl_FragCoord`, which holds the screen coordinates of the *pixel* or *screen fragment* that the active thread is working on. With `vec4 gl_FragCoord`, we know where a thread is working inside the billboard. In this case we don't call it `uniform` because it will be different from thread to thread, instead `gl_FragCoord` is called a *varying*. -->
<div class="codeAndCanvas" data="space.frag"></div>
W powyższy kodzie, *normalizujemy* współrzędne fragmentu poprzez podzielenie go przez rozdzielczość kanwy. W ten sposó otrzymujemy wartości z przedziału od `0.0` do `1.0`, co ułatwia zmapowanie współrzędnych x i y do, odpowiednio, czerwonego i zielonego kanału.
<!-- In the above code we *normalize* the coordinate of the fragment by dividing it by the total resolution of the billboard. By doing this the values will go between `0.0` and `1.0`, which makes it easy to map the X and Y values to the RED and GREEN channel. -->
W świecie shaderów nie mamy zbyt dużo sposóbów debuggowania poza przypisywaniem jaskrawych kolorów do zmiennych i wyciągania wniosków o działaniu shadera, na podstawie tego, co widzimy. Odkryjesz, że programowania GLSL jest często jak wkładanie miniaturowych statków do butelki - jest to trudne, ale tez piękne i satysfakcjonujące.
<!-- In shader-land we dont have too many resources for debugging besides assigning strong colors to variables and trying to make sense of them. You will discover that sometimes coding in GLSL is very similar to putting ships inside bottles. Is equally hard, beautiful and gratifying. -->
![](08.png)
Czas przetestować nasze rozumienie kodu:
* Czy jesteś w stanie powiedzieć, gdzie na naszej kanwie znajduje się fragment o znormalizowanych współrzędnych `(0.0, 0.0)`?
* Co z framgentami o znormalizowanych współrzędnych `(1.0, 0.0)`, `(0.0, 1.0)`, `(0.5, 0.5)` i `(1.0, 1.0)`?
* Czy jesteś w stanie użyć uniforma `u_mouse` wiedząc, że wartości są nieznormalizowane? Spróbuj użyć go do manipulacji kolorem za pomocą ruchów myszki.
* Czy jesteś sobie w stanie wyobrazić ciekawy sposób zmieniania koloru, łącząc współrzędne `u_mouse` z `u_time`?
Po wykonaniu tych ćwiczeń, zapewne zastanawiasz się, gdzie jeszcze można użyć twoich nowych shaderowych mocy. W następnym rozdziale zobaczymy jak stworzyć swój własny shader w three.js, Processing i openFrameworks.
<!-- Now it is time to try and challenge our understanding of this code.
* Can you tell where the coordinate `(0.0, 0.0)` is in our canvas?
* What about `(1.0, 0.0)`, `(0.0, 1.0)`, `(0.5, 0.5)` and `(1.0, 1.0)`?
* Can you figure out how to use `u_mouse` knowing that the values are in pixels and NOT normalized values? Can you use it to move colors around?
* Can you imagine an interesting way of changing this color pattern using `u_time` and `u_mouse` coordinates?
After doing these exercises you might wonder where else you can try your new shader-powers. In the following chapter we will see how to make your own shader tools in three.js, Processing, and openFrameworks. -->

@ -0,0 +1,276 @@
<!-- ## Running your shader -->
## Korzystanie z shaderów
W ramach prac nad tą książką stworzyłem ekosystem narzędzi do tworzenia, wyświetlania, udostępniania i organizowania shaderów. Narzędzia te działają, bez konieczności dostosowywania kodu, na systemach Linux, MacOS, Windows i [Raspberry Pi](https://www.raspberrypi.org/) oraz w przeglądarce.
<!-- As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. These tools work consistently across Linux, MacOS, Windows and [Raspberry Pi](https://www.raspberrypi.org/) and browsers without the need of changing your code. -->
<!-- ## Running your shaders on the browser -->
## Korzystanie z shaderów w przeglądarce
**Wyświetlaj**: wszystkie interaktywne przykłady w tej książce wyświetlane są dzięki [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas), który znacząco ułatwia proces korzystania z shaderów.
<!-- **Display**: all live examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredibly easy. -->
```html
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
```
Jak widać, `glslCanvas` wymaga jedynie elementu `canvas` z `class="glslCanvas"` oraz URL do twojego shadera w `data-fragment-url`. Aby dowiedzieć się więcej, kliknij [tutaj](https://github.com/patriciogonzalezvivo/glslCanvas).
<!-- As you can see, it just needs a `canvas` element with `class="glslCanvas"` and the url to your shader in the `data-fragment-url`. Learn more about it [here](https://github.com/patriciogonzalezvivo/glslCanvas). -->
Jeśli podobnie jak ja chciałbyś móć korzysatć z shaderów w konsoli, to [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) powinien cie zainteresować. Aplikacja ta pozwala zintegrować shadery z `bash`owymi skryptami i Unixowymi pipeline'ami, podobnie jak [ImageMagick](http://www.imagemagick.org/script/index.php). Ponadto, [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) pozwala ci kompilować shadery na [Raspberry Pi](https://www.raspberrypi.org/) - właśnie dlatego [openFrame.io](http://openframe.io/) używa go do wyświetalania swoich shaderowych dział sztuki. Kliknij [tutaj](https://github.com/patriciogonzalezvivo/glslViewer), aby dowiedzieć się więcej.
<!-- If you are like me, you will probably want to run shaders directly from the console, in that case you should check out [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). This application allows you to incorporate shaders into your `bash` scripts or unix pipelines and use it in a similar way to [ImageMagick](http://www.imagemagick.org/script/index.php). Also [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) is a great way to compile shaders on your [Raspberry Pi](https://www.raspberrypi.org/), which is the reason [openFrame.io](http://openframe.io/) uses it to display shader artwork. Learn more about this application [here](https://github.com/patriciogonzalezvivo/glslViewer). -->
```bash
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -E screenshot,yourOutputImage.png
```
**Twórz**: w celu usprawnienia procesu pisania shaderów stworzyłem edytor online [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). Edytor ten jest wykorzystywany w interaktywnych przykładach tej książki. Dodaje on poręczne widżety, czyniące abstrakcyjne doświadczenie pracy z kodem GLSL bardziej uchwytnym. Możesz również korzystać z niego jako samodzielnej aplikacji webowej pod adresem [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Kliknij [tutaj](https://github.com/patriciogonzalezvivo/glslEditor), aby dowiedzieć się więcej.
<!-- **Create**: in order to illuminate the experience of coding shaders I made an online editor called [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). This editor is embedded on the book's live examples, it brings a series of handy widgets to make more tangible the abstract experience of working with glsl code. You can also run it as a standalone web application from [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Learn more about it [here](https://github.com/patriciogonzalezvivo/glslEditor). -->
![](glslEditor-01.gif)
Jeśli preferujesz pracę offline z wykorzystaniem [SublimeText](https://www.sublimetext.com/), [rozszerzenie glslViewer](https://packagecontrol.io/packages/glslViewer) może cie zainteresować. Dowiedz się o nim więcej [tutaj](https://github.com/patriciogonzalezvivo/sublime-glslViewer).
<!-- If you prefer to work offline using [SublimeText](https://www.sublimetext.com/) you can install this [package for glslViewer](https://packagecontrol.io/packages/glslViewer). Learn more about it [here](https://github.com/patriciogonzalezvivo/sublime-glslViewer). -->
![](glslViewer.gif)
**Udostępniaj**: dzięki edytorowi online ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) możesz udstępniać swoje shadery! Zarówno webowa jak i stacjonarna wersja ma funkcję eksportu, generującą unikalny URL do twojego shadera. Ponadto, ma też funkcję bezpośredniego eksportu do [openFrame.io](http://openframe.io/).
<!-- **Share**: the online editor ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) can share your shaders! Both the embedded and standalone version have an export button where you can get an unique URL's to your shader. Also it has the ability to export directly to an [openFrame.io](http://openframe.io/). -->
![](glslEditor-00.gif)
**Organizuj**: udostępnianie kodu stanowi początek dzielenia się twoimi shaderowymi dziełami! Poza opcją eksportu do [openFrame.io](http://openframe.io/) stworzyłem narzędzie do organizowania twoich shaderów w galerię, którą można wstawić na dowolną stronę internetową; nazywa się [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Kliknij [tutaj](https://github.com/patriciogonzalezvivo/glslGallery), aby dowiedzieć się więcej.
<!-- **Curate**: Sharing your code is the beginning of you sharing your shader as artwork! Beside the option to export to [openFrame.io](http://openframe.io/) I made a tool to curate your shaders into a gallery that can be embedded on any site, its name is [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Learn more [here](https://github.com/patriciogonzalezvivo/glslGallery). -->
![](glslGallery.gif)
<!-- ## Running your shaders on your favorite framework -->
## Korzystanie shaderów w twoim ulubionym frameworku
Jeżeli programowanie we frameworkach jak [Processing](https://processing.org/), [Three.js](http://threejs.org/), [OpenFrameworks](http://openframeworks.cc/) or [SFML](https://www.sfml-dev.org/) nie jest ci obce, to opcja wypróbowania w nich swoich shaderów zapewne cie zainteresuje. Poniżej znajdziesz przykłady, jak wykorzystać shadery w każdym z nich (z takimi samymi uniformami jak w tej książce). (W [repozytorium GitHub'owym dla tego rozdziału](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) znajdziesz pełny kod źródłowy dla tych frameworków.
<!-- In case you already have experience programming in a framework like: [Processing](https://processing.org/), [Three.js](http://threejs.org/), [OpenFrameworks](http://openframeworks.cc/) or [SFML](https://www.sfml-dev.org/), you're probably excited to try shaders on these platforms you feel comfortable with. The following are examples of how to set shaders in some popular frameworks with the same uniforms that we are going to use throughout this book. (In the [GitHub repository for this chapter](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), you'll find the full source code for these three frameworks.) -->
### W **Three.js**
Znakomity i bardzo skromny Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) razem z [kontrybutorami](https://github.com/mrdoob/three.js/graphs/contributors) tworzą prawdopodobnie najbardziej popularny framework WebGL'owy zwany [Three.js](http://threejs.org/). Znajdziesz wiele przykładów, tutoriali i książek, które uczą, jak wykorzstać tę JavaScriptową bibliotekę do tworzenia odjazdowej grafiki 3D.
<!-- The brilliant and very humble Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) has been developing along with other [contributors](https://github.com/mrdoob/three.js/graphs/contributors) probably one of the most famous frameworks for WebGL, called [Three.js](http://threejs.org/). You will find a lot of examples, tutorials and books that teach you how to use this JavaScript library to make cool 3D graphics. -->
Poniżej znajduje się przykład kodu w HTML i JS potrzebny do rozpoczęcia przygody z shaderami w three.js. Zwróć uwage na skrypt z `id="fragmentShader"` - do niego możesz wstawiać kod shaderów, które znajdziesz, przykładowo, w tej książce.
<!-- Below is an example of the HTML and JS you need to get started with shaders in three.js. Pay attention to the `id="fragmentShader"` script, here is where you can copy the shaders you find in this book. -->
```html
<body>
<div id="container"></div>
<script src="js/three.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
gl_Position = vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec2 u_resolution;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
gl_FragColor=vec4(st.x,st.y,0.0,1.0);
}
</script>
<script>
var container;
var camera, scene, renderer, clock;
var uniforms;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
clock = new THREE.Clock();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.onmousemove = function(e){
uniforms.u_mouse.value.x = e.pageX
uniforms.u_mouse.value.y = e.pageY
}
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
uniforms.u_time.value += clock.getDelta();
renderer.render( scene, camera );
}
</script>
</body>
```
### W **Processing**
Stworzony przez [Ben Fry](http://benfry.com/) i [Casey Reas](http://reas.com/) w 2001, [Processing](https://processing.org/) jest nadzwyczaj prostym i potężnym środowiskiem, w którym możesz zacząć swoją przygodę z programowaniem (tak było w moim wypadku). [Andres Colubri](https://codeanticode.wordpress.com/) wniósł istotne zmiany do OpenGL i funkcji wideo w Processing, znacząco ułatwiając wykorzystanie w nim shaderów GLSL. Processing szuka pliku `shader.frag` w folderze `data`. Zatem, jeśli chcesz spróbować uruchomić przykłady z tej książki w Processing, to pamiętaj umieścić je w tym folderze i odpowiednio nazwać.
<!-- Started by [Ben Fry](http://benfry.com/) and [Casey Reas](http://reas.com/) in 2001, [Processing](https://processing.org/) is an extraordinarily simple and powerful environment in which to take your first steps in code (it was for me at least). [Andres Colubri](https://codeanticode.wordpress.com/) has made important updates to the openGL and video in Processing, making it easier than ever to use and play with GLSL shaders in this friendly environment. Processing will search for the shader named `"shader.frag"` in the `data` folder of the sketch. Be sure to copy the examples you find here into that folder and rename the file. -->
```cpp
PShader shader;
void setup() {
size(640, 360, P2D);
noStroke();
shader = loadShader("shader.frag");
}
void draw() {
shader.set("u_resolution", float(width), float(height));
shader.set("u_mouse", float(mouseX), float(mouseY));
shader.set("u_time", millis() / 1000.0);
shader(shader);
rect(0,0,width,height);
}
```
Aby shader działał na wersjach wcześniejszych niż 2.1, dodaj poniższą linijkę na początku shadera: `#define PROCESSING_COLOR_SHADER`. Powinno to wyglądać tak:
<!-- In order for the shader to work on versions previous to 2.1, you need to add the following line at the beginning of your shader: `#define PROCESSING_COLOR_SHADER`. So that it looks like this: -->
```glsl
#ifdef GL_ES
precision mediump float;
#endif
#define PROCESSING_COLOR_SHADER
uniform vec2 u_resolution;
uniform vec3 u_mouse;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.st/u_resolution;
gl_FragColor = vec4(st.x,st.y,0.0,1.0);
}
```
Jeśli chcesz wiedzieć więcej o sahderach w Processing, sprawdź ten [tutorial](https://processing.org/tutorials/pshader/).
<!-- For more information about shaders in Processing check out this [tutorial](https://processing.org/tutorials/pshader/). -->
### W **openFrameworks**
Każda ma takie miejsce, gdzie czuje się najabrdziej komfortowo. W moim wypadku jest to społeczność [openFrameworks](http://openframeworks.cc/). Ten C++'owy framework jest wrapperem OpenGL i innych open source'owych bibliotek C++. Pod pewnym względem jest całkiem podobny do Processing, ale z dodanym utrudnieniem radzenia sobie z kompilatorami C++.
<!-- Everybody has a place where they feel comfortable, in my case, thats still the [openFrameworks community](http://openframeworks.cc/). This C++ framework wraps around OpenGL and other open source C++ libraries. In many ways it's very similar to Processing, but with the obvious complications of dealing with C++ compilers. In the same way as Processing, openFrameworks will search for your shader files in the data folder, so dont forget to copy the `.frag` files you want to use and change the name when you load them. -->
```cpp
void ofApp::draw(){
ofShader shader;
shader.load("","shader.frag");
shader.begin();
shader.setUniform1f("u_time", ofGetElapsedTimef());
shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight());
ofRect(0,0,ofGetWidth(), ofGetHeight());
shader.end();
}
```
Polecam addon [ofxShader](https://github.com/patriciogonzalezvivo/ofxshader) do openFrameworks, jeśli potrzbujesz takiego zestawu uniformów jak w GlslViewer i GlslCanvas, wsparcia dla "multiple buffering", "material shaders", hot reload'owania oraz automatycznej konwersji do OpenGL ES na Raspberry Pi. Twój kod stanie się tak prosty jak poniżej:
<!-- If you want to use the full set of uniforms contain on the specs of GlslViewer and GlslCanvas in a more simple way on OpenFrameworks I recomend using the [ofxShader](https://github.com/patriciogonzalezvivo/ofxshader) addon which will also have support for multiple buffers, material shaders, hotreload and automatic conversion for OpenGL ES in the Raspberry Pi. And your code will be as simple as doing -->
```cpp
//--------------------------------------------------------------
void ofApp::setup(){
ofDisableArbTex();
sandbox.allocate(ofGetWidth(), ofGetHeight());
sandbox.load("grayscott.frag");
}
//--------------------------------------------------------------
void ofApp::draw(){
sandbox.render();
sandbox.draw(0, 0);
}
```
Po więcej informacji na temat shaderów w openFrameworks zajrzyj do znakomitego [tutoriala](http://openframeworks.cc/ofBook/chapters/shaders.html) autorstwa [Joshua Noble](http://thefactoryfactory.com/).
<!-- For more information about shaders in openFrameworks go to this [excellent tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) made by [Joshua Noble](http://thefactoryfactory.com/). -->
### W **Blender**
[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) to addon pozwalający programistycznie generować textury z użyciem shaderó GLSL. Jest on w pełni kompatybilny z resztą sandboxów w tym rozdziale. Jak go użyć?
<!-- [GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) is an addon that allows you to programmatically generate textures using GLSL Shaders and is fully compatible with the rest of the sandboxes on this chapter. How it works: -->
1. Operator Search: `F3` (lub `Spacja`, w zależności od twojego setupu ). Wpisz `GlslTexture`
![](blender/00.png)
2. Zmień pola `width` (szerokość), `height` (wysokość) oraz `Source` (ścieżka pliku źródłowego; może być ścieżką do zewnętrznego pliku).
![](blender/01.png)
3. Wykorzystaj węzeł Image w zakładce Materials. Nazwa węzła Image będzie taka sama jak nazwa pliku źródłowego.
<!-- 3. Use the Image on your materials. The Image name will be based on the name of the source file. -->
![](blender/02.png)
4. Idź do zakładki Scripting (lub zewnętrznego edytora, jeśli twój plik źródłowy jest zewnętrzny) i zacznij edytować shader. Będzie hot reload'owany.
<!-- 4. Go to the Text Editor (or an external editor if your source file is external) and edit the shader. It will hot reload. -->
![](blender/03.png)

@ -0,0 +1,8 @@
"Modern computers usually have groups of four processors that work like these pipes, completing tasks one after another"
- what is meant here by groups of four processors? Four CPU cores?
- fixed according to German version
Podać polskie tłumaczenie słowa pipeline
Podać angielskie tłumaczenie wejście i wyjście
Wytłumaczyć "hot reloading" (04)
Loading…
Cancel
Save