From eb8d3c5f80325e74a4b7d0e01dea35552d39091c Mon Sep 17 00:00:00 2001 From: Manoylov Andriy Date: Sat, 17 Jun 2023 15:49:08 +0300 Subject: [PATCH 01/47] add ukrainian translation --- 00/README-ua.md | 47 ++ 00/README.md | 2 +- 01/README-ua.md | 48 ++ 02/README-ua.md | 53 +++ 03/README-ua.md | 61 +++ 04/README-ua.md | 233 +++++++++ 04/README.md | 2 +- 05/README-ua.md | 134 ++++++ 06/README-ua.md | 136 ++++++ 07/README-ua.md | 233 +++++++++ 08/README-ua.md | 105 ++++ 09/README-ua.md | 115 +++++ 10/README-ua.md | 92 ++++ 11/README-ua.md | 220 +++++++++ 11/README.md | 2 +- 12/README-ua.md | 191 ++++++++ 13/README-ua.md | 111 +++++ 14/README-ua.md | 16 + 14/README.md | 15 +- 15/README-ua.md | 81 ++++ 15/README.md | 11 +- 15/index.php | 1 + 16/README-ua.md | 23 + 16/README.md | 7 +- 16/index.php | 5 +- README-ch.md | 2 + README-de.md | 2 + README-es.md | 4 +- README-fa.md | 4 +- README-fr.md | 2 + README-id.md | 4 +- README-it.md | 2 + README-jp.md | 2 + README-kr.md | 4 +- README-pl.md | 2 + README-pt.md | 4 +- README-ru.md | 2 + README-ua.md | 130 +++++ README-vi.md | 2 + README.md | 2 + appendix/00/README-ua.md | 33 ++ appendix/00/index.php | 1 + appendix/01/README-ua.md | 18 + appendix/01/index.php | 1 + appendix/02/README-ua.md | 72 +++ appendix/02/index.php | 1 + appendix/03/README-ua.md | 63 +++ appendix/03/index.php | 1 + appendix/04/README-ua.md | 449 ++++++++++++++++++ appendix/04/index.php | 1 + appendix/05/index.php | 1 + appendix/06/index.php | 1 + appendix/README-ua.md | 15 + appendix/index.php | 1 + examples/README-ua.md | 5 + glossary/README-ua.md | 278 +++++++++++ glossary/abs/README-ua.md | 21 + glossary/acos/README-ua.md | 21 + glossary/all/README-ua.md | 31 ++ glossary/any/README-ua.md | 31 ++ glossary/asin/README-ua.md | 21 + glossary/atan/README-ua.md | 32 ++ glossary/attribute/README-ua.md | 15 + glossary/bool/README-ua.md | 15 + glossary/bvec2/README-ua.md | 21 + glossary/bvec3/README-ua.md | 25 + glossary/bvec4/README-ua.md | 21 + glossary/ceil/README-ua.md | 21 + glossary/clamp/README-ua.md | 29 ++ glossary/const/README-ua.md | 13 + glossary/cos/README-ua.md | 21 + glossary/cross/README-ua.md | 18 + glossary/dFdx/README-ua.md | 16 + glossary/dFdy/README-ua.md | 16 + glossary/degrees/README-ua.md | 21 + glossary/distance/README-ua.md | 23 + glossary/dot/README-ua.md | 24 + glossary/equal/README-ua.md | 24 + glossary/exp/README-ua.md | 22 + glossary/exp2/README-ua.md | 21 + glossary/faceforward/README-ua.md | 23 + glossary/float/README-ua.md | 15 + glossary/floor/README-ua.md | 21 + glossary/fract/README-ua.md | 21 + glossary/gl_FragColor/README-ua.md | 9 + glossary/gl_FragCoord/README-ua.md | 9 + glossary/gl_FragCoord/README.md | 2 +- glossary/gl_FrontFacing/README-ua.md | 9 + .../README-ua.md | 9 + glossary/gl_MaxDrawBuffers/README-ua.md | 9 + .../gl_MaxFragmentUniformVectors/README-ua.md | 9 + glossary/gl_MaxTextureImageUnits/README-ua.md | 9 + glossary/gl_MaxVaryingVectors/README-ua.md | 9 + glossary/gl_MaxVertexAttribs/README-ua.md | 9 + .../README-ua.md | 9 + glossary/gl_PointCoord/README-ua.md | 9 + glossary/gl_PointSize/README-ua.md | 9 + glossary/gl_Position/README-ua.md | 9 + glossary/greaterThan/README-ua.md | 24 + glossary/greaterThanEqual/README-ua.md | 24 + glossary/highp/README-ua.md | 16 + glossary/in/README-ua.md | 26 + glossary/index.php | 5 +- glossary/inout/README-ua.md | 23 + glossary/int/README-ua.md | 15 + glossary/inversesqrt/README-ua.md | 21 + glossary/ivec2/README-ua.md | 21 + glossary/ivec3/README-ua.md | 25 + glossary/ivec4/README-ua.md | 21 + glossary/length/README-ua.md | 21 + glossary/lessThan/README-ua.md | 24 + glossary/lessThanEqual/README-ua.md | 24 + glossary/log/README-ua.md | 22 + glossary/log2/README-ua.md | 22 + glossary/lowp/README-ua.md | 16 + glossary/main/README-ua.md | 9 + glossary/mat2/README-ua.md | 37 ++ glossary/mat3/README-ua.md | 38 ++ glossary/mat4/README-ua.md | 38 ++ glossary/matrixCompMult/README-ua.md | 20 + glossary/max/README-ua.md | 27 ++ glossary/mediump/README-ua.md | 16 + glossary/min/README-ua.md | 27 ++ glossary/mix/README-ua.md | 31 ++ glossary/mod/README-ua.md | 27 ++ glossary/normalize/README-ua.md | 19 + glossary/not/README-ua.md | 18 + glossary/notEqual/README-ua.md | 24 + glossary/out/README-ua.md | 25 + glossary/pow/README-ua.md | 23 + glossary/precision/README-ua.md | 22 + glossary/radians/README-ua.md | 21 + glossary/reflect/README-ua.md | 23 + glossary/reflect/README.md | 2 +- glossary/refract/README-ua.md | 33 ++ glossary/return/README-ua.md | 12 + glossary/sampler2D/README-ua.md | 9 + glossary/samplerCube/README-ua.md | 9 + glossary/sign/README-ua.md | 21 + glossary/sin/README-ua.md | 21 + glossary/smoothstep/README-ua.md | 38 ++ glossary/sqrt/README-ua.md | 23 + glossary/step/README-ua.md | 31 ++ glossary/struct/README-ua.md | 27 ++ glossary/tan/README-ua.md | 21 + glossary/texture2D/README-ua.md | 25 + glossary/textureCube/README-ua.md | 25 + glossary/textureCube/README.md | 2 +- glossary/uniform/README-ua.md | 15 + glossary/varying/README-ua.md | 15 + glossary/vec2/README-ua.md | 21 + glossary/vec3/README-ua.md | 25 + glossary/vec4/README-ua.md | 21 + glossary/void/README-ua.md | 14 + src/main.js | 8 +- toc-header.php | 17 +- 156 files changed, 4981 insertions(+), 24 deletions(-) create mode 100644 00/README-ua.md create mode 100644 01/README-ua.md create mode 100644 02/README-ua.md create mode 100644 03/README-ua.md create mode 100644 04/README-ua.md create mode 100644 05/README-ua.md create mode 100644 06/README-ua.md create mode 100644 07/README-ua.md create mode 100644 08/README-ua.md create mode 100644 09/README-ua.md create mode 100644 10/README-ua.md create mode 100644 11/README-ua.md create mode 100644 12/README-ua.md create mode 100644 13/README-ua.md create mode 100644 14/README-ua.md create mode 100644 15/README-ua.md create mode 100644 16/README-ua.md create mode 100644 README-ua.md create mode 100644 appendix/00/README-ua.md create mode 100644 appendix/01/README-ua.md create mode 100644 appendix/02/README-ua.md create mode 100644 appendix/03/README-ua.md create mode 100644 appendix/04/README-ua.md create mode 100644 appendix/README-ua.md create mode 100644 examples/README-ua.md create mode 100644 glossary/README-ua.md create mode 100644 glossary/abs/README-ua.md create mode 100644 glossary/acos/README-ua.md create mode 100644 glossary/all/README-ua.md create mode 100644 glossary/any/README-ua.md create mode 100644 glossary/asin/README-ua.md create mode 100644 glossary/atan/README-ua.md create mode 100644 glossary/attribute/README-ua.md create mode 100644 glossary/bool/README-ua.md create mode 100644 glossary/bvec2/README-ua.md create mode 100644 glossary/bvec3/README-ua.md create mode 100644 glossary/bvec4/README-ua.md create mode 100644 glossary/ceil/README-ua.md create mode 100644 glossary/clamp/README-ua.md create mode 100644 glossary/const/README-ua.md create mode 100644 glossary/cos/README-ua.md create mode 100644 glossary/cross/README-ua.md create mode 100644 glossary/dFdx/README-ua.md create mode 100644 glossary/dFdy/README-ua.md create mode 100644 glossary/degrees/README-ua.md create mode 100644 glossary/distance/README-ua.md create mode 100644 glossary/dot/README-ua.md create mode 100644 glossary/equal/README-ua.md create mode 100644 glossary/exp/README-ua.md create mode 100644 glossary/exp2/README-ua.md create mode 100644 glossary/faceforward/README-ua.md create mode 100644 glossary/float/README-ua.md create mode 100644 glossary/floor/README-ua.md create mode 100644 glossary/fract/README-ua.md create mode 100644 glossary/gl_FragColor/README-ua.md create mode 100644 glossary/gl_FragCoord/README-ua.md create mode 100644 glossary/gl_FrontFacing/README-ua.md create mode 100644 glossary/gl_MaxCombinedTextureImageUnits/README-ua.md create mode 100644 glossary/gl_MaxDrawBuffers/README-ua.md create mode 100644 glossary/gl_MaxFragmentUniformVectors/README-ua.md create mode 100644 glossary/gl_MaxTextureImageUnits/README-ua.md create mode 100644 glossary/gl_MaxVaryingVectors/README-ua.md create mode 100644 glossary/gl_MaxVertexAttribs/README-ua.md create mode 100644 glossary/gl_MaxVertexTextureImageUnits/README-ua.md create mode 100644 glossary/gl_PointCoord/README-ua.md create mode 100644 glossary/gl_PointSize/README-ua.md create mode 100644 glossary/gl_Position/README-ua.md create mode 100644 glossary/greaterThan/README-ua.md create mode 100644 glossary/greaterThanEqual/README-ua.md create mode 100644 glossary/highp/README-ua.md create mode 100644 glossary/in/README-ua.md create mode 100644 glossary/inout/README-ua.md create mode 100644 glossary/int/README-ua.md create mode 100644 glossary/inversesqrt/README-ua.md create mode 100644 glossary/ivec2/README-ua.md create mode 100644 glossary/ivec3/README-ua.md create mode 100644 glossary/ivec4/README-ua.md create mode 100644 glossary/length/README-ua.md create mode 100644 glossary/lessThan/README-ua.md create mode 100644 glossary/lessThanEqual/README-ua.md create mode 100644 glossary/log/README-ua.md create mode 100644 glossary/log2/README-ua.md create mode 100644 glossary/lowp/README-ua.md create mode 100644 glossary/main/README-ua.md create mode 100644 glossary/mat2/README-ua.md create mode 100644 glossary/mat3/README-ua.md create mode 100644 glossary/mat4/README-ua.md create mode 100644 glossary/matrixCompMult/README-ua.md create mode 100644 glossary/max/README-ua.md create mode 100644 glossary/mediump/README-ua.md create mode 100644 glossary/min/README-ua.md create mode 100644 glossary/mix/README-ua.md create mode 100644 glossary/mod/README-ua.md create mode 100644 glossary/normalize/README-ua.md create mode 100644 glossary/not/README-ua.md create mode 100644 glossary/notEqual/README-ua.md create mode 100644 glossary/out/README-ua.md create mode 100644 glossary/pow/README-ua.md create mode 100644 glossary/precision/README-ua.md create mode 100644 glossary/radians/README-ua.md create mode 100644 glossary/reflect/README-ua.md create mode 100644 glossary/refract/README-ua.md create mode 100644 glossary/return/README-ua.md create mode 100644 glossary/sampler2D/README-ua.md create mode 100644 glossary/samplerCube/README-ua.md create mode 100644 glossary/sign/README-ua.md create mode 100644 glossary/sin/README-ua.md create mode 100644 glossary/smoothstep/README-ua.md create mode 100644 glossary/sqrt/README-ua.md create mode 100644 glossary/step/README-ua.md create mode 100644 glossary/struct/README-ua.md create mode 100644 glossary/tan/README-ua.md create mode 100644 glossary/texture2D/README-ua.md create mode 100644 glossary/textureCube/README-ua.md create mode 100644 glossary/uniform/README-ua.md create mode 100644 glossary/varying/README-ua.md create mode 100644 glossary/vec2/README-ua.md create mode 100644 glossary/vec3/README-ua.md create mode 100644 glossary/vec4/README-ua.md create mode 100644 glossary/void/README-ua.md diff --git a/00/README-ua.md b/00/README-ua.md new file mode 100644 index 0000000..9046e4a --- /dev/null +++ b/00/README-ua.md @@ -0,0 +1,47 @@ +# Вступ + + + +Наведені вище зображення були зроблені різними способами. Перше намальовано рукою Ван Гога з поступовим нанесенням фарби шар за шаром. Це зайняло в нього години. Друге було створено миттєво за допомоги комбінації чотирьох матриць пікселів різних кольорів: ціанового, пурпурового, жовтого та чорного. Ключова відмінність полягає в тому, що друге зображення отримано не послідовним чином, тобто не поступово крок за кроком, а усе одночасно. + +Ця книга про революційну техніку обчислювання - *фрагментні шейдери* - яка виводить генерацію цифрових зображень на новий рівень. Ви можете думати про це як про своєрідний еквівалент преса Гутенберга для графіки. + +![Gutenberg's press](gutenpress.jpg) + +Фрагментні шейдери дають вам повний контроль над пікселями екрану із надзвичайно високою швидкістю. Ось чому вони використовуються у самих різних випадках, від відеофільтрів на мобільних телефонах до неймовірних 3D-ігор. + +![Journey by That Game Company](journey.jpg) + +У наступних розділах ви дізнаєтесь, наскільки неймовірно швидка і потужна ця техніка та як застосувати її у своїх професійних та особистих проєктах. + +## Для кого ця книга? + +Книга написана для творчих програмістів, розробників ігор та інженерів, які мають досвід програмування, базові знання лінійної алгебри та тригонометрії й бажають вивести свою роботу на захопливий новий рівень графічної якості. Якщо ви тільки починаєте і хочете навчитися програмувати, я наполегливо рекомендую вам почати з [Processing](https://processing.org/) і повернутися пізніше, коли освоїтесь. + +Ця книга навчить вас використовувати та інтегрувати шейдери у ваші проєкти, покращуючи їхню продуктивність і графічну якість. Оскільки GLSL (OpenGL Shading Language) шейдери компілюються і працюють на різних платформах, ви зможете застосувати отримані тут знання до будь-якого середовища, яке використовує OpenGL, OpenGL ES або WebGL. Іншими словами, ви зможете застосовувати та використовувати свої знання у [Processing](https://processing.org/)-скетчах, [openFrameworks](http://openframeworks.cc/) програмах, інтерактивних інсталяціях [Cinder](http ://libcinder.org/), веб-сайтах з [Three.js](http://threejs.org/) або iOS/Android іграх. + +## Про що йдеться в цій книзі? + +Ця книга буде присвячена використанню піксельних GLSL шейдерів. Спочатку ми визначимо, що таке шейдери, а потім навчимося створювати за їх допомогою процедурні форми, візерунки, текстури та анімацію. Ви вивчите основи мови шейдерів та застосуєте її до більш корисних задач, таких як: обробка зображень (різні операції із зображеннями, згортання матриці, розмиття, кольорові фільтри, таблиці пошуку та інші ефекти) і симуляції ("гра життя" Конвея, реакційно-дифузійна модель Грея-Скотта, брижі води, акварельні ефекти, комірки Вороного тощо). Ближче до кінця книги ми побачимо набір передових технік, заснованих на Ray Marching (алгоритми трасування променів). + +*У кожному розділі є інтерактивні приклади, з кодом яких можна взаємодіяти.* При редагуванні коду ви одразу побачите відповідні зміни. Описані поняття можуть бути абстрактними та незрозумілими, тому інтерактивні приклади будуть корисними при вивченні матеріалу. Чим швидше ви побачите концепції в дії, тим легшим буде процес навчання. + +Що не розглядається в цій книзі: + +* Це *не* книга з openGL або webGL. OpenGL/webGL є більш обширною темою, ніж GLSL або фрагментні шейдери. Щоб дізнатися більше про openGL/webGL, я рекомендую переглянути: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (також відома як червона книга) або [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) + +* Це *не* підручник з математики. Хоча ми розглянемо низку алгоритмів і методів, які спираються на розуміння алгебри та тригонометрії, ми не будемо пояснювати їх докладно. Якщо у вас виникнуть запитання щодо математики, я рекомендую тримати під рукою одну з таких книг як: [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) або [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). + +## Що потрібно для початку? + +Не багато! Якщо у вас є сучасний браузер, який підтримує WebGL (наприклад, Chrome, Firefox або Safari) і підключення до Інтернету, просто натисніть кнопку «Next» в кінці цієї сторінки. + +Окрім того, в залежності від вашого бажання, ви можете: + +- [Зробити офлайн-версію книги](https://thebookofshaders.com/appendix/00/?lan=ua) + +- [Запустити приклади на Raspberry Pi без браузера](https://thebookofshaders.com/appendix/01/?lan=ua) + +- [Зібрати PDF-версію книги для друку](https://thebookofshaders.com/appendix/02/?lan=ua) + +- Переглянути [GitHub-репозиторій книги](https://github.com/patriciogonzalezvivo/thebookofshaders) для виправлення помилок або поділитися своїми прикладами коду. diff --git a/00/README.md b/00/README.md index 1b71977..34281ea 100644 --- a/00/README.md +++ b/00/README.md @@ -18,7 +18,7 @@ In the following chapters you will discover how incredibly fast and powerful thi This book is written for creative coders, game developers and engineers who have coding experience, a basic knowledge of linear algebra and trigonometry, and who want to take their work to an exciting new level of graphical quality. (If you want to learn how to code, I highly recommend you start with [Processing](https://processing.org/) and come back later when you are comfortable with it.) -This book will teach you how to use and integrate shaders into your projects, improving their performance and graphical quality. Because GLSL (OpenGL Shading Language) shaders compile and run on a variety of platforms, you will be able to apply what you learn here to any enviroment that uses OpenGL, OpenGL ES or WebGL. In other words, you will be able to apply and use your knowledge with [Processing](https://processing.org/) sketches, [openFrameworks](http://openframeworks.cc/) applications, [Cinder](http://libcinder.org/) interactive installations, [Three.js](http://threejs.org/) websites or iOS/Android games. +This book will teach you how to use and integrate shaders into your projects, improving their performance and graphical quality. Because GLSL (OpenGL Shading Language) shaders compile and run on a variety of platforms, you will be able to apply what you learn here to any environment that uses OpenGL, OpenGL ES or WebGL. In other words, you will be able to apply and use your knowledge with [Processing](https://processing.org/) sketches, [openFrameworks](http://openframeworks.cc/) applications, [Cinder](http://libcinder.org/) interactive installations, [Three.js](http://threejs.org/) websites or iOS/Android games. ## What does this book cover? diff --git a/01/README-ua.md b/01/README-ua.md new file mode 100644 index 0000000..808dd5c --- /dev/null +++ b/01/README-ua.md @@ -0,0 +1,48 @@ +# Вступ +## Що таке фрагментний шейдер? + +У попередньому розділі ми описали шейдери як еквівалент пресу Гутенберга для графіки. Чому? І що ще важливіше: що таке шейдер? + +![Ліворуч: літера за літерою (монах скрипторію за роботою, William Blades, 1891). Праворуч: Сторінка за сторінкою, (печатний станок, Rolt-Wheeler, 1920.](print.png) + +Якщо у вас уже є досвід малювання за допомогою комп'ютера, то ви знаєте, що в цьому процесі ви, умовно кажучи, спочатку малюєте коло, потім прямокутник, лінію, ще кілька трикутників і так далі, доки не отримаєте потрібне зображення. Цей процес дуже схожий на написання листа чи книги від руки – це набір інструкцій, які послідовно виконують одне завдання за іншим. + +Шейдери також є набором інструкцій, але вони виконуються одночасно для кожного пікселя на екрані. Це означає, що код, який ви пишете, має поводити себе по-різному залежно від положення пікселя на екрані. Подібно до печатного преса, ваша програма працюватиме як функція, яка отримує координати пікселя та повертає колір. Після компіляції вона працюватиме надзвичайно швидко. + +![Китайський набірний шрифт](typepress.jpg) + +## Чому шейдери швидкі? + +Щоб відповісти на це питання, я розповім про чудеса *паралельних обчислень*. + +Уявіть центральний процесор вашого комп'ютера у вигляді великої промислової труби, а кожне завдання як щось, що проходить крізь неї, як через фабричну лінію. Деякі завдання більші за інші, а це означає, що для їх вирішення потрібно більше часу та енергії. В комп'ютерному сенсі ми скажемо, що їм потрібна більша обчислювальна потужність. Через особливості архітектури комп'ютерів завдання виконуються послідовно, тобто по черзі. Сучасні комп'ютери зазвичай мають групи з кількох процесорів, які працюють як ці труби, виконуючи завдання одне за одним, щоб забезпечити безперебійну роботу. Кожна подібна труба також називається *потоком*. + +![CPU](00.jpeg) + +Відеоігри та інші графічні програми вимагають набагато більшої обчислювальної потужності, ніж інші програми. Через свій графічний контент їм доводиться виконувати величезну кількість попіксельних операцій. Необхідно обчислити кожен окремий піксель на екрані, а в 3D-іграх також потрібно обчислити усю геометрію і перспективу. + +Повернемося до нашої метафори про труби та завдання. Кожен піксель на екрані представляє просте маленьке завдання. Окремо такі завдання не є проблемою для CPU, але проблема в тому, що кожне крихітне завдання потрібно виконати для кожного пікселя на екрані! Це означає, що на старому екрані з роздільною здатністю 800x600 потрібно обробляти 480 000 пікселів на 1 кадр оновлення, що становить близько 14 400 000 обчислень за секунду! О, так! Це достатньо велика проблема, щоб перенавантажити мікропроцесор. У сучасному дисплеї Retina 2880x1800, що оновлюється зі швидкістю 60 кадрів на секунду, ця кількість обчислень за секунду складе 311 040 000. Як інженери графічних систем розв'язують цю проблему? + +![](03.jpeg) + +Ось коли паралельні обчислення стають хорошим рішенням. Замість того, щоб мати пару великих і потужних мікропроцесорів, або *труб*, розумніше мати багато маленьких мікропроцесорів, що працюють паралельно. Саме так і влаштовано графічний процесор (GPU). + +![GPU](04.jpeg) + +Уявіть крихітні мікропроцесори у вигляді столу із труб, а дані кожного пікселя як кульку для пінг-понгу. 14 400 000 кульок для пінг-понгу за секунду можуть закупорити майже будь-яку трубу. Але стіл з крихітними трубками розміром 800x600, зможе спокійно прийняти 30 хвиль по 480 000 пікселів за секунду і працюватиме безперебійно. Те ж саме і з прикладом вищої роздільної здатності - чим більше у вас обладнання, що працює паралельно, тим більшим потоком воно зможе керувати. + +Ще одна "суперздатність" графічного процесора — це спеціальні математичні функції, прискорені за допомогою апаратного забезпечення. Тож складні математичні операції вирішуються безпосередньо мікрочіпами, а не програмним забезпеченням. Це означає надшвидкі тригонометричні та матричні операції - настільки швидкі, наскільки швидко може рухатися електрика. + +## Що таке GLSL? + +GLSL розшифровується як OpenGL Shading Language і є спеціальним стандартом шейдерних програм, які ви побачите в наступних розділах. Залежно від апаратного забезпечення та операційної системи існують різні типи шейдерів. Ми працюватимемо зі специфікаціями OpenGL, які регулює [Khronos Group](https://www.khronos.org/opengl/). Розуміння історії OpenGL може бути корисним для розуміння більшості його дивних конвенцій. Для цього я рекомендую переглянути наступне посилання: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html) + +## Чому шейдери такі болючі? + +Як сказав дядько Бен, "з великою силою приходить велика відповідальність" і паралельні обчислення дотримуються цього правила. Потужний архітектурний дизайн графічного процесора має власні обмеження. + +Щоб працювати паралельно, кожен канал або потік має бути незалежним від будь-якого іншого потоку. Ми кажемо, що потоки *сліпі* стосовно того, що роблять інші потоки. Це обмеження означає, що всі дані повинні рухатись в одному напрямку. Тому неможливо перевірити результат іншого потоку, змінити вхідні дані або передати результат одного потоку в інший потік. Спроба дозволу міжпотокових зв'язків ставить під загрозу цілісність даних. + +Крім того, GPU підтримує свої мікропроцесори (труби) постійно зайнятими. Як тільки вони звільняються, вони отримують нову інформацію для обробки. Потоку неможливо дізнатися, що він робив у попередній момент. Це могло бути малювання кнопки інтерфейсу операційної системи, потім рендеринг частини неба із гри, а потім зображення тексту електронного листа. Кожен потік є не лише **сліпим**, а й **безпам'ятним**. Окрім абстракції, необхідної для кодування загальної функції, яка змінює результат в залежності від положення пікселя, сліпота і безпам'ятство роблять шейдери не дуже популярними серед програмістів-початківців. + +Не хвилюйтесь! У наступних розділах ми крок за кроком розглянемо шейдерні обчислення від простого до складного. Якщо ви читаєте книгу в сучасному браузері, то оціните можливість взаємодії з інтерактивними прикладами. Тож давайте більше не відкладати веселощі та натискайте на посилання *Next >>*, щоб перейти до програмування! diff --git a/02/README-ua.md b/02/README-ua.md new file mode 100644 index 0000000..3050210 --- /dev/null +++ b/02/README-ua.md @@ -0,0 +1,53 @@ +## Hello World + +Зазвичай програма "Hello world!" — це перший крок до вивчення нової мови. Це проста програма, яка виводить вітальне повідомлення та заявляє про майбутні можливості. + +У GPU-світі рендеринг тексту є надскладним завданням для першого кроку. Натомість щоб висловити свій ентузіазм, ми виберемо та намалюємо яскравий колір! + +
+ +Якщо ви читаєте цю книгу в браузері, попередній блок коду є інтерактивним. Це означає, що ви можете змінити будь-яку частину коду, яку захочете. Зміни будуть оновлені негайно завдяки архітектурі GPU, яка компілює та замінює шейдери *на льоту*. Спробуйте змінити значення в рядку 8. + +Хоча ці прості рядки коду не виглядають складними, ми можемо вивести з них суттєві знання: + +1. Мова шейдерів має одну функцію `main`, яка повертає колір у кінці. Це схоже на мову C. + +2. Остаточний колір пікселя записується у зарезервовану глобальну змінну `gl_FragColor`. + +3. У цій C-подібній мові є вбудовані *змінні* (наприклад, `gl_FragColor`), *функції* і *типи*. У цьому випадку ми щойно познайомилися з `vec4`, який означає чотиривимірний вектор числових значень з рухомою крапкою. Пізніше ми побачимо більше типів, таких як `vec3` і `vec2` разом із популярними `float`, `int` і `bool`. + +4. Якщо ми уважно подивимося на тип `vec4`, то можемо зробити висновок, що його чотири аргументи відповідають ЧЕРВОНОМУ, ЗЕЛЕНОМУ, СИНЬОМУ та АЛЬФА-каналам. Також ми бачимо, що ці значення *нормалізовані* - це означає, що вони знаходяться в діапазоні від `0.0` до `1.0`. Пізніше ми дізнаємося, як нормалізація полегшує *зіставлення* значень між змінними. + +5. Інша важлива *C-особливість*, яку ми можемо побачити в цьому прикладі, вказує на наявність макросів препроцесора. Макроси є частиною етапу попередньої компіляції. З їх допомогою можна визначити (`#define`) глобальні змінні та виконати деякі базові умовні операції, використовуючи `#ifdef` і `#endif`. Усі макрокоманди починаються з символу решітки `#`. Пре-компіляція відбувається безпосередньо перед компіляцією, підставляє всі визначення із директив `#defines` і перевіряє умови `#ifdef` (якщо визначено) і `#ifndef` (якщо не визначено). У наведеному вище прикладі "hello world!", ми вставляємо рядок 2, лише якщо визначено `GL_ES`, що здебільшого відбувається, коли код компілюється на мобільних пристроях і в браузерах. + +6. Типи чисел з рухомою крапкою життєво важливі в шейдерах, тому рівень *точності* є вирішальним. Нижча точність означає швидший рендеринг, але ціною якості. Ви можете бути вибагливими та вказати точність кожної такої змінної, яку використовує. У другому рядку (`precision mediump float;`) ми встановлюємо середню точність для всіх значень з рухомою крапкою. Також можна вибрати низьку (`precision lowp float;`) або високу (`precision highp float;`) точність. + +7. Остання і, мабуть, найважливіша деталь полягає в тому, що специфікації GLSL не гарантують автоматичного приведення типів. Що це означає? Виробники мають різні підходи до прискорення роботи відеокарт, але вони змушені гарантувати мінімальні вимоги. Автоматичне приведення типів не відноситься до них. У нашому прикладі `vec4` має містити число з рухомою крапкою на яке й очікує. Якщо ви хочете писати якісний узгоджений код і не витрачати години на відладку білих екранів, звикніть ставити крапку (`.`) для значень з рухомою крапкою. Бо наступний код працюватиме не завжди та не скрізь: + +```glsl +void main() { + gl_FragColor = vec4(1, 0, 0, 1); // ПОМИЛКА +} +``` + +Тепер, коли ми описали найбільш релевантні елементи нашої програми "hello world!", настав час повернутися до блоку з кодом та почати застосовувати отримані знання. Ви помітите, що в разі помилок програма не компілюється, показуючи білий екран. Є кілька речей, які можна спробувати, наприклад: + +* Спробуйте замінити числа з рухомою крапкою на цілі числа. Ваша графічна карта може підтримувати або не підтримувати таку поведінку. + +* Спробуйте закоментувати рядок 8 і не призначати пікселю жодного значення. + +* Спробуйте створити окрему функцію, яка повертає певний колір, і використайте її всередині `main()`. Нижче приклад функції, яка повертає червоний колір: + +```glsl +vec4 red() { + return vec4(1.0, 0.0, 0.0, 1.0); +} +``` + +* Існує кілька способів конструювання типу `vec4`, спробуйте знайти інші способи. Ось один з них: + +```glsl +vec4 color = vec4(vec3(1.0, 0.0, 1.0), 1.0); +``` + +Це не дуже захопливий, але найпростіший приклад - ми змінюємо всі пікселі всередині полотна на той самий однаковий колір. У наступному розділі ми побачимо, як змінити кольори пікселів за допомогою двох типів вхідних даних: просторового (положення пікселя на екрані) і часового (кількість секунд після завантаження сторінки). diff --git a/03/README-ua.md b/03/README-ua.md new file mode 100644 index 0000000..db9f60b --- /dev/null +++ b/03/README-ua.md @@ -0,0 +1,61 @@ +## Uniforms + +Раніше ми побачили, яким чином графічний процесор керує великою кількістю паралельних потоків, кожен з яких відповідає за призначення кольору частці загального зображення. Хоча кожен паралельний потік закритий для інших, ми повинні мати можливість надсилати деякі вхідні дані від CPU до всіх потоків. Через архітектуру відеокарти ці вхідні дані будуть однаковими (*uniform* - *уніфікованими*, *однорідними*) для всіх потоків і доступними *лише для читання*. Іншими словами, кожен потік отримує ті ж самі дані, які він може читати, але не може змінювати. + +Ці вхідні дані називаються `uniform` та мають більшість підтримуваних типів: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `sampler2D` і `samplerCube `. Uniform-змінні визначаються з відповідним типом у верхній частині шейдера відразу після встановлення точності для float-значень. + +```glsl +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; // Розмір полотна (ширина, висота) +uniform vec2 u_mouse; // Положення курсору на екрані +uniform float u_time; // Час у секундах з моменту запуску коду +``` + +Ви можете уявити uniform-змінні як маленькі містки між CPU та GPU. Назви для змінних можуть відрізнятися від реалізації до реалізації, але в цій серії прикладів я завжди передаю: `u_time` (час у секундах із моменту запуску шейдера), `u_resolution` (розмір зображення де застосовується шейдер) і `u_mouse` (положення курсору всередині зображення, що вимірюється у пікселях). Я дотримуюся конвенції з префіксом `u_` перед назвою uniform-змінних, щоб чітко означити природу таких змінних, але насправді ви можете зустріти різні назви. Наприклад, [ShaderToy.com](https://www.shadertoy.com/) використовує ті ж самі змінні, але з наступними назвами: + +```glsl +uniform vec3 iResolution; // роздільна здатність області зображення, у пікселях (viewport resolution) +uniform vec4 iMouse; // піксельні координати курсору. xy - поточні, zw - клік +uniform float iTime; // час роботи шейдера (у секундах) +``` + +Досить розмов, подивимося на уніформи в дії. У наведеному нижче коді ми використовуємо `u_time` — кількість секунд із моменту запуску шейдера — разом із синус-функцією, щоб анімувати зміни у кількості червоного кольору на екрані. + +
+ +Як ви бачите, GLSL має ще багато сюрпризів. GPU має апаратне прискорення для кутових, тригонометричних та експоненціальних функцій. Ось деякі з цих функцій: [`sin()`](../glossary/?lan=ua&search=sin), [`cos()`](../glossary/?lan=ua&search=cos), [`tan()`](../glossary/?lan=ua&search=tan), [`asin()`](../glossary/?lan=ua&search=asin), [`acos()`](../glossary/?lan=ua&search=acos), [`atan()`](../glossary/?lan=ua&search=atan), [`pow()`](../glossary/?lan=ua&search=pow), [`exp()`](../glossary/?lan=ua&search=exp), [`log()`](../glossary/?lan=ua&search=log), [`sqrt()`](../glossary/?lan=ua&search=sqrt), [`abs()`](../glossary/?lan=ua&search=abs), [`sign()`](../glossary/?lan=ua&search=sign), [`floor()`](../glossary/?lan=ua&search=floor), [`ceil()`](../glossary/?lan=ua&search=ceil), [`fract()`](../glossary/?lan=ua&search=fract), [`mod()`](../glossary/?lan=ua&search=mod), [`min()`](../glossary/?lan=ua&search=min), [`max()`](../glossary/?search=max) and [`clamp()`](../glossary/?lan=ua&search=clamp). + +Настав час знову пограти з наведеним вище кодом. + +* Уповільнюйте частоту, щоб зміна кольору стала майже непомітною. + +* Пришвидшуйте, поки не побачите один колір без мерехтіння. + +* Пограйтеся із RGB-каналами та різними частотами для них, щоб отримати якусь цікаву поведінку. + +## gl_FragCoord + +Подібно до того як GLSL, за замовчуванням, дає нам вихідні дані `vec4 gl_FragColor`, він також дає нам вхідні дані за замовчуванням, `vec4 gl_FragCoord`, що містять екранні координати *пікселя* або *фрагменту екрана*, з якими працює активний потік. За допомогою `vec4 gl_FragCoord` ми знаємо, де саме працює поточний потік всередині зображення. У цьому випадку ми не називаємо його `uniform`, тому що він буде відрізнятися від потоку до потоку, натомість `gl_FragCoord` називається *varying* (змінливим). + +
+ +У наведеному вище коді ми *нормалізуємо* координати фрагмента, розділивши їх на роздільну здатність зображення. У результаті цього отримані значення будуть змінюватися у діапазоні від `0.0` до `1.0`, що полегшує зіставлення X і Y значень з ЧЕРВОНИМ і ЗЕЛЕНИМ каналами. + +У світі шейдерів ми не маємо зручних інструментів для зневаджування програми, тому інколи доводиться призначати змінним якісь яскраві кольори, щоб за їх допомогою спробувати дістати потрібну інформацію. Ви виявите, що кодування на GLSL іноді дуже схоже на розміщення корабля у пляшку. Це однаково важко, красиво і захопливо. + +![](08.png) + +Тепер настав час перевірити наше розуміння цього коду. + +* Чи можете ви сказати, де знаходиться координата `(0.0, 0.0)` на нашому полотні? + +* А як щодо `(1.0, 0.0)`, `(0.0, 1.0)`, `(0.5, 0.5)` і `(1.0, 1.0)`? + +* Чи можете ви зрозуміти, як використати змінну `u_mouse`, знаючи, що її значення вказані в пікселях і НЕ нормалізовані? Чи зможете за її допомогою і руху курсору змінювати кольори? + +* Чи можете ви вигадати цікавий спосіб для зміни кольорів за допомогою координат `u_time` і `u_mouse`? + +Після виконання цих вправ ви можете поставити собі питання: де ще можна спробувати можливості шейдерів. У наступному розділі ми розглянемо, як створити власні шейдерні інструменти у three.js, Processing і openFrameworks. diff --git a/04/README-ua.md b/04/README-ua.md new file mode 100644 index 0000000..6873511 --- /dev/null +++ b/04/README-ua.md @@ -0,0 +1,233 @@ +## Запуск шейдера + +У процесі створення цієї книги та моєї художньої практики, я сформував екосистему інструментів для створення шейдерів, їх відображення, спільного використання та керування. Ці інструменти працюють однаково в Linux, MacOS, Windows, [Raspberry Pi](https://www.raspberrypi.org/) та браузерах без необхідності змінювати код. + +## Запуск шейдерів у браузері + +**Відображення**: усі інтерактивні приклади в цій книзі відображаються за допомогою [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas), що робить процес запуску автономного шейдера неймовірно простим. + +```html + +``` + +Як бачите, для цього потрібен лише елемент `canvas` із відповідним класом `class="glslCanvas"` та URL-адресою вашого шейдера, заданої в атрибуті `data-fragment-url`. Дізнатися більше про це можна [тут](https://github.com/patriciogonzalezvivo/glslCanvas). + +Якщо ви схожі на мене, ви, ймовірно, захочете запускати шейдери безпосередньо з консолі. У такому випадку вам допоможе [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Ця програма дозволяє вам включати шейдери у ваші `bash`-скрипти або unix-конвеєри та використовувати їх подібно до [ImageMagick](http://www.imagemagick.org/script/index.php). Також [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) є чудовим способом компіляції шейдерів на [Raspberry Pi](https://www.raspberrypi.org/), через що [openFrame.io](http://openframe.io/) використовує його для демонстрації шейдерних робіт. Дізнайтеся більше про цю програму за цим [посиланням](https://github.com/patriciogonzalezvivo/glslViewer). + +```bash +glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -E screenshot,yourOutputImage.png +``` + +**Створення**: щоб покращити досвід кодування шейдерів, я створив онлайн-редактор під назвою [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). Цей редактор використовується в інтерактивних прикладах книги та пропонує низку зручних віджетів, що робить взаємодію з абстрактним кодом glsl більш відчутним. Ви також можете запустити його як окрему вебпрограму: [editor.thebookofshaders.com](http://editor.thebookofshaders.com/). Дізнатися більше про редактор можна [тут](https://github.com/patriciogonzalezvivo/glslEditor). + +![](glslEditor-01.gif) + +Якщо ви бажаєте працювати з редактором офлайн за допомогою [SublimeText](https://www.sublimetext.com/), то можете встановити цей [пакет для glslViewer](https://packagecontrol.io/packages/glslViewer). Дізнайтеся більше [тут](https://github.com/patriciogonzalezvivo/sublime-glslViewer). + +![](glslViewer.gif) + +**Експортування**: онлайн-редактор ([editor.thebookofshaders.com](http://editor.thebookofshaders.com/)) може поділитися вашими шейдерами! Як вбудована, так і окрема версія мають кнопку для експорту, за допомогою якої ви можете отримати унікальну URL-адресу свого шейдера. Також є можливість експортувати шейдер безпосередньо в [openFrame.io](http://openframe.io/). + +![](glslEditor-00.gif) + +**Керування**: експорт коду — початок для того, щоб ви ділилися своїм шейдером у якості художнього витвору! Окрім опції експорту в [openFrame.io](http://openframe.io/), я створив інструмент для керування вашими шейдерами у галереї, яку можна вбудувати у будь-який сайт — [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Детальніше [тут](https://github.com/patriciogonzalezvivo/glslGallery). + +![](glslGallery.gif) + +## Запуск ваших шейдерів у вашому улюбленому фреймворку + +Якщо у вас уже є досвід програмування в таких фреймворках, як [Processing](https://processing.org/), [Three.js](http://threejs.org/), [OpenFrameworks](http://openframeworks.cc/) або [SFML](https://www.sfml-dev.org/), ви, мабуть, із задоволенням спробуєте шейдери у них. Нижче наведено приклади того, як налаштувати шейдери в деяких популярних фреймворках з вказаними у книзі uniform-змінними. У [GitHub-репозиторії для цього розділу](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) ви знайдете повний вихідний код для цих трьох фреймворків. + +### **Three.js** + +Блискучий і дуже скромний Ricardo Cabello (він же [MrDoob](https://twitter.com/mrdoob)) з групою інших [однодумців](https://github.com/mrdoob/three.js/graphs/contributors) розробили один із найвідоміших фреймворків для WebGL під назвою [Three.js](http://threejs.org/). Там ви знайдете безліч прикладів, посібників і книг, які навчать вас, як використовувати цю JS-бібліотеку для створення класної 3D-графіки. + +Нижче наведено приклад із HTML та JS, які необхідні для початку роботи з шейдерами у three.js. Зверніть увагу на скрипт з `id="fragmentShader"` куди ви можете скопіювати шейдери, знайдені в цій книзі. + +```html + +
+ + + + + +``` + +### **Processing** + +[Processing](https://processing.org/) започатковано у 2001 році у співпраці між [Ben Fry](http://benfry.com/) та [Casey Reas](http://reas.com/). Фреймворк є надзвичайно простим та потужним середовищем, у якому можна робити свої перші кроки в програмуванні (принаймні так було у мене). [Andres Colubri](https://codeanticode.wordpress.com/) вніс важливі оновлення в Processing для підтримки openGL і відео, що полегшило використання шейдерів GLSL у цьому дружньому середовищі, ніж будь-коли. Processing шукатиме шейдер із назвою `"shader.frag"` у теці `data` вашого скетчу. Тож вам достатньо скопіювати приклади цієї книги у файл із відповідною назвою. + +```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); +} +``` + +Щоб шейдер працював у попередніх версіях, нижчих за 2.1, вам потрібно додати рядок `#define PROCESSING_COLOR_SHADER` на початку вашого шейдера. Це виглядатиме так: + +```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); +} +``` + +Щоб дізнатися більше про шейдери у Processing, перегляньте цей [посібник](https://processing.org/tutorials/pshader/). + +### **openFrameworks** + +У кожного є місце, де йому комфортно, у моєму випадку таким місцем залишається [спільнота openFrameworks](http://openframeworks.cc/). Цей C++ фреймворк є обгорткою навколо OpenGL та інших бібліотек на C++ з відкритим кодом. Багато в чому він дуже схожий на Processing, але зі своїми особливостями роботи з використанням компіляторів C++. Так само як і Processing, openFrameworks шукатиме ваші файли шейдерів у теці `data`. Тому не забудьте скопіювати код прикладів, які хочете використати, у файли з розширенням `.frag` і покласти їх у згадану теку: + +```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(); +} +``` + +Якщо ви хочете використовувати в OpenFrameworks повний набір уніформ, що містяться в специфікаціях GlslViewer і GlslCanvas, простішим способом, я рекомендую використовувати доповнення [ofxShader](https://github.com/patriciogonzalezvivo/ofxshader). Воно також має підтримку кількох буферів, шейдерних матеріалів, гаряче перезавантаження та автоматизацію для OpenGL ES у Raspberry Pi. Ваш код буде таким же простим, як нижче: + +```cpp +//-------------------------------------------------------------- +void ofApp::setup(){ + ofDisableArbTex(); + + sandbox.allocate(ofGetWidth(), ofGetHeight()); + sandbox.load("grayscott.frag"); +} + +//-------------------------------------------------------------- +void ofApp::draw(){ + sandbox.render(); + sandbox.draw(0, 0); +} +``` + + +Щоб дізнатися більше про шейдери в openFrameworks, перегляньте цей [чудовий посібник](http://openframeworks.cc/ofBook/chapters/shaders.html), створений [Joshua Noble](http://thefactoryfactory.com/). + +### **Blender** + +[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) — це доповнення, яке дозволяє програмно генерувати текстури за допомогою шейдерів GLSL і повністю сумісне з рештою прикладів даного розділу. Як це працює: + + +1. Ввімкніть пошук: `F3` або `пробіл`, залежно від налаштувань. Введіть `GlslTexture`: + +![](blender/00.png) + +2. Змініть значення розмірів для полів `width`, `height` та `Source`-шлях до зовнішнього файлу, якщо такий є. + +![](blender/01.png) + +3. Використовуйте зображення у своїх матеріалах. Ім’я зображення базуватиметься на назві вихідного файлу. + +![](blender/02.png) + +4. Перейдіть до текстового редактора (або зовнішнього редактора, якщо ваш вихідний файл також зовнішній) і відредагуйте шейдер. Після чого відбудеться оновлення результату. + +![](blender/03.png) diff --git a/04/README.md b/04/README.md index 5374279..444dcf0 100644 --- a/04/README.md +++ b/04/README.md @@ -190,7 +190,7 @@ void ofApp::draw(){ } ``` -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 +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 recommend 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 //-------------------------------------------------------------- diff --git a/05/README-ua.md b/05/README-ua.md new file mode 100644 index 0000000..48f4b70 --- /dev/null +++ b/05/README-ua.md @@ -0,0 +1,134 @@ +# Алгоритмічне малювання +## Формотворчі функції або функції формування + +Цей розділ можна було б назвати "Урок з парканом від містера Міягі". Раніше ми зіставляли нормалізоване положення координат *x* і *y* з *червоним* і *зеленим* каналами. По суті, ми створили функцію, яка приймає двовимірний вектор (x і y) та повертає чотиривимірний вектор (r, g, b і a). Але перш ніж перейти до подальшого перетворення даних між вимірами, нам потрібно почати з простіших речей... набагато простіших. З розуміння того, як користуватись одновимірними функціями. Чим більше часу та енергії ви витратите на освоєння цього і відповідну практику, тим сильнішим буде ваше шейдерне карате. + +![The Karate Kid (1984)](mr_miyagi.jpg) + +Наступний приклад коду буде нашим парканом. У ньому ми візуалізуємо нормалізоване значення координати *x* (`st.x`) двома способами: один за допомогою яскравості (подивіться на гарний градієнт від чорного до білого), а інший шляхом побудови зеленої діагональної лінії зверху (у цьому випадку значення *x* присвоюється безпосередньо до *y*). Поки що не зосереджуйтеся занадто на функції `plot`. Згодом ми розберемося з нею більш детально. + +
+ +**Коротка примітка**: конструктор типу `vec3` "розуміє", що ви хочете призначити одне і те саме значення трьом каналам, тоді як `vec4` розуміє, що ви хочете побудувати чотиривимірний вектор за допомогою одного тривимірного і додаткового четвертого значення. У цьому випадку четверте значення відповідатиме за альфа-канал або непрозорість. Перегляньте ці приклади на рядках 19 і 25. + +Цей код — ваш паркан. Важливо бачити його і розуміти. Ви знову і знову повертатиметеся до цього простору між *0.0* і *1.0*. Ви опануєте мистецтво змішування та формування подібних ліній. + +Цей однозначний зв'язок між *x* і *y* (або яскравістю) відомий як *лінійна інтерполяція*. З цього моменту ми можемо використовувати деякі математичні функції для надання лінії певної *форми*, для її формування. Наприклад, ми можемо піднести *x* до 5 степеня, щоб отримати *криву* лінію. + +
+ +Цікаво, правда? У рядку 22 спробуйте різні показники для степеня: наприклад, 20.0, 2.0, 1.0, 0.0, 0.2 і 0.02. Розуміння цього зв'язку між значенням і експонентою буде дуже корисним. Використання подібних типів математичних функцій дасть вам виразний засіб для контролю вашого коду, свого роду акупунктуру даних, яка дозволить вам контролювати потік значень. + +[`pow()`](../glossary/?lan=ua&search=pow) — одна з багатьох вбудованих функцій GLSL. Більшість із них прискорені на апаратному рівні, а це означає, що якщо вони використовуються належним чином і з обережністю, то ваш код стане швидшим. + +Замініть функцію `pow` у рядку 22 на якусь іншу, наприклад: [`exp()`](../glossary/?lan=ua&search=exp), [`log()`](../glossary/?lan=ua&search=log) і [`sqrt()`](../glossary/?lan=ua&search=sqrt). Деякі з цих функцій стають цікавіші із використанням числа PI. У рядку 8 ви можете побачити, що я визначив макрос, який замінить будь-яке використання `PI` на значення `3.14159265359`. + +### step і smoothstep + +GLSL має деякі унікальні функції інтерполяції, які також апаратно прискорені. + +Функція інтерполяції [`step()`](../glossary/?lan=ua&search=step) приймає два параметри. Перший — це межа або поріг, а другий — це значення для якого ми хочемо застосувати функцію. Будь-яке значення нижче порогу поверне `0.0`, а все, що його перевищує — `1.0`. + +Спробуйте змінити у наступному коді порогове значення, що на рядку 20: + +
+ +Інша унікальна функція називається [`smoothstep()`](../glossary/?lan=ua&search=smoothstep). Функція плавно інтерполює значення у вказаному діапазоні з двох чисел. Перші два параметри призначені для початку та кінця перехідного діапазону, а третій — для значення, яке потрібно інтерполювати. + +
+ +У функції `plot()` на рядку 12 попереднього прикладу, ми використали smoothstep, щоб намалювати зелену лінію. Для кожної позиції вздовж вісі *x* ця функція робить *виступи* у певному значенні *y*. Яким чином? Об'єднавши результат двох функцій [`smoothstep()`](../glossary/?lan=ua&search=smoothstep) разом. Погляньте на наступну функцію, замініть нею рядок 20 вище і подумайте про неї як про вертикальний розріз. Фон схожий на лінію, чи не так? + +```glsl +float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x); +``` + +### Синус і Косинус + +Коли ви хочете застосувати певну математику для анімації, або при формуванні чи змішуванні значень, немає нічого кращого, ніж товаришувати з синусом і косинусом. + +Ці дві основні тригонометричні функції працюють у парі при побудові кола, що є настільки ж корисним, як і швейцарський армійський ніж. Важливо знати, як вони поводяться і як їх можна комбінувати. Коротко кажучи, задаючи їм кут у радіанах, вони повертають правильне положення координати *x* ([cos](../glossary/?lan=ua&search=cos)) і *y* ([sin](../glossary/?lan=ua&search=sin)) точки на краю кола з радіусом, рівним 1. А той факт, що вони повертають нормалізовані значення (від -1 до 1), які до того ж достатньо плавні, робить їх неймовірним інструментом. + +![](sincos.gif) + +Хоча важко описати всі взаємозв'язки між тригонометричними функціями та колами, наведена вище анімація чудово їх узагальнює. + +
+ +Уважно подивіться на зображену вище синусоїду. Зверніть увагу, як значення *y* плавно змінюються між +1 і -1. Як ми бачили у прикладі зі змінною для часу, що був у попередньому розділі, ви можете використовувати цю ритмічну поведінку [`sin()`](../glossary/?lan=ua&search=sin) для анімації властивостей. Якщо ви читаєте цей приклад у браузері, то можете змінити код у формулі вище, щоб побачити, як змінюється хвиля. (Примітка: не забудьте про крапку з комою в кінці рядка.) + +Спробуйте виконати наступні вправи та зверніть увагу на те, що відбувається: + +* Додайте час (`u_time`) до *x* перед обчисленням `sin`. Оцініть **рух** уздовж осі *x*. + +* Помножте *x* на `PI` перед обчисленням `sin`. Зверніть увагу, як дві фази **скорочуються**, так що кожен цикл повторюється через кожні 2 цілих числа. + +* Помножте час (`u_time`) на *x* перед обчисленням `sin`. Подивіться, як **частота** між фазами стає все більш і більш стиснутою. Зверніть увагу, що `u_time` до цього моменту може стати вже дуже великим, що ускладнить сприйняття отриманого графіка. + +* Додайте 1.0 до [`sin(x)`](../glossary/?lan=ua&search=sin). Подивіться, як уся хвиля **змістилася** вгору, і тепер усі значення знаходяться між 0.0 і 2.0. + +* Помножте [`sin(x)`](../glossary/?lan=ua&search=sin) на 2.0. Подивіться, як **амплітуда** збільшилася вдвічі. + +* Обчисліть абсолютне значення за допомогою ([`abs()`](../glossary/?lan=ua&search=abs)) `sin(x)`. Графік стане схожим на траєкторію м'яча, що **стрибає**. + +* Виділіть лише дробову частину від результату [`sin(x)`](../glossary/?lan=ua&search=sin) за допомогою [`fract()`](../glossary/?lan=ua&search=fract). + +* Додайте результати [`sin(x)`](../glossary/?lan=ua&search=sin), округлені в більшу ([`ceil()`](../glossary/?lan=ua&search=ceil)) та меншу сторони ([`floor()`](../glossary/?lan=ua&search=floor)), щоб отримати цифрову хвилю зі значеннями 1 і -1. + +### Деякі додаткові корисні функції + +Наприкінці останньої вправи ми представили кілька нових функцій. Настав час поекспериментувати з ними. Спробуйте по черзі розкоментувати та випробувати кожну з них. Ознайомтеся з цими функціями та вивчіть, як вони поводяться. Я знаю, вам цікаво... навіщо? Швидкий пошук у Google на тему "генеративне мистецтво" підкаже вам. Майте на увазі, що ці функції є нашим парканом. Ми опановуємо рух в одному вимірі, вгору і вниз. Вже зовсім скоро настане час для двох, трьох і чотирьох вимірів! + +![Anthony Mattox (2009)](anthony-mattox-ribbon.jpg) + +
+ +### Просунуті формотворчі функції + +[Golan Levin](http://www.flong.com/) має чудову документацію про складніші формотворчі функції, які є надзвичайно корисними. Перенесення їх на GLSL — це розумний крок, щоб почати створювати власний ресурс з фрагментами коду. + +* Поліноміальні формотворчі функції: [www.flong.com/archive/texts/code/shapers_poly](http://www.flong.com/archive/texts/code/shapers_poly/) + +* Експоненціальні формотворчі функції: [www.flong.com/archive/texts/code/shapers_exp](http://www.flong.com/archive/texts/code/shapers_exp/) + +* Кругові та еліптичні формотворчі функції: [www.flong.com/archive/texts/code/shapers_circ](http://www.flong.com/archive/texts/code/shapers_circ/) + +* Безьє та інші параметричні функції: [www.flong.com/archive/texts/code/shapers_bez](http://www.flong.com/archive/texts/code/shapers_bez/) + +
+ +Подібно до кухарів, які збирають спеції та екзотичні інгредієнти, цифрові художники та креативні кодери приділяють особливу увагу створенню власних формотворчих функцій. + +[Iñigo Quiles](http://www.iquilezles.org/) має чудову колекцію [корисних функцій](http://www.iquilezles.org/www/articles/functions/functions.htm). Прочитавши [цю статтю](http://www.iquilezles.org/www/articles/functions/functions.htm), перегляньте на наступні реалізації цих функцій на GLSL. Зверніть увагу на невеликі зміни, які потрібно було внести. Як-от на "." (крапку) для чисел з рухомою крапкою та заміни деяких *C*-функцій на GLSL аналоги: наприклад, замість `powf()` використовується `pow()`. + +
+ +Для підтримки вашої мотивації, ось елегантний приклад опанування карате формотворчих функцій. Автор [Danguafer](https://www.shadertoy.com/user/Danguafer): + + + +У наступному розділі ми почнемо використовувати нові карате-рухи. Спочатку почнемо зі змішування кольорів, а потім перейдемо до малювання фігур. + +#### Вправа + +Подивіться на наведену нижче таблицю рівнянь, створену за авторства [Kynd](http://www.kynd.info/log/). Подивіться, як він поєднує функції та їхні властивості, щоб контролювати значення між 0.0 та 1.0. Настав час потренуватися, самостійно відтворюючи ці функції. Пам'ятайте, що чим більше ви тренуєтеся, тим краще буде ваше карате. + +![Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)](kynd.png) + +#### До вашого інструментарію + +Ось кілька інструментів, які полегшать візуалізацію цих типів функцій: + +* [GraphToy](http://www.iquilezles.org/apps/graphtoy/): вже згаданий [Iñigo Quilez](http://www.iquilezles.org) створив інструмент для візуалізації GLSL-функцій у WebGL. + +![Iñigo Quilez - GraphToy (2010)](graphtoy.png) + +* [Бібліотека шейдерів LYGIA](https://lygia.xyz/) — бібліотека шейдерів із функцій, які можна легко включити та використати у ваших проєктах. Бібліотека дуже атомарна, створена для зручного перевикористання, продуктивності й гнучкості. Може бути легко додана до будь-яких проєктів та фреймворків. diff --git a/06/README-ua.md b/06/README-ua.md new file mode 100644 index 0000000..151e5b8 --- /dev/null +++ b/06/README-ua.md @@ -0,0 +1,136 @@ +![Paul Klee - Color Chart (1931)](klee.jpg) + +## Кольори + +Раніше у нас не було нагоди поговорити про векторні типи GLSL. Перш ніж рушити далі, важливо дізнатися про них більше. А тема кольорів якраз дуже підходить для цього і буде чудовим шляхом для такого знайомства. + +Якщо ви знайомі з парадигмами об'єктноорієнтованого програмування, то, мабуть, помітили, що ми зверталися до даних у векторах, як до будь-якої звичайної C-подібної `структури`. + +```glsl +vec3 red = vec3(1.0, 0.0, 0.0); +red.x = 1.0; +red.y = 0.0; +red.z = 0.0; +``` + +Визначення кольору за допомогою нотації *x*, *y* і *z* може заплутати й ввести в оману, чи не так? Ось чому існують й інші способи доступу до цієї самої інформації, але під іншими іменами. Значення `.x`, `.y` і `.z` так само можна отримати через `.r`, `.g` і `.b`, а також через `.s`, `.t` і `.p`. (`.s`, `.t` і `.p` зазвичай використовуються для роботи з просторовими координатами текстури, які ми побачимо в наступному розділі.) Крім того, ви також можете отримати доступ до елементів вектора через позицію індексу: `[0]`, `[1]` і `[2]`. + +Наступні рядки показують всі способи доступу до тих самих даних: + +```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; +``` + +Всі ці різні способи посилання на змінні всередині вектора — лише додаткові номенклатури — розроблені позначення, щоб допомогти вам написати чіткіший код. Ця гнучкість, вбудована в мову шейдерів, дає вам можливість почати думати про просторові координати та значення кольорів як про взаємозамінні сутності. + +Ще одна чудова особливість векторних типів у GLSL полягає в тому, що їх властивості можна комбінувати в будь-якому довільному порядку, що спрощує приведення та змішування значень. Ця здатність називається *змішуванням*. + +```glsl +vec3 yellow, magenta, green; + +// Створення жовтого кольору +yellow.rg = vec2(1.0); // Присвоєння 1.0 червоному та зеленому каналам +yellow[2] = 0.0; // Присвоєння 0.0 синьому каналу + +// Створення пурпурового кольору +magenta = yellow.rbg; // Присвоєння каналів зі зміною місць зеленого і синього. rbg замість rgb + +// Створення зеленого кольору +green.rgb = yellow.bgb; // Присвоєння значення синього каналу зі змінної "yellow" червоному і синьому каналам змінної "red" +``` + +### Змішування кольорів + +Тепер, коли ви знаєте, як визначаються кольори, настав час об'єднати ці нові знання з попередніми. У GLSL є дуже корисна функція [`mix()`](../glossary/?lan=ua&search=mix), яка дозволяє змішувати два значення у відсотках. Чи можете ви здогадатися, який саме там діапазон? Так, звісно це значення від 0.0 до 1.0! Ідеально підійде для вас, особливо після довгих годин відпрацювання рухів карате з парканом – настав час скористатися ними! + +![](mix-f.jpg) + +Перевірте наступний код у рядку 18 і подивіться, як ми використовуємо абсолютні значення синусу на основі часу, щоб змішати значення кольорів у змінних `colorA` та `colorB`. + +
+ +Покажіть свої навички: + +* Зробіть експресивний перехід між кольорами. Подумайте про якусь емоцію. Який колір здається найбільш характерним для неї? Як він з'являється? Як зникає? Подумайте про іншу емоцію та відповідний їй колір. Змініть початковий і кінцевий кольори у коді вище, відповідно цим емоціям. Потім анімуйте перехід за допомогою формотворчих функцій. Robert Penner розробив серію популярних функцій для комп'ютерної анімації, відомих як [функції пом'якшення](http://easings.net/). Ви можете використати [цей приклад](../edit.php#06/easing.frag) для дослідження та натхнення, але найкращий результат ви здобудете, налаштувавши свої власні переходи. + +### Гра з градієнтами + +Функція [`mix()`](../glossary/?lan=ua&search=mix) може запропонувати більше. Замість одного `float` значення ми можемо передати компонентний тип змінної, однаковий для перших двох аргументів, у нашому випадку це `vec3`. Таким чином ми отримуємо контроль над відсотками змішування кожного окремого каналу кольорів: `r`, `g` і `b`. + +![](mix-vec.jpg) + +Розгляньте наступний приклад. Як і в прикладах попереднього розділу, ми створюємо нормалізовані координати та використовуємо *x* для візуалізації лінії. Зараз усі канали змінюються по спільному правилу. + +Тепер розкоментуйте рядок 25 і подивіться, що станеться. Потім спробуйте розкоментувати рядки 26 і 27. Пам’ятайте, що лінії візуалізують вагу змішування кожного каналу змінних `colorA` та `colorB`. + +
+ +Ви, напевно, впізнали три функції, які ми використовуємо в рядках 25-27. Пограйте з ними! Настав час дослідити та продемонструвати свої навички з попереднього розділу та створити цікаві градієнти. Спробуйте наступні вправи: + +![Вільям Тернер - Останній рейс "Тімірера" (1838)](turner.jpg) + +* Створіть градієнт, що нагадує захід сонця Вільяма Тернера + +* Анімуйте перехід між сходом і заходом сонця за допомогою `u_time`. + +* Чи можете ви зробити веселку, використовуючи отримані до цього часу знання? + +* Використайте функцію `step()`, щоб створити кольоровий прапор. + +### HSB + +Ми не можемо говорити про колір, не згадавши про колірний простір. Як ви, напевно, знаєте, існують різні способи організації кольорів, окрім червоного, зеленого та синього каналів. + +[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) означає відтінок (Hue), насиченість (Saturation) і яскравість (Brightness або Value) і є більш інтуїтивно зрозумілою організацією кольорів. Прочитайте код функцій `rgb2hsv()` і `hsv2rgb()` у наступному прикладі. + +Зіставляючи `x`-координату на відтінок та `y`-координату на яскравість, ми отримуємо гарний спектр видимих кольорів. Такий просторовий розподіл кольору може бути дуже зручним. Вибір кольору з простору HSB більш інтуїтивний, ніж з RGB. + +
+ +### HSB в полярних координатах + +HSB початково розроблений для представлення в полярних координатах (на основі кута та радіуса) замість декартових координат (на основі x і y). Щоб зіставити нашу функцію HSB з полярними координатами, нам потрібно отримати кут і відстань від центру полотна до піксельної координати. Для цього ми використаємо функцію розрахунку відстані — [`length()`](../glossary/?lan=ua&search=length) і арктангенс — [`atan(y, x)`](../glossary/?lan=ua&search=atan) (GLSL-версія загальновживаної функції `atan2(y, x)`). + +Під час використання векторних і тригонометричних функцій типи `vec2`, `vec3` і `vec4` розглядаються як вектори, навіть якщо вони представляють кольори. Ми почнемо обробляти кольори та вектори однаковим чином. Згодом ви побачите, що ця концептуальна гнучкість дуже розширює ваші можливості. + +**Примітка:** Якщо вам цікаво, то окрім [`length`](../glossary/?lan=ua&search=length) існують й інші геометричні функції, наприклад: [`distance()`](../glossary/?lan=ua&search=distance), [`dot()`](../glossary/?lan=ua&search=dot), [`cross()`](../glossary/?lan=ua&search=cross), [`normalize()`](../glossary/?lan=ua&search=normalize), [`faceforward()`](../glossary/?lan=ua&search=faceforward), [`reflect()`](../glossary/?lan=ua&search=reflect) та [`refract()`](../glossary/?lan=ua&search=refract). Також GLSL має спеціальні векторні функції порівняння, такі як: [`lessThan()`](../glossary/?lan=ua&search=lessThan), [`lessThanEqual()`](../glossary/?lan=ua&search=lessThanEqual), [`greaterThan()`](../glossary/?lan=ua&search=greaterThan), [`greaterThanEqual()`](../glossary/?lan=ua&search=greaterThanEqual), [`equal()`](../glossary/?lan=ua&search=equal) та [`notEqual()`](../glossary/?lan=ua&search=notEqual). + +Отримавши кут і довжину, нам потрібно "нормалізувати" їх значення у діапазоні від 0.0 до 1.0. У рядку 27 [`atan(y, x)`](../glossary/?lan=ua&search=atan) поверне кут у радіанах між -PI та PI (від -3.14 до 3.14). Тому нам потрібно розділити це число на подвійне PI, яке записане у макрос `TWO_PI`, що визначений у верхній частині коду. Це дозволить нам отримати значення від -0.5 до 0.5, які шляхом простого додавання до них значення 0.5 ми змінимо на бажаний діапазон від 0.0 до 1.0. Радіус поверне максимум 0.5 (оскільки ми обчислюємо відстань від центру вікна перегляду), тому нам потрібно подвоїти цей діапазон (множенням на два), щоб отримати максимум 1.0. + +Як бачите, наша гра полягає в перетворенні та масштабуванні значень, які нам потрібні у діапазоні від 0.0 до 1.0. + +
+ +Спробуйте наступні вправи: + +* Змініть приклад з полярними координатами, щоб отримати колірне коло, що обертається, як невелике коло біля екранного курсора в режимі очікування. + +* Використайте функцію формування разом із функцією перетворення кольору з HSB у RGB, щоб розширити область кола з певним відтінком та звузити решту. + +![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg) + +* Якщо ви уважно придивитесь на колірне коло у програмних палітрах кольорів (див. зображення нижче), ви побачите, що вони використовують інший спектр відповідно до колірного простору RYB. Наприклад, колір, напроти червоного повинен бути зеленим, але в нашому прикладі вище це блакитний. Спробуйте змінити код прикладу, щоб отримати таке саме коло, як на наступному зображенні? [Підказка: це чудовий момент для використання функцій формування.] + +![](colorwheel.png) + +* Прочитайте книгу [Джозефа Альберса "Взаємодія кольору"](http://www.goodreads.com/book/show/111113.Interaction_of_Color) і скористайтеся для практики наведеними нижче прикладами шейдерів. + +
+ +#### Примітка про функції та аргументи + +Перш ніж перейти до наступного розділу, зупинімось і трохи перемотаємо назад. Поверніться та погляньте на функції в попередніх прикладах. Ви можете помітити слово `in` перед типом аргументів. Це [*кваліфікатор*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier), і в цьому випадку він вказує, що змінна лише для читання. У наступних прикладах ми побачимо, що також можна визначити аргументи із кваліфікаторами `out` або `inout`. Цей останній, `inout`, концептуально подібний до передачі аргументу за посиланням, що дає нам можливість змінювати передану змінну. + +```glsl +int newFunction( + in vec4 aVec4, // лише для читання + out vec3 aVec3, // лише для запису + inout int aInt // і для читання і для запису +); +``` + +Ви можете не повірити, але тепер у нас є всі необхідні елементи для створення крутих зображень. У наступному розділі ми навчимося комбінувати всі ці трюки, щоб створити геометричні фігури шляхом *змішування* простору. Так-так... *змішування* простору! diff --git a/07/README-ua.md b/07/README-ua.md new file mode 100644 index 0000000..0b029e1 --- /dev/null +++ b/07/README-ua.md @@ -0,0 +1,233 @@ +![Alice Hubbard, Providence, United States, ca. 1892. Photo: Zindman/Freemont.](froebel.jpg) + +## Фігури + +Нарешті! Ми розвивали попередні навички саме для цього моменту! Ви вивчили більшість основ GLSL мови, її типи та функції. Ви знову й знову практикували свої навички у формотворчих функціях та рівняннях. Настав час зібрати все разом. Ви вже готові прийняти цей виклик! У цьому розділі ви дізнаєтесь, як малювати прості фігури за допомогою паралельних обчислень. + +### Прямокутник + +Уявіть, що ми маємо листок паперу у клітинку, як на уроках математики, і наше домашнє завдання — намалювати квадрат. Розмір паперу 10х10, а квадрат має бути 8х8. Що ви будете робити? + +![](grid_paper.jpg) + +Мабуть, ви б розфарбували все, окрім першого й останнього рядків та першого й останнього стовпців, чи не так? + +Як це пов'язано з шейдерами? Кожен маленький квадрат нашої сітки — це один потік (піксель). Кожен квадратик знає своє положення, наче координати на шаховій дошці. У попередніх розділах ми масштабували координати *x* та *y* у канали *червоного* та *зеленого* кольорів й навчилися використовувати вузьку двовимірну територію масштабовану між 0.0 та 1.0. Як за допомогою цього ми можемо намалювати квадрат відцентрований посередині нашого полотна? + +Почнімо з псевдокоду та використання `if`-операторів для просторових координат. Ці принципи надзвичайно схожі на випадок з паперовим варіантом. + +```glsl +if ((X GREATER THAN 1) AND (Y GREATER THAN 1)) // якщо (x більше 1) та (y більше 1) + paint white // фарбуємо білим +else // інакше + paint black // фарбуємо чорним +``` + +Тепер, коли ми маємо краще уявлення про потрібну роботу, замінімо оператор `if` на [`step()`](../glossary/?lan=ua&search=step), а замість використання листка 10x10 використаємо нормалізовані значення між 0.0 і 1.0: + +```glsl +uniform vec2 u_resolution; + +void main(){ + vec2 st = gl_FragCoord.xy / u_resolution.xy; + vec3 color = vec3(0.0); + + // кожен результат поверне 1.0 (білий) або 0.0 (чорний). + float left = step(0.1, st.x); // подібно до (X більше 0.1) + float bottom = step(0.1, st.y); // подібно до (Y більше 0.1) + + // множення left на bottom спрацює як логічний оператор AND. + color = vec3(left * bottom); + + gl_FragColor = vec4(color, 1.0); +} +``` + +Функція [`step()`](../glossary/?lan=ua&search=step) перетворить кожен піксель нижче 0.1 на чорний колір (`vec3(0.0)`), а решту — на білий (`vec3(1.0)`). Множення між `left` і `bottom` працює як логічна операція AND, де обидва значення мають бути рівні 1.0, щоб повернути 1.0. Цей код намалює дві чорні лінії: знизу та зліва. + +![](rect-01.jpg) + +У попередньому коді ми повторюємо одну і ту ж саму дію для обох сторін: лівої та нижньої. Ми можемо зекономити кілька рядків коду, передавши у [`step()`](../glossary/?lan=ua&search=step) одразу два значення, у вигляді вектору, замість одного: + +```glsl +vec2 borders = step(vec2(0.1), st); +float pct = borders.x * borders.y; +``` + +Поки що ми намалювали лише дві межі нашого прямокутника: нижню та ліву. Зробімо інші дві: верхню та праву. Розгляньте наступний код: + +
+ +Розкомментуйте *рядки 21-22* і подивіться, як ми інвертуємо там координати `st` і повторюємо ту саму функцію [`step()`](../glossary/?lan=ua&search=step). Таким чином `vec2(0.0, 0.0)` буде у верхньому правому куті. Це цифровий еквівалент перевороту сторінки з повторенням попередньої процедури. + +![](rect-02.jpg) + +Зверніть увагу, що в *рядках 18 і 22* всі сторони перемножуються разом. Це еквівалентно наступному написанню: + +```glsl +vec2 bl = step(vec2(0.1), st); // нижній-лівий +vec2 tr = step(vec2(0.1), 1.0 - st); // верхніх-правий +color = vec3(bl.x * bl.y * tr.x * tr.y); +``` + +Цікаво правда? Ця техніка базується на використанні [`step()`](../glossary/?lan=ua&search=step), множенні у якості логічної операції та перевороті координат. + +Перш ніж продовжити, спробуйте виконати такі вправи: + +* Змініть розмір і пропорції прямокутника. + +* Поекспериментуйте з тим самим кодом, використовуючи [`smoothstep()`](../glossary/?lan=ua&search=smoothstep) замість [`step()`](../glossary/?lan=ua&search=step). Зауважте, що змінюючи значення, ви можете переходити від розмитих меж до елегантно згладжених країв. + +* Виконайте іншу реалізацію, з використанням [`floor()`](../glossary/?lan=ua&search=floor). + +* Виберіть реалізацію, яка вам найбільше до вподоби, та створіть для неї функцію, яку ви зможете повторно використовувати в майбутньому. Зробіть свою функцію гнучкою та ефективною. + +* Створіть іншу функцію, яка малюватиме просто контур прямокутника. + +* Як можна було б пересувати та розміщувати різні прямокутники на одному полотні? Якщо зрозумієте як це зробити, продемонструйте свої вміння, створивши композицію з прямокутників і кольорів, що нагадує картину [Piet Mondrian](http://en.wikipedia.org/wiki/Piet_Mondrian). + +![Piet Mondrian - Tableau (1921)](mondrian.jpg) + +### Кола + +Легко намалювати квадрати на папері в клітинку та прямокутники за декартовими координатами, але кола вимагають іншого підходу, особливо тому, що нам потрібен "по-піксельний" алгоритм. Одне з рішень полягає в *перетворенні* просторових координат таким чином, щоб ми змогли використовувати функцію [`step()`](../glossary/?lan=ua&search=step) для малювання кола. + +Як? Почнімо з того, що повернемося до уроку математики та паперу у клітинку. Розкриємо циркуль на радіус кола, поставимо його голку в центрі кола, а потім окреслимо окружність кола простим обертанням. + +![](compass.jpg) + +Перекладаючи це на мову шейдера, де кожен квадрат на папері є пікселем, ми маємо *спитати* кожен піксель (або потік), чи знаходиться він усередині кола. Ми робимо це, обчислюючи відстань від пікселя до центру кола. + +![](circle.jpg) + +Є кілька способів розрахувати цю відстань. Найпростіший використовує функцію [`distance()`](../glossary/?lan=ua&search=distance), яка всередині обчислює [`length()`](../glossary/?lan=ua&search=length)-різниці між двома точками. У нашому випадку між координатою пікселя та центром полотна. По своїй суті функція `length()` — це не що інше, як скорочення для [рівняння визначення довжини гіпотенузи](http://en.wikipedia.org/wiki/Hypotenuse), яке використовує квадратний корінь ([`sqrt()`](../glossary/?lan=ua&search=sqrt)). + +![](hypotenuse.png) + +Щоб обчислити відстань до центру полотна ви можете використовувати [`distance()`](../glossary/?lan=ua&search=distance), [`length()`](../glossary/?lan=ua&search=length) або [`sqrt()`](../glossary/?lan=ua&search=sqrt). Наступний код містить ці три функції та той недивний факт, що кожна з них повертає точно такий самий результат. + +* Закоментуйте та розкоментуйте рядки, щоб спробувати різними способами отримати той самий результат. + +
+ +У попередньому прикладі ми переводимо відстань від центру полотна у яскравість кольору пікселя. Чим ближче піксель до центру, тим менше (темніше) значення він має. Зауважте, що значення не стають надто високими, оскільки максимальна відстань від центру (`vec2(0.5, 0.5)`) ледве перевищує значення 0.5. Подивіться на зображення і подумайте: + +* Який висновок ви можете з цього зробити? + +* Як ми можемо використати це, щоб намалювати коло? + +* Змініть наведений вище код, щоб вмістити весь круговий градієнт всередині полотна. + +### Поле відстаней + +Наведений вище приклад можна розглянути як карту висот, де темніший колір означає вищу позицію. В такому разі цей круговий градієнт буде картою конуса. Уявіть себе на вершині цього конуса. Відстань по горизонталі до краю конуса, в будь-якому напрямку, дорівнює 0.5. Вибираючи, на якій висоті "зрізати" конус, ви отримаєте більший чи менший діаметр кругової поверхні. + +![](distance-field.jpg) + +По суті ми інтерпретуємо простір на основі його відстані до центру для того, щоб робити таким чином фігури. Ця техніка відома як "поле відстаней" і використовується різними шляхами, від контурів шрифтів до 3D-графіки. + +Спробуйте наступні вправи: + +* Використовуйте [`step()`](../glossary/?lan=ua&search=step), щоб перетворити значення більші за 0.5 у білий колір, а все, що менше 0.0 — у чорний. + +* Змініть місцями кольори фону та переднього плану. + +* Використовуючи [`smoothstep()`](../glossary/?lan=ua&search=smoothstep) та експериментуючи з різними значеннями, отримайте гарний плавний край для вашого кола. + +* Для найбільш вдалої вашої реалізації створіть функцію, яку ви зможете повторно використовувати в майбутньому. + +* Додайте колу колір. + +* Чи зможете ви анімувати своє коло, щоб воно збільшувалося та зменшувалося, імітуючи серцебиття? Ви можете отримати натхнення з анімації у попередньому розділі. + +* А як щодо переміщення кола? Чи зможете ви перемістити та розташувати на полотні кілька різних кіл? + +* Що станеться, якщо скомбінувати поля відстаней за допомогою різних функцій та операцій? + +```glsl +pct = distance(st, vec2(0.4)) + distance(st, vec2(0.6)); +pct = distance(st, vec2(0.4)) * distance(st, vec2(0.6)); +pct = min(distance(st, vec2(0.4)),distance(st, vec2(0.6))); +pct = max(distance(st, vec2(0.4)),distance(st, vec2(0.6))); +pct = pow(distance(st, vec2(0.4)),distance(st, vec2(0.6))); +``` + +* Створіть три композиції за допомоги цієї техніки. Ще краще, якщо вони будуть анімовані! + +#### Для вашого інструментарію + +З точки зору обчислювальної потужності, функція [`sqrt()`](../glossary/?lan=ua&search=sqrt) і всі функції, які від неї залежать, можуть бути досить ресурсовитратними. Ось ще один спосіб для створення кругового поля відстаней за допомогою функції [`dot()`](../glossary/?lan=ua&search=dot). + +
+ +### Корисні властивості поля відстаней + +![Zen garden](zen-garden.jpg) + +Поля відстаней можна використовувати для малювання майже всього. Очевидно, що чим складнішою є форма, тим складнішим буде її рівняння. Але як тільки у вас є формула для створення поля відстаней певної форми, її дуже легко комбінувати та/або застосовувати до неї ефекти. Наприклад, згладження країв або численні контури. Через це поля відстаней популярні у цифровому зображенні шрифтів, наприклад [Mapbox GL Labels](https://blog.mapbox.com/drawing-text-with-signed-distance-fields-in-mapbox-gl-b0933af6f817), [Material Design Fonts](http://mattdesl.svbtle.com/material-design-on-the-gpu) (автор: [Matt DesLauriers](https://twitter.com/mattdesl)) та [iPhone 3D Programming, O’Reilly (див. розділ 7)](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921). + +Розгляньте наступний код: + +
+ +Ми починаємо з переміщення відліку системи координат у центр. Звужуємо її вдвічі, щоб вона вміщувала в себе значення позиції між -1.0 та 1.0. Також у *рядку 24* ми візуалізуємо значення поля відстаней за допомогою функції [`fract()`](../glossary/?lan=ua&search=fract), що покаже малюнок форми, який воно створює. Контур поля відстаней повторюється знову і знову, як кільця в саду дзен. + +Подивімось на формулу поля відстаней у *рядку 19*. Тут ми обчислюємо відстань до позиції у точці `(.3, .3)` (або `vec3(.3)`) в усіх чотирьох квадрантах (саме для цього було використано [`abs()`](../glossary/?lan=ua&search=abs)). + +Якщо ви розкоментуєте *рядок 20*, то помітите, що ми об'єднуємо відстані до цих чотирьох точок за допомогою функції [`min()`](../glossary/?lan=ua&search=min) до нуля. У результаті виходить новий цікавий візерунок. + +Тепер спробуйте розкоментувати *рядок 21*. Тут ми робимо те саме, але використовуємо функцію [`max()`](../glossary/?lan=ua&search=max). В результаті вийде прямокутник із закругленими кутами. Зверніть увагу, що кільця поля відстаней стають більш гладкими, чим далі вони віддаляються від центру. + +Нарешті, по черзі розкоментуйте *рядки з 27 по 29*, щоб побачити та зрозуміти різні варіанти шаблонів використання поля відстаней. + +### Фігури у полярних координатах + +![Robert Mangold - Untitled (2008)](mangold.jpg) + +У розділі про колір ми зіставляли декартові координати з полярними координатами, обчислюючи *радіус* і *кут* кожного пікселя за такою формулою: + +```glsl +vec2 pos = vec2(0.5) - st; +float r = length(pos) * 2.0; +float a = atan(pos.y, pos.x); +``` + +На початку розділу ми використали частину цієї формули, щоб намалювати коло. Ми обчислили відстань до центру за допомогою функції [`length()`](../glossary/?lan=ua&search=length). Тепер, знаючи про поля відстаней, ми можемо навчитися малювати фігури за допомогою полярних координат іншим способом. + +Ця техніка трохи обмежена, але дуже проста. Вона полягає в отримання різних форм, змінюючи радіус кола залежно від кута. Як це працює? Звісно ж за допомогою функцій формування! + +Нижче ви знайдете функції для отримання значень у декартовій системі координат та зображення їх на графіку. А ще нижче інший приклад з тими ж самими функціями, але вже для полярних координат (між *рядками 21 і 25*). Розкоментуйте ці функції одну за одною та звертайте увагу на співвідношення між обома системами координат. + +
+ +
+ +Спробуйте: + +* Анімувати ці форми. +* Комбінувати різні формотворчі функції, щоб *вирізати отвори* у формі й зробити подобу квітів, сніжинок та шестерень. +* Використати функцію `plot()` з розділу [Формотворчих функцій](/05/?lan=ua), щоб намалювати лише контур. + +### Сила комбінацій + +Ми навчилися модулювати радіус кола відповідно до кута за допомогою функції [`atan()`](../glossary/?lan=ua&search=atan) для малювання різних фігур. Тепер ми можемо навчитися використовувати `atan()` з полями відстаней та застосувати всі трюки та ефекти, можливі з цими полями. + +Наступний трюк використовує кількість ребер багатокутника для побудови поля відстаней за допомогою полярних координат. Перегляньте [цей код](http://thndl.com/square-shaped-shaders.html) від [Andrew Baldwin](https://twitter.com/baldand). + +
+ +* Використовуючи цей приклад, створіть функцію, яка приймає положення та кількість кутів потрібного багатокутника й повертає значення поля відстаней. + +* Змішайте поля відстаней за допомогою функції [`min()`](../glossary/?lan=ua&search=min) та [`max()`](../glossary/?lan=ua&search=max). + +* Виберіть геометричний логотип і відтворіть його за допомогою полей відстані. + +Щиро вітаю! Ви пройшли через складну частину! Зробіть перерву й дайте цим концепціям засвоїтись. Так, малювати прості фігури десь у Processing легко, але не тут. У світі шейдерів малювання фігур хитромудра справа, і адаптація до цієї нової парадигми кодування може бути виснажливою. + +У кінці цього розділу ви знайдете посилання на [Колоду PixelSpirit](https://patriciogonzalezvivo.github.io/PixelSpiritDeck/). Ця колода карт допоможе вам вивчити нові функції SDF, скомпонувати їх та використати у ваших шейдерах. Колода має прогресивну криву навчання. Можете брати по одній карті на день й опрацьовувати її, щоб підштовхнути та випробувати свої навички. + +Тепер, коли ви знаєте, як малювати фігури, я впевнений, що у вас у голові з’являться нові ідеї. У наступному розділі ви дізнаєтесь, як переміщувати, обертати та масштабувати фігури. Це дозволить вам складати композиції! diff --git a/08/README-ua.md b/08/README-ua.md new file mode 100644 index 0000000..a5971e8 --- /dev/null +++ b/08/README-ua.md @@ -0,0 +1,105 @@ +## Двомірні матриці + + + +### Переміщення + +У попередньому розділі ми навчилися створювати деякі фігури — хитрість переміщення цих фігур полягає в тому, щоб перемістити саму систему координат. Ми можемо досягти цього, просто додавши вектор до змінної ```st```, яка містить розташування кожного фрагмента. Це спричиняє зміщення у просторі усієї системи координат. + +![](translate.jpg) + +Це легше побачити, ніж пояснити, тому дивіться самі: + +* Розкоментуйте рядок 35 в коді нижче, щоб побачити, як рухається сам простір. + +
+ +Тепер спробуйте наступне: + +* Використовуючи змінну ```u_time``` разом із функціями формування, надайде хрестику рух у новому цікавому напрямку. Знайдіть конкретний варіант руху, яка вас цікавить, і спробуйте змусити хрест рухатися таким же чином. Спробуйте для початку щось із "реального світу" — це можуть бути хвилеподібні рухи, коливання маятника, м’яч, що підстрибує, прискорення як в автомобіля чи зупинка велосипеда. + +### Обертання + +Щоб обертати об'єкти, нам також потрібно рухати всю систему простору. Для цього ми будемо використовувати [матрицю](http://en.wikipedia.org/wiki/Matrix_%28mathematics%29). Матриця — це організований набір чисел у стовпцях і рядках. Вектори помножуються на матриці відповідно до певних правил, щоб змінити значення вектора визначеним чином. + +[![Wikipedia entry for Matrix (mathematics) ](matrixes.png)](https://en.wikipedia.org/wiki/Matrix) + +GLSL має вбудовану підтримку дво-, три- та чотиривимірних матриць: [```mat2```](../glossary/?lan=ua&search=mat2) (2x2), [```mat3```](../glossary/?lan=ua&search=mat3) (3x3) та [```mat4```](../glossary/?lan=ua&search=mat4) (4x4). GLSL також підтримує множення матриць (```*```) та специфічну для матриці функцію ([```matrixCompMult()```](../glossary/?lan=ua&search=matrixCompMult)). + +Можна побудувати різні матриці для отримання певної поведінки. Наприклад, ми можемо використати матрицю для переміщення вектора: + +![](3dtransmat.png) + +Що ще цікавіше, ми можемо використати матрицю для обертання системи координат: + +![](rotmat.png) + +Подивіться на наведений нижче код функції, яка створює двовимірну матрицю обертання. Ця функція відповідає наведеній вище [формулі](http://en.wikipedia.org/wiki/Rotation_matrix) для обертання координат навколо точки ```vec2(0.0)```. + +```glsl +mat2 rotate2d(float _angle) { + return mat2( + cos(_angle), -sin(_angle), + sin(_angle), cos(_angle) + ); +} +``` + +Судячи з того, як ми малювали фігури, це не зовсім те, що нам потрібно. Наша форма хреста намальована в центрі полотна, що відповідає позиції ```vec2(0.5)```. Отже, перед тим, як обертати простір, нам потрібно перемістити фігуру із `центру` до координати ```vec2(0.0)```, повернути простір, а потім, нарешті, перемістити його назад у початкове положення. + +![](rotate.jpg) + +Це можна запрограмувати таким чином: + +
+ +Спробуйте наступні вправи: + +* Розкоментуйте рядок 45 із коду вище та зверніть увагу на те, що відбувається. + +* Закоментуйте зміщення координат до та після повороту, у рядках 38 та 42, спостерігаючи за наслідками. + +* Використайте обертання, щоб покращити анімацію, яку ви моделювали під час вправи з переміщенням. + +### Масштаб + +Ми побачили, як матриці використовуються для переміщення та обертання об'єктів у просторі. А точніше, як змінювати системи координат для обертання та переміщення об'єктів. Якщо ви користувалися програмним забезпеченням для 3D-моделювання або функціями `push` та `pop` для матриць у Processing, то знаєте, що матриці також можна використовувати й для масштабування розміру об'єктів. + +![](scale.png) + +Дотримуючись попередньої формули, ми можемо створити двомірну матрицю масштабування: + +```glsl +mat2 scale(vec2 _scale) { + return mat2( + _scale.x, 0.0, + 0.0, _scale.y + ); +} +``` + +
+ +Спробуйте виконати наступні вправи, щоб глибше зрозуміти, як це працює. + +* Розкомментуйте рядок 42 із коду вище, щоб побачити масштабування просторових координат. + +* Подивіться, що відбудеться, коли ви закоментуєте переміщення координат до та після масштабування в рядках 37 та 39. + +* Спробуйте поєднати матрицю обертання разом із матрицею масштабування. Майте на увазі, що порядок має значення. Спочатку помножте на матрицю, а потім результат помножте на вектори. + +* Тепер, коли ви знаєте, як малювати різні фігури, переміщувати, обертати та масштабувати їх, настав час створити гарну композицію. Спроєктуйте та створіть фейковий [UI або HUD](https://www.pinterest.com/patriciogonzv/huds/). HUD (heads up display) — мається на увазі розташування інформації на прозорих поверхнях або дисплеях. Для натхнення та довідки, можете використати наступний ShaderToy-приклад від [Ndel](https://www.shadertoy.com/user/ndel). + + + +### Інше використання матриць: колір у просторі YUV + +[YUV](http://en.wikipedia.org/wiki/YUV) — це колірний простір, який використовується для аналогового кодування фотографій та відео, яке враховує діапазон людського сприйняття для зменшення пропускної здатності компонентів колірності. + +Наступний код є цікавою можливістю використовувати матричні операції в GLSL для перетворення кольорів з одного простору в інший. + +
+ +Як бачите, ми розглядаємо кольори як вектори, перемножуючи їх на матриці. Таким чином ми "переміщуємо" значення кольорів. + +У цьому розділі ми навчилися використовувати матричні перетворення для переміщення, обертання та масштабування векторів. Ці трансформації будуть корисними для створення композицій із фігур, про які ми дізналися із попереднього розділу. У наступному розділі ми застосуємо всі здобуті знання для створення красивих процедурних візерунків. Ви побачите, що програмування повторень та варіацій може бути захопливою діяльністю. diff --git a/09/README-ua.md b/09/README-ua.md new file mode 100644 index 0000000..9d68e00 --- /dev/null +++ b/09/README-ua.md @@ -0,0 +1,115 @@ +## Патерни + +Шейдерні програми виконуються попіксельно, тому незалежно від того скільки ви повторюєте якусь фігуру, кількість обчислень залишається незмінною. Це означає, що фрагментні шейдери добре підходять для створення патернів — візерунків, що повторюються. + +[![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg)](../edit.php#09/dots5.frag) + +У цьому розділі ми збираємося застосувати дещо з попереднього матеріалу, щоб продублювати його кілька разів на полотні. Як і в попередніх розділах, наша стратегія базуватиметься на перемноженні просторових координат з діапазоном від 0.0 до 1.0, так щоб фігури, які ми малюватимемо між значеннями 0.0 та 1.0, повторювалися, утворюючи сітку. + +*"Сітка забезпечує структуру, в межах якої людській інтуїції та винахідливості зручно орієнтуватись. У хаосі природи візерунки створюють контраст і обіцяють порядок. Від ранніх візерунків на кераміці до геометричної мозаїки в римських лазнях люди давно використовують сітки, щоб прикрасити своє життя за допомогою декору."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/) + +Спочатку згадаймо функцію [```fract()```](../glossary/?lan=ua&search=fract). Вона повертає дробову частину числа, роблячи ```fract()``` модулем одиниці ([```mod(x,1.0)```](../glossary/?lan=ua&search=mod)). Іншими словами, [```fract()```](../glossary/?lan=ua&search=fract) повертає число після коми з рухомою крапкою. Наша змінна з нормалізованою системою координат (```st```) уже змінюється в межах діапазону від 0.0 до 1.0, тому немає сенсу робити щось на наступний зразок: + +```glsl +void main() { + vec2 st = gl_FragCoord.xy / u_resolution; + vec3 color = vec3(0.0); + st = fract(st); + color = vec3(st, 0.0); + gl_FragColor = vec4(color, 1.0); +} +``` + +Але якщо ми збільшимо масштаб нормалізованої системи координат, скажімо, втричі до 3.0, то отримаємо три послідовності лінійної інтерполяції одиничного розміру. Перша між 0.0 та 1.0, друга між 1.0 та 2.0 й третя між 2.0 та 3.0. + +
+ +Настав час намалювати щось у кожному підпросторі, розкоментувавши рядок 27. Оскільки обидві вісі x та y помножуються на однакове значення, то співвідношення сторін простору не змінюється. Відповідно форми також не матимуть викривлень та будуть такими, як очікувалося. + +Для глибшого розуміння, спробуйте виконати деякі з наведених нижче вправ: + +* Помножте просторові координати на різні числа. Спробуйте різні значення з рухомою крапкою, а також різні значення для x та y. + +* Зробіть, для цього трюку з плиткою, функцію для повторного використання. + +* Розділіть простір на 3 рядки та 3 стовпці. Знайдіть спосіб дізнатися, у якому стовпці та рядку знаходиться потік, і в залежності від цього змінити фігуру, що буде малюватися. Спробуйте зробити композицію з гри у хрестики-нулики. + +### Застосування матриць всередині патернів + +Оскільки кожен підрозділ або комірка є зменшеною версією нормалізованої системи координат, яку ми використовували раніше, ми можемо застосувати до них такі ж самі матричні перетворення для переміщення, обертання та масштабування. + +
+ +* Подумайте про цікаві способи анімації цього візерунка. Подумайте про анімацію кольорів, форм і рухів. Зробіть три різні анімації. + +* Відтворіть складніші візерунки, компонуючи різні форми. + +[![](diamondtiles-long.png)](../edit.php#09/diamondtiles.frag) + +* Комбінуйте різні шари патернів, щоб створити власні [орнаменти шотландського тартану](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns). + +[![Векторний візерунок шотландського тартану від Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076) + +### Патерни зі зміщенням + +Припустимо, ми хочемо імітувати цегляну стіну. Розглядаючи стіну, ви можете побачити, що кожен другий її ряд зміщений на півцеглини по вісі x. Як можна це зробити? + +![](brick.jpg) + +Першим кроком потрібно визначити, чи є потік поточного рядка парним чи непарним, що дасть нам розуміння чи потрібно робити зміщення у цьому рядку. Для цього ми використаємо функцію модуля [```mod()```](../glossary/?lan=ua&search=mod) зі значенням ```2.0``` для другого параметру, а потім перевіримо, чи результат буде меншим від ``` 1.0``` чи ні. Подивіться на наступну формулу та розкоментуйте два останні рядки. + +
+ +Як бачите, ми можемо використати [тернарний оператор](https://en.wikipedia.org/wiki/%3F:), щоб перевірити, чи остача від ділення по модулю [```mod()```](../glossary/?lan=ua&search=mod) на ```2.0``` менше за ```1.0```, що означатиме другий рядок. Або ми можемо аналогічно використати функцію [```step()```](../glossary/?lan=ua&search=step), яка виконає ту саму операцію, але швидше. Чому? Хоча важко напевно знати, як кожна графічна карта оптимізує та компілює код, але можна з упевненістю припустити, що вбудовані функції працюють швидше. За кожної можливості надавайте перевагу використанню вбудованих функцій! + +Тепер, маючи формулу визначення непарних чисел, ми можемо застосувати зміщення до непарних рядків, щоб надати нашим плиткам *ефект цегли*. У рядку 14 наступного коду ми використовуємо функцію для "виявлення" непарних рядків та зсуваємо їх на половину одиниці по вісі ```x```. Зауважте, що для парних рядків результатом нашої функції буде ```0.0```, що при множенні на значення для зміщення в ```0.5``` залишається тим самим ```0.0```. Але в непарних рядках ми отримуємо результат нашої функції як ```1.0```, що при множенні на зсув ```0.5```, переміщує вісь ```x``` системи координат на ```0.5```. + +Тепер спробуйте розкоментувати рядок 32 — це розтягне співвідношення сторін системи координат, щоб імітувати її до співвідношення "сучасної цегли". Розкоментувавши рядок 40, ви зможете побачити, як виглядає система координат, відображена у червоний та зелений кольори. + +
+ +* Спробуйте анімувати цей приклад, змінюючи зміщення відповідно до часу. + +* Зробіть ще одну анімацію, у якій парні ряди рухаються ліворуч, а непарні — праворуч. + +* Чи можете ви повторити цей ефект, але зі стовпцями? + +* Спробуйте скомбінувати зсуви на вісі ```x``` та ```y```, щоб отримати щось на зразок наступного: + + + +## Плитка Труше + +Тепер, коли ми навчилися визначати, чи знаходиться наша комірка в парному чи непарному рядку чи стовпці, можна повторно використовувати один елемент дизайну залежно від його положення. Розглянемо випадок [плитки Труше](http://en.wikipedia.org/wiki/Truchet_tiles), де один елемент дизайну може бути представлено чотирма різними способами: + +![](truchet-00.png) + +Змінюючи малюнок у плитках, можна побудувати нескінченний набір складних зображень. + +![](truchet-01.png) + +Зверніть увагу на функцію ```rotateTilePattern()```, яка розбиває простір на чотири комірки та призначає кожній кут повороту. + +
+ +* Закоментуйте, розкоментуйте та продублюйте рядки з 69 по 72, щоб скомпонувати нові зображення. + +* Змініть чорно-білий трикутник на інший елемент, наприклад: півколо, повернуті квадрати або лінії. + +* Запрограмуйте інші патерни, де елементи обернені відповідно до їхнього положення. + +* Створіть патерн, який змінює інші свої властивості відповідно до положення елементів. + +* Подумайте про щось інше, не обов'язково про патерни, де ви можете застосувати принципи з цього розділу. Наприклад, [гексаграми "I Ching"](https://en.wikipedia.org/wiki/Hexagram_(I_Ching)): + + + +## Створення власних правил + +Створення процедурних патернів — це розумова вправа з пошуку мінімальної кількості елементів для багаторазово використання в просторі. Ця давня практика. Ми, як біологічний вид, використовуємо сітки та візерунки для декорування текстилю, підлоги та границь об'єктів протягом тривалого часу: від візерунків декоративних звивистих ліній (меандрів) стародавньої Греції до китайських решітчастих патернів. Насолода від повторення та варіацій захоплює нашу уяву. Знайдіть час, щоб переглянути [декоративні](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [візерунки](https://www.pinterest.com/patriciogonzv/paterns/) та подивитися як художники з дизайнерами балансуються між передбачуваністю порядку й несподіваністю варіацій та хаосу. Від арабських геометричних візерунків до розкішних африканських зображень на тканинах пролягає цілий всесвіт візерунків для натхнення та пізнання. + +[![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png)](https://archive.org/details/handbookoforname00meyeuoft/page/10/mode/2up) + +Цією главою ми закінчуємо розділ про алгоритмічне малювання. У наступних розділах ми дізнаємося, як привносити у наші шейдери трохи ентропії та створювати генеративні дизайни. diff --git a/10/README-ua.md b/10/README-ua.md new file mode 100644 index 0000000..243096f --- /dev/null +++ b/10/README-ua.md @@ -0,0 +1,92 @@ +# Генеративний дизайн + +Не дивно, що після стількох повторень наших карате-рухів і впорядкованості, автор змушений внести трохи хаосу. + +## Випадковість + +[![Ryoji Ikeda - тестовий патерн (2008) ](ryoji-ikeda.jpg)](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set) + +Випадковість є максимальним проявом ентропії. Як ми можемо створити випадковість у, здавалося б, передбачуваному та суворому програмному середовищі? + +Почнемо з аналізу наступної функції: + +
+ +Значення [```sin()```](../glossary/?lan=ua&search=sin) коливаються між ```-1.0``` до ```1.0```. Вище ми витягуємо дробову частину цієї синусоїди, "обрізаючи" та підіймаючи діапазон її негативних значень до позитивних в межах від ```0.0``` до ```1.0```. Цей ефект можна використати, щоб отримати деякі псевдовипадкові значення, "розбивши" синусоїду на менші частини. Як? За допомогою помноження результату [```sin(x)```](../glossary/?lan=ua&search=sin) на більші числа. Поверніться до прикладу і почніть додавати нулі до цілої частини множника. + +Коли дійдете до ```100000.0``` і рівняння виглядатиме як "```y = fract(sin(x) * 100000.0)```", то більше не зможете розрізнити синусоїду. Деталізація дробової частини спотворила плавний потік синусоїди, перетворивши її у псевдовипадковий хаос. + +## Управління хаосом + +Використання випадковості може бути важкою справою. Інколи вона буває занадто хаотичною, а часом недостатньо випадковою. Подивіться на наступний графік. В ньому ми використовуємо функцію ```rand()```, яка реалізована так само як ми описали вище. + +Придивившись ближче, ви можете побачити гребні у [```sin()```](../glossary/?lan=ua&search=sin)-хвилі по x-вісі біля значень ```-1.5707``` та ```1.5707```. Б'юся об заклад, тепер ви розумієте чому — саме там відбувається максимум і мінімум синусоїди. + +Якщо уважно розглянути цей розподіл псевдовипадкових значень, то ви також помітите, що навколо середини y-вісі спостерігається більша концентрація значень, аніж на її краях. + +
+ +Свого часу [Pixelero](https://pixelero.wordpress.com) опублікував [цікаву статтю про випадковий розподіл](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/). Я додав декілька його прикладів до попереднього графіка, щоб ви могли пограти з ними та побачити, як можна змінити розподіл значень. Розкоментуйте рядки та подивіться, що станеться. + +Читаючи [статтю Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/), важливо мати на увазі, що наша функція ```rand()``` є детерміновано випадковою, інакше кажучи, псевдовипадковою. Це означає, що, наприклад, ```rand(1.)``` завжди повертатиме одне й те саме значення. [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) у своїй статті посилається на недетерміновану ActionScript-функцію ```Math.random()```, кожен виклик якої повертає різні значення. + +## Двомірна випадковість + +Тепер, коли ми краще розуміємо випадковість, настав час застосувати її у двомірному просторі, до осей ```x``` та ```y```. Для цього нам потрібен спосіб перетворити двовимірний вектор в одновимірне значення з рухомою крапкою. Існують різні способи зробити це, але функція [```dot()```](../glossary/?lan=ua&search=dot) особливо корисна в цьому випадку. Вона повертає єдине float-значення між ```0.0``` і ```1.0``` залежно від розташування двох векторів. + +
+ +Подивіться на рядки з 13 по 15 і зверніть увагу на те, як ми порівнюємо ```vec2 st``` з іншим двовимірним вектором (```vec2(12.9898, 78.233)```). + +* Спробуйте змінити значення в рядках 14 і 15. Подивіться як змінюється зображення та поміркуйте, чого ми можемо з цього навчитися. + +* Застосуйте цю функцію з отримання випадкових значень до взаємодії зі змінною для курсора миші (```u_mouse```) та часом (```u_time```), щоб краще зрозуміти, як вона працює. + +## Використання хаосу + +Випадкові значення у двовимірному зображенні дуже схожі на телевізійний шум, чи не так? Це жорсткий та занадто сирий матеріал для створення зображень. Навчімось же ним користуватися. + +Першим кроком застосуємо до нього сітку. За допомогою функції [```floor()```](../glossary/?lan=ua&search=floor) ми згенеруємо таблицю з цілочисельною кількістю клітинок. Подивіться на наступний код, особливо на рядки 22 і 23: + +
+ +Після збільшення простору у 10 разів (рядок 21), ми відокремлюємо цілі числа координат від дробової частини (рядок 22). Ми знайомі з цією операцією, тому що вже використовували її для поділу простору на менші комірки, що йдуть від ```0.0``` до ```1.0```. Отримавши ціле значення координати, ми виокремлюємо загальне значення кількості пікселів, необхідних для побудови одної комірки. Далі ми можемо використовувати це ціле число, щоб отримати випадкове значення для цієї області. Оскільки наша випадкова функція є детермінованою, то випадкове значення, що повертається, буде постійним для всіх пікселів у цій клітинці. + +Розкомментуйте рядок 29, щоб побачити, що ми зберігаємо дробову частину координати (рядок 23), тому ми все ще можемо використовувати її як нормовану систему координат для кожної окремої клітинки. + +Поєднання цілої та дробової частин координати дозволить змішувати варіацію та порядок. + +Подивіться на наступну GLSL-версію відомого генератора лабіринтів [```10 PRINT CHR$(205.5 + RND(1)); : GOTO 10```](https://10print.org/). + +
+ +Тут я використовую випадкові значення комірок для малювання лінії в одному чи іншому напрямку за допомогою функції ```truchetPattern()``` із попереднього розділу (рядки 41-47). + +Розкоментувавши блок рядків з 50 по 53, ви можете отримати інший цікавий патерн, або анімувати його, розкоментувавши рядки 35 і 36. + +## Майстер випадковості + +[Ryoji Ikeda](http://www.ryojiikeda.com/) — японський електронний композитор і візуальний художник, який опанував використання випадковості. Важко залишитись байдужим та не стати загіпнозованим його роботами. При використанні випадковості у своїх аудіо- та візуальних середовищах він не перетинає межу дратівливого хаосу та відзеркалює складність нашої технологічної культури. + + + +Перегляньте роботу [Ikeda](http://www.ryojiikeda.com/) і спробуйте виконати такі вправи: + +* Створіть ряди рухомих у протилежних напрямках комірок із випадковими значеннями. Показуйте лише клітинки найбільш яскравими значеннями. Зробіть так, щоб швидкість рядків з часом змінювалася: + + + +* Так само зробіть кілька рядів, але кожен з різною швидкістю та напрямком. Зробіть, щоб кількість видимих клітинок залежали від положення вказівника миші: + + + +* Створіть інші цікаві ефекти: + + + +Використовування випадковості для отримання естетичних результатів може бути проблематичним, особливо якщо ви хочете зробити симуляції, що виглядатимуть природно. Випадковість занадто хаотична й дуже мало речей виглядають **`рандомно`** у реальному житті. Якщо поглянути на патерн дощу або біржову діаграму, які є досить випадковими, то вони зовсім не схожі на ту модель випадковості, яку ми створили на початку цього розділу. В чому причина? Ну що ж, просто ці випадкові значення не мають ніякої кореляції між собою, а більшість природних шаблонів мають певну "пам'ять" про свій попередній стан. + +У наступному розділі ми дізнаємося про шум, плавний і *природний* спосіб створення обчислювального хаосу. diff --git a/11/README-ua.md b/11/README-ua.md new file mode 100644 index 0000000..0e692fa --- /dev/null +++ b/11/README-ua.md @@ -0,0 +1,220 @@ + +![NASA / WMAP science team](mcb.jpg) + +## Шум + +Час взяти перерву! Ми гралися з функціями випадкових значень, що нагадують телевізійний білий шум, наші голови все ще кружляють від думок про шейдери та втомились очі. Час піти на прогулянку! + +Ми відчуваємо повітря на нашій шкірі, сонце на обличчі. Світ такий яскравий та насичений. Кольори, текстури, звуки. На прогулянці ми не можемо не помітити поверхню доріг, каменів, дерев та хмар. + +![](texture-00.jpg) +![](texture-01.jpg) +![](texture-02.jpg) +![](texture-03.jpg) +![](texture-04.jpg) +![](texture-05.jpg) +![](texture-06.jpg) + +Непередбачуваність цих текстур можна назвати "випадковою", але вони не схожі на той рандом, з якими ми грали раніше. "Реальний світ" — це дуже багате й складне місце! Як ми можемо апроксимувати цю варіативність за допомогою обчислень? + +Це питання [Кен Перлін](https://mrl.nyu.edu/~perlin/) намагався вирішити на початку 1980-х років, коли йому доручили створити більш реалістичні текстури для фільму "Трон". У результаті він придумав елегантний алгоритм для генерації шуму за який потім отримав своєрідний *Оскар*. Нічого особливого) + +![Disney - Tron (1982)](tron.jpg) + +Нижче наведено не класичний алгоритм шуму Перліна, але це хороша відправна точка для розуміння того, як генерувати шум. + +
+ +У цих рядках ми робимо щось подібне до того, що робили в попередньому розділі. Ми ділимо безперервне число з рухомою крапкою (`x`) на цілу (`i`) і дробову (`f`) складові. Для отримання цілої частини "**`i`**" ми використовуємо [```floor()```](../glossary/lan=ua&?search=floor), а для дробової частини "**`f`**" — [```fract()```](../glossary/lan=ua&?search=fract). Потім ми застосовуємо ```rand()``` до цілої частини "**`x`**", що дає унікальне випадкове значення для кожного цілого числа. + +Також ви бачите два закоментовані рядки. Перший інтерполює кожне випадкове значення лінійним чином. + +```glsl +y = mix(rand(i), rand(i + 1.0), f); +``` + +Розкоментуйте цей рядок, щоб побачити його роботу. Ми використовуємо дробове значення **`f`**, отримане після [```fract()```](../glossary/lan=ua&?search=fract), щоб за допомогою [```mix()```](../glossary/lan=ua&?search=mix) зміксувати два випадкових значення. + +Ми вже знаємо, що можемо використати краще рішення, ніж лінійна інтерполяція, чи не так? +Розкоментуйте наступний рядок, щоб застосувати інтерполяцію [```smoothstep()```](../glossary/lan=ua&?search=smoothstep). + +```glsl +y = mix(rand(i), rand(i + 1.0), smoothstep(0., 1. ,f)); +``` + +Зверніть увагу на те, як перехід між вершинами стає плавним. У деяких реалізаціях шуму програмісти віддають перевагу створенню власних кубічних кривих (наприклад, наступна формула) замість використання [```smoothstep()```](../glossary/lan=ua&?search=smoothstep). + +```glsl +float u = f * f * (3.0 - 2.0 * f ); // варіант кубічної кривої +y = mix(rand(i), rand(i + 1.0), u); // використання її в інтерполяції +``` + +Ця *плавна випадковість* змінює правила гри для графічних інженерів і художників. Вона надає можливість генерувати зображення та геометрію, що виглядатимуть органічно. Алгоритм шуму Перліна реалізовано на різних мовах та для різних вимірів, що дозволяє створювати захопливі витвори мистецтва для різноманітних творчих цілей. + +![Robert Hodgin - Written Images (2010)](robert_hodgin.jpg) + +Тепер настала ваша черга: + +* Створіть власну функцію типу "```float noise(float x)```". + +* Використайте функцію шуму для анімації фігури, переміщуючи її, обертаючи або змінюючи масштаб. + +* Використовуючи шум, створіть анімаційну композицію з кількох рухомих фігур. + +* Сконструюйте за допомогою шуму "органічні" форми. + +* Розвиньте отриману "істоту" у персонаж, задавши їй певний рух. + +## Двомірний шум + +![](02.png) + +Тепер, коли ми знаємо, як створити одномірний шум (1D - one dimention), настав час перейти до 2D. У 2D, замість інтерполяції між двома точками лінії (```rand(x)``` та ```rand(x) + 1.0```), ми будемо інтерполювати між чотирма кутами квадратної площини (```rand(st)```, ```rand(st) + vec2(1., 0.)```, ```rand(st) + vec2(0., 1.)``` та ```rand(st) + vec2(1., 1.)```). + +![](01.png) + +Так само, якщо ми хочемо отримати тривимірний шум, то потрібно інтерполювати між вісьмома кутами куба. Ця техніка пов'язана з інтерполяцією випадкових значень, тому її називають **value noise (шумом значення)**. + +![](04.jpg) + +Як і з одномірним прикладом, ця інтерполяція не лінійна, а кубічна, яка плавно інтерполює будь-які точки всередині нашої квадратної сітки. + +![](05.jpg) + +Погляньте на наступну функцію шуму: + +
+ +Ми починаємо з масштабування простору у 5 разів (рядок 45), щоб побачити інтерполяцію між квадратами сітки. Потім у функції шуму ми ділимо простір на комірки. Дробову частину координати ми зберігаємо для використання всередині клітини, а цілу частину — як координату самої клітини. Ми використовуємо цілочисельне значення позиції, щоб обчислити координати чотирьох кутів комірки та отримати випадкове значення для кожного з них (рядки 23-26). Нарешті, у рядку 35 ми інтерполюємо між 4 випадковими значеннями кутів, використовуючи дробові позиції, які ми зберегли раніше. + +Тепер ваша черга. Спробуйте наступні вправи: + +* Змініть множник у рядку 45. Спробуйте анімувати його. + +* На якому рівні масштабування шум знову починає виглядати випадковим? + +* На якому рівні масштабування шум непомітний? + +* Спробуйте зробити функцію шуму залежною від координат курсору. + +* Що, якщо розглядати градієнт шуму як поле відстаней? Зробіть з ним щось цікаве. + +* Тепер, коли ви досягли певного контролю над порядком та хаосом, настав час використати ці знання. Створіть композицію з прямокутниками, кольорами й шумом, яка нагадувала б комплексність картини [Марка Ротко](http://en.wikipedia.org/wiki/Mark_Rothko). + +![Mark Rothko - Three (1950)](rothko.jpg) + +## Використання шуму в генеративному дизайні + +Алгоритми шуму початково були розроблені, щоб надати цифровим текстурам певної природної якості. Одномірна та двомірна реалізації, які ми бачили до цього часу, були інтерполяцією між випадковими *значеннями*, тому вони називаються **шумом значень**, але існують й інші способи отримати шум... + +[![Inigo Quilez - Value Noise](value-noise.png)](../edit.php#11/2d-vnoise.frag) + +Як ви виявили в попередніх вправах, значення шуму має тенденцію виглядати "блоковим". Щоб зменшити цей блоковий ефект, у 1985 році [Кен Перлін](https://mrl.nyu.edu/~perlin/) розробив іншу реалізацію алгоритму під назвою **градієнтний шум**. Кен зрозумів як інтерполювати випадкові *градієнти* замість значень. Ці градієнти були результатом двомірної випадкової функції, яка повертає напрямки (у вигляді ```vec2```) замість окремих значень типу ```float```. Клацніть на наступне зображення, щоб побачити код та як він працює. + +[![Inigo Quilez - Gradient Noise](gradient-noise.png)](../edit.php#11/2d-gnoise.frag) + +Знайдіть хвилинку, щоб переглянути ці два приклади, за авторства [Inigo Quilez](http://www.iquilezles.org/), та зверніть увагу на відмінності між [шумом значень](https://www.shadertoy.com/view/lsf3WH) та [градієнтним шумом](https://www.shadertoy.com/view/XdXGW8). + +Подібно до художника, який розуміється на роботі пігментних фарб, чим більше ми знаємо про імплементацію шуму, тим краще ми можемо їх використовувати. Наприклад, якщо за допомогою значень двомірного шуму обертати простір зображення з прямими лініями, то можна створити наступний ефект закручування, схожий на текстуру деревини. Клацніть на зображення, щоб побачити код: + +[ ![Wood texture](wood-long.png) ](../edit.php#11/wood.frag) + +```glsl + pos = rotate2d(noise(pos)) * pos; // обертання простору + pattern = lines(pos, .5); // малювання лінії +``` + +Ще один спосіб отримати цікаві візерунки за допомогою шуму – це розглядати його як поле відстаней та застосувати деякі трюки, описані в [розділі про фігури](../07/?lan=ua). + +[ ![Splatter texture](splatter-long.png) ](../edit.php#11/splatter.frag) + +```glsl + color += smoothstep(.15, .2, noise(st * 10.)); // чорні бризки + color -= smoothstep(.35, .4, noise(st * 10.)); // дірки на бризках +``` + +Третій спосіб використання функції шуму – це модуляція фігур. Для цього також потрібні певні трюки з [розділу про фігури](../07/?lan=ua). + + + +Для вашої практики: + +* Які ще генеративні патерни ви можете створити? Як щодо граніту? Мармуру? Магми? Води? Знайдіть три зображення текстур, які вас цікавлять та алгоритмічно реалізуйте їх, використовуючи шум. +* Використайте шум для модуляції форми. +* Як щодо використання шуму для руху? Поверніться до [розділу про матриці](../08/?lan=ua), використайте приклад з переміщенням хреста та застосуйте до його рухів трохи *випадковості* та *шуму*. +* Сгенеруйте зображення подібне до картини Джексона Поллака. + +![Jackson Pollock - Number 14 gray (1948)](pollock.jpg) + +## Покращений шум + +Кен Перлін удосконалив свій оригінальний шум та зробив **симплексний шум**, що полягає в заміні кубічної кривої Ерміта ( _f(x) = 3x^2-2x^3_, яка є ідентичною до функції [```smoothstep()```](../glossary/?lan=ua&search=smoothstep)) на квінтичну інтерполяційну криву (криву п'ятого ступеня) ( _f(x) = 6x^5 - 15x^4 + 10x^3_ ). Це робить обидва кінці кривої більш "пласкими", тому кожна межа з'єднується з наступною плавніше. Іншими словами, ви отримуєте більш безперервний перехід між осередками. Ви можете побачити це, розкоментувавши другу формулу в наступному прикладі графіка (або перегляньте обидва рівняння [тут](https://www.desmos.com/calculator/2xvlk5xp8b)). + +
+ +Зверніть увагу на те, як змінюються кінці кривої. Ви можете прочитати більше про це у [поясненнях самого Кена](http://mrl.nyu.edu/~perlin/paper445.pdf). + + +## Симплексний шум + +Кен Перлін не задовольнився успіхом свого алгоритму. Він гадав, що зможе досягти для нього більшої продуктивності. На Siggraph 2001 він представив "симплексний шум", у якому досяг наступних покращень у порівнянні з попередньою версією: + +* Менша обчислювальна складність та менша кількість множень. +* Шум масштабується до вищих розмірностей з меншими обчислювальними витратами. +* Шум без направлених артефактів. +* Шум має чітко визначений безперервний градієнт, який обчислюється досить дешево. +* Алгоритм достатньо легко реалізувати для апаратного забезпечення. + +Я знаю про що ви думаєте... "Хто цей чоловік?" Так, його робота фантастична! Але серйозно, як він покращив алгоритм? Розберімось. Для двох вимірів він інтерполював 4 точки (кути квадрата), для трьох [(див. реалізацію)](../edit.php#11/3d-noise.frag) та чотирьох вимірів нам потрібно інтерполювати вже 8 і 16 точок відповідно. Правильно? Іншими словами, для N вимірів вам потрібно плавно інтерполювати 2 у степені N точок (2^N). Але Кен розумно помітив, що хоча очевидним вибором форми, що заповнює простір, є квадрат, найпростішою фігурою у двомірному просторі є рівносторонній трикутник. Тому він почав із заміни квадратної сітки (яку ми щойно навчилися використовувати) на симплексну сітку рівносторонніх трикутників. + +![](simplex-grid-00.png) + +Симплексна форма для N-розмірності – це багатокутник з N + 1 кутами. Іншими словами, у двомірному просторі можна буде обчислювати на один кут менше, у тримірному – на 4 кути менше, а у чотиримірному – на 11 кутів менше! Це величезне покращення! + +У двох вимірах інтерполяція відбувається подібно до звичайного шуму, шляхом інтерполяції значень кутів ділянки. Однак у випадку з симплексною сіткою, нам потрібно інтерполювати лише 3 кути. + +![](simplex-grid-01.png) + +Як створюється симплексна сітка? Іншим блискучим і елегантним ходом є те, що симплексну сітку можна отримати, розділивши комірки правильної сітки з 4 кутами на два рівнобедрених трикутники, а потім трохи скосити їх, доки кожен трикутник не стане рівностороннім. + +![](simplex-grid-02.png) + +Далі, як описав [Stefan Gustavson у статті "Simplex noise demystified"](https://web.archive.org/web/20230310204121/https://weber.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): _"...розглянувши цілі частини трансформованої координати (x, y) для точки, яку ми хочемо визначити, можна швидко визначити, яка саме клітинка з двох симплексів її вміщує. Порівнявши абсолютні величини x і y, ми можемо визначити, чи точка знаходиться у верхньому чи нижньому симплексі та обійти через три кутові точки."_ + +У наступному коді ви можете розкоментувати рядок 44, щоб побачити перекіс сітки, а потім розкоментувати рядок 47, щоб побачити побудову симплексної сітки. Зверніть увагу, як у рядку 22 ми ділимо скошений квадрат на два рівносторонні трикутники, просто визначаючи, чи ```x > y``` ("нижній" трикутник) чи ```y > x``` ("верхній" трикутник). + +
+ +Результатом усіх цих удосконалень є алгоритмічний шедевр, відомий як **Симплексний шум**. Нижче наведено GLSL-реалізацію цього алгоритму, розроблену за участі Ian McEwan та Stefan Gustavson (представлена у роботі ["Efficient computational noise in GLSL"](https://web.archive.org/web/20190203222422/http://weber.itn.liu.se/~stegu/jgt2012/article.pdf)), яка занадто складна для простих освітніх цілей, але ви із задоволенням побачите, що вона менш загадкова, ніж можна було очікувати, а код короткий та швидкий. + +[ ![Ian McEwan of Ashima Arts - Simplex Noise](simplex-noise.png) ](../edit.php#11/2d-snoise-clear.frag) + +Що ж... досить технічних нюансів, настав ваш час для використання цього ресурсу у якості нового засобу виразності: + +* Поміркуйте, як виглядає кожна реалізація шуму. Уявіть їх як необроблену сировину, як мармурову скелю для скульптора. Що ви можете сказати про відчуття до кожної з них? Примружте очі для активізації уяви, наче видивляєтеся якісь фігури в хмарах. Що ви бачите? Про що це нагадує? Що підказує вам ваша уява, що можна зробити з кожною реалізацією шуму? Слідуйте за своїм чуттями та спробуйте втілити ідеї в коді. + +* Створіть шейдер, який створює ілюзію потоку. Подібно до лавової лампи, крапель чорнила, води тощо. + + + +* Використовуючи симплексний шум, додайте трохи текстурності до виконаних раніше робіт. + + + +У цьому розділі ми навчилися певного контролю над хаосом. Це була нелегка робота! Для того, щоб стати майстром з використання шуму, потрібні час та зусилля. + +У наступних розділах ми оглянемо деякі добре відомі методи для вдосконалення ваших навичок та отримаємо більше користі від шуму для розробки якісної генеративної графіки за допомогою шейдерів. А поки що трохи відпочиньте та насолодіться часом на свіжому повітрі, споглядаючи природу та її складні візерунки. Ваша здатність до спостереження потребує такої ж, або навіть більшої, уваги, ніж ваші творчі навички. Вийдіть на вулицю та насолодіться рештою дня! + +

"Поговори з деревом, подружися з ним." Bob Ross +

diff --git a/11/README.md b/11/README.md index d5d933a..ae410ae 100644 --- a/11/README.md +++ b/11/README.md @@ -202,7 +202,7 @@ All these improvements result in an algorithmic masterpiece known as **Simplex N Well... enough technicalities, it's time for you to use this resource in your own expressive way: -* Contemplate how each noise implementation looks. Imagine them as a raw material, like a marble rock for a sculptor. What can you say about about the "feeling" that each one has? Squinch your eyes to trigger your imagination, like when you want to find shapes in a cloud. What do you see? What are you reminded of? What do you imagine each noise implementation could be made into? Following your guts and try to make it happen in code. +* Contemplate how each noise implementation looks. Imagine them as a raw material, like a marble rock for a sculptor. What can you say about the "feeling" that each one has? Squinch your eyes to trigger your imagination, like when you want to find shapes in a cloud. What do you see? What are you reminded of? What do you imagine each noise implementation could be made into? Following your guts and try to make it happen in code. * Make a shader that projects the illusion of flow. Like a lava lamp, ink drops, water, etc. diff --git a/12/README-ua.md b/12/README-ua.md new file mode 100644 index 0000000..0c0d6c6 --- /dev/null +++ b/12/README-ua.md @@ -0,0 +1,191 @@ +![](dragonfly.jpg) + +## Клітинний шум + +У 1996 році, через шістнадцять років після оригінального шуму Перліна та за п’ять років до його симплексного шуму, Steven Worley написав статтю під назвою [“Базова функція клітинної текстури”](http://www.rhythmiccanvas.com/research/papers/worley.pdf). У ній він описує техніку процедурного текстурування, яка зараз широко використовується графічною спільнотою. + +Щоб зрозуміти принципи, що лежать в її основі, нам потрібно почати думати в термінах **ітерацій**. Напевно, ви розумієте, що це означає використання циклів ```for```. У циклах ```for``` в GLSL є лише одна заковика: число, яке використовується у перевірці лічильника, має бути константою ([```const```](../glossary/?lan=ua&search=const)). Отже, ніяких динамічних циклів — кількість ітерацій має бути фіксованою. + +Давайте розглянемо приклад. + +### Точки у полі відстаней + +Клітинний шум базується на полях відстаней, що розташовані до найближчої точки з певного набору. Скажімо, ми хочемо створити поле відстаней з 4 точок. Що нам потрібно зробити? **Для кожного пікселя ми хочемо обчислити відстань до найближчої точки**. Це означає, що нам потрібно виконати ітерацію по всім точкам, обчислити до них відстані від поточного пікселя та зберегти значення до найближчої. + +```glsl + float min_dist = 100.; // змінна для збереження відстані до найближчої точки + + min_dist = min(min_dist, distance(st, point_a)); + min_dist = min(min_dist, distance(st, point_b)); + min_dist = min(min_dist, distance(st, point_c)); + min_dist = min(min_dist, distance(st, point_d)); +``` + +![](cell-00.png) + +Не дуже елегантно, але робить свою справу. Тепер реалізуємо цей підхід за допомогою масиву та циклу ```for```: + +```glsl + float m_dist = 100.; // мінімальна відстань + + for (int i = 0; i < TOTAL_POINTS; i++) { + float dist = distance(st, points[i]); + m_dist = min(m_dist, dist); + } +``` + +Зверніть увагу, як ми використовуємо цикл ```for```, щоб перебирати масив точок і відстежувати мінімальну відстань за допомогою функції [```min()```](../glossary/?lan=ua&search=min). Ось коротка робоча реалізація цієї ідеї: + +
+ +У наведеному вище коді одна з точок прив'язана до положення курсору. Пограйте з прикладом, щоб отримати краще інтуїтивне уявлення щодо поведінки програми. Потім спробуйте наступне: + +- Як анімувати решту точок? +- Прочитавши [розділ про фігури](../07/?lan=ua), уявіть цікаві способи використання з цим полем відстаней! +- Як додати більше точок до цього поля відстаней? Що можна зробити для динамічного додавання або видалення точок? + +### Замощення та ітерація + +Ви, мабуть, помітили, що цикли ```for``` та *масиви* не дуже дружать з GLSL. Як ми вже говорили раніше, місцеві цикли не здатні на динамічну кількість ітерацій. Крім того, велика кількість ітерацій значно знижує продуктивність вашого шейдера. Це означає, що ми не можемо використовувати цей прямолінійний підхід для великої кількості точок. Нам потрібно знайти іншу стратегію, яка буде використовувати переваги архітектури GPU з її паралельними обчисленнями. + +![](cell-01.png) + +Один з підходів до розв'язання цієї проблеми — це розділення простору на плитки. Кожному пікселю не обов'язково перевіряти відстань до кожної окремої точки, чи не так? Враховуючи той факт, що кожен піксель працює у власному потоці, ми можемо розділити простір на комірки, кожна з яких матиме одну унікальну точку для спостереження. Крім того, щоб уникнути аберацій на межах між комірками, нам потрібно перевірити відстань до точок лише у сусідніх клітинах. Це і є головною чудовою ідеєю у [статті Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Зрештою, кожен піксель має перевірити лише дев’ять позицій: точку своєї клітини та точки у 8 клітинах навколо неї. Ми вже поділяли простір на комірки в розділах про: [патерни](../09/?lan=ua), [випадковість](../10/?lan=ua) та [шум](../11/?lan=ua), тож, сподіваюся, ви вже знайомі з цією технікою. + +```glsl + // Масштаб + st *= 3.; + + // Розділ простору на плитки + vec2 i_st = floor(st); + vec2 f_st = fract(st); +``` + +Отже, який план? Ми будемо використовувати координати клітини-плитки, збережені в цілочисельній координаті ```i_st```, щоб побудувати випадкову позицію точки. Функція ```random2f```, яку ми будемо використовувати, отримує на вхід ```vec2``` та повертає нам також ```vec2``` з випадковою для даної клітини координатою. Таким чином, для кожної плитки ми матимемо одну особливу точку у випадковому місці цієї плитки. + +```glsl + vec2 point = random2(i_st); +``` + +Кожен піксель усередині плитки, з координатою збереженою у змінній ```f_st```, перевірятиме свою відстань до випадкової точки, про яку ми говорили раніше. + +```glsl + vec2 diff = point - f_st; + float dist = length(diff); +``` + +Результат буде виглядати так: + + + +Нам все ще потрібно перевірити відстані до точок у навколишніх клітинах, а не лише на поточній. Для цього нам потрібно **ітерувати** сусідні клітини. Не всі клітини, а лише ті, що знаходяться безпосередньо навколо поточної. Тобто від ```-1``` клітини ліворуч, до ```+1``` клітини праворуч по осі ```x``` та від ```-1``` клітини знизу до ```+1``` клітини зверху по осі ```y```. Цю ділянку розміром 3x3 із 9 клітин можна обійти за допомогою подвійного циклу ```for```: + +```glsl +for (int y= -1; y <= 1; y++) { + for (int x= -1; x <= 1; x++) { + // Сусідня позиція клітини у сітці + vec2 neighbor = vec2(float(x), float(y)); + ... + } +} +``` + +![](cell-02.png) + +Тепер у вкладеному циклі ```for``` ми можемо обчислити положення наших випадкових точок у кожній сусідній клітині, додаючи зміщення сусідньої клітини до координат поточної. + +```glsl + ... + // Положення випадкової точки у сусідній плитці + vec2 point = random2(i_st + neighbor); + ... +``` + +Решта зводиться до обчислення відстаней до цієї точки та збереження найближчої у змінну ```m_dist```. + +```glsl + ... + vec2 diff = neighbor + point - f_st; + + // Відстань до точки + float dist = length(diff); + + // Збереження ближчої дистанції + m_dist = min(m_dist, dist); + ... +``` + +Наведений вище код створено на основі [статті Inigo's Quilez](http://www.iquilezles.org/www/articles/smoothvoronoi/smoothvoronoi.htm), де він писав: + +*"... варто зазначити, що у наведеному вище коді є гарний трюк. Більшість реалізацій страждають від проблем із точністю, оскільки вони генерують свої випадкові точки в просторі "домену" (наприклад, у "глобальному" просторі чи просторі "об'єкта"), який може бути як завгодно далеко від початку координат. Проблему можна вирішити, перемістивши весь код до типів даних з вищою точністю, або проявивши трохи кмітливості. Моя реалізація генерує точки не в просторі "домену", а в просторі "комірки": як тільки із фрагментного пікселя отримано цілу та дробову частини, а значить визначено клітину, в якій ми працюємо, нас цікавитиме лише те, що відбувається навколо цієї клітини, а не весь простір. Тобто ми можемо відкинути цілочисельну частину значення наших координат та зберегти кілька біт точності. Насправді у звичайній реалізації діаграми Вороного, цілі частини координат точки просто скасовуються, коли випадкові точки клітини віднімаються від поточної шейдерної точки. У реалізації вище ми не робимо цього, оскільки переносимо всі обчислення в простір "комірки". Цей підхід дозволяє накласти діаграму Вороного хоч на цілу планету — достатньо просто подвоїти точність для вхідних даних, виконати для них обчислення з floor() і fract(), а решту обчислень проводити вже зі звичайною точністю для float, не витрачаючи обчислювальні ресурси на зміну всієї реалізації до подвійної точності. Звісно, той самий трюк можна застосувати й до підходів з шумом Перліна, але я ніколи не бачив подібну реалізацію чи опис подібного алгоритму)."* + +Підсумовуючи: розбиваємо простір на клітини. Кожен піксель обчислює відстань до точки у власній клітині та навколишніх 8 клітинах, зберігаючи найближчу відстань. В результаті маємо поле відстаней, що виглядає як на прикладі нижче: + +
+ +Дослідіть цей приклад глибше: + +- Масштабуйте простір різними значеннями. +- Вигадайте інші способи анімації точок. +- Що потрібно зробити для обчислення додаткової точки у положенні курсору? +- Які інші способи побудови цього поля відстаней ви можете собі уявити, окрім ```m_dist = min(m_dist, dist);```? +- Які цікаві візерунки можна зробити за допомогою цього поля відстаней? + +Цей алгоритм також можна інтерпретувати з точки зору точок, а не пікселів. У цьому випадку його можна описати таким чином: кожна точка росте, доки не натрапить на область росту іншої точки. Ця поведінка відображає деякі правила росту в природі. Живі організми формуються через цю напругу між внутрішньою силою зростання й розширення та обмеженнями зовнішніх сил. Класичний алгоритм, який імітує таку поведінку, названий на честь [Георгія Вороного](https://en.wikipedia.org/wiki/Georgy_Voronoy). + +![](monokot_root.jpg) + +### Алгоритм Вороного + +Побудувати діаграми Вороного з клітинного шуму не так складно, як може здатися. Нам просто потрібно *зберегти* додаткову інформацію про найближчу точку до пікселя. Для цього ми використаємо змінну ```m_point``` типу ```vec2```. Зберігаючи вектор напрямку до найближчої точки замість відстані, ми "отримаємо" "унікальний" ідентифікатор цієї точки. + +```glsl + ... + if ( dist < m_dist ) { + m_dist = dist; + m_point = point; + } + ... +``` + +Зауважте, що в наступному коді, для обчислення найближчої відстані ми використовуємо звичайний оператор ```if``` замість функції ```min```. Чому? Тому що, при знаходженні нової найближчої точки, ми хочемо зробити додаткову дію і зберегти її координати (рядки 32-37). + +
+ +Зверніть увагу, як колір рухомої комірки, прив'язаної до положення курсору, змінює колір відповідно до його положення. Це тому, що колір визначається залежно від позиції найближчої точки. + +Як і у попередніх прикладах, настав час збільшити масштаби, скориставшись підходом зі [статті за авторства Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Спробуйте реалізувати його самостійно. Ви можете скористатися допомогою наступного прикладу, клацнувши на нього. Зауважте, що оригінальний підхід від Steven Worley використовує змінну кількість точок для кожної клітини, більш ніж одну у більшості випадків. У його програмній реалізації на мові C це використовується для прискорення циклу завдяки раннім виходам із нього. Цикли GLSL не дозволяють змінювати кількість ітерацій, тому вам, ймовірно, доведеться використовувати лише одну точку на клітину. + + + +Розібравшись із цим алгоритмом, подумайте про цікаві та креативні способи його використання. + +![Extended Voronoi - Leo Solaas (2011)](solas.png) + +![Cloud Cities - Tomás Saraceno (2011)](saraceno.jpg) + +![Accretion Disc Series - Clint Fulkerson](accretion.jpg) + +![Vonoroi Puzzle - Reza Ali (2015)](reza.png) + +### Поліпшення діаграми Вороного + +У 2011 році [Stefan Gustavson оптимізував алгоритм Steven Worley для GPU](https://web.archive.org/web/20220530233245/https://weber.itn.liu.se/~stegu/GLSL-cellular/GLSL-cellular-notes.pdf), обходячи лише матрицю 2x2 замість 3x3. Це значно зменшує обсяг роботи, але може створювати артефакти у вигляді розривів на краях між клітинами. Подивіться на наступні приклади: + +
+ +Пізніше у 2012 році [Inigo Quilez написав статтю про створення точних меж для комірок Вороного](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm). + + + +На цьому експерименти Inigo з Вороним не закінчилися. У 2014 році він написав чудову статтю про функцію [voro-noise](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm), яка дозволяє поступово змішувати звичайний шум з комірками Вороного. Ось вирізка з його слів: + +*"Попри схожість, сітка в обох патернах використовується по різному. Шум інтерполює/усереднює випадкові значення (як у шумі значення) або градієнти (як у градієнтному шумі), тоді як алгоритм Вороного обчислює відстань до найближчої опорної точки. Плавна білінійна інтерполяція та обчислення мінімума — дві дуже різні операції чи... ні? Чи можна їх об’єднати у більш загальну метрику? Якщо так, то шум та патерни Вороного можна розглядати як окремі випадки більш загального генератора патернів на основі регулярної сітки?»* + + + +Настав час придивитися до навколишніх речей, надихнутися природою, знайти власну ідею та спробувати сили у цій техніці! + +![Deyrolle glass film - 1831](DeyrolleFilm.png) + +
diff --git a/13/README-ua.md b/13/README-ua.md new file mode 100644 index 0000000..cf0ef6c --- /dev/null +++ b/13/README-ua.md @@ -0,0 +1,111 @@ +![Due East over Shadequarter Mountain - Matthew Rangel (2005) ](rangel.jpg) + +## Фрактальний броунівський рух + +Для різних людей слово "шум" означає різні речі. Музиканти будуть думати про безладні звуки, інженери зв'язку — про перешкоди, а астрофізики — про космічний мікрохвильовий фон. Ці концепції повертають нас до фізичної природи випадковості в навколишньому світі. Однак почнімо з чогось більш фундаментального та простішого: хвиль та їхніх характеристик. Хвиля — це коливання певної властивості з плином часу. Аудіохвилі — це коливання тиску повітря, електромагнітні хвилі — це коливання електричного та магнітного полів. Двома важливими характеристиками хвилі є її амплітуда та частота. Рівняння для простої лінійної (одномірної) хвилі виглядає так: + +
+ +* Спробуйте змінити значення частоти та амплітуди, щоб зрозуміти їх поведінку. +* Використовуючи формотворчі функції, змінюйте амплітуду залежно від часу. +* Використовуючи формотворчі функції, змінюйте частоту залежно від часу. + +Виконуючи останні дві вправи, ви "модулювали" синусоїду, створивши AM (амплітудно-модульовані) та FM (frequency modulated - частотно-модульовані) хвилі. Мої вітання! + +Ще однією цікавою властивістю хвиль є здатність до їх поєднання, що формально називається суперпозицією. Закоментуйте, розкоментуйте та позмінюйте наступні рядки. Зверніть увагу на зміни загального вигляду, коли ми додаємо разом хвилі з різними амплітудами та частотами. + +
+ +* Поекспериментуйте, змінюючи частоту й амплітуду додаткових хвиль. +* Чи можна зробити дві хвилі, що нейтралізуватимуть одна одну? Як це буде виглядати? +* Чи можна скласти хвилі так, щоб вони посилювали одна одну? + +У музиці кожна нота асоціюється з певною частотою. Частоти для цих нот відповідають певному порядку, який ми називаємо гамою. Подвоєння або зменшення частоти вдвоє відповідає зміні ноти на одну октаву. + +Тепер, замість синусоїди, використаємо шум Перліна! Шум Перліна у своїй основній формі виглядає та відчувається, як синусоїда. Його амплітуда та частота дещо мінливі, але амплітуда залишається досить однорідною, а частота обмежена досить вузьким діапазоном навколо центральної частоти. В цілому шум не такий регулярний, як синусоїда, та з його допомогою легше створити видимість випадковості, об'єднавши кілька масштабованих версій. Вигляд суми синусоїд також можна зробити більш випадковим, але для цього потрібно багато різних хвиль, щоб приховати їх періодичну та регулярну природу. + +Додаючи різні ітерації шуму (*октави*), у яких ми послідовно збільшуємо частоту на регулярну величину (*лакунарність*) та зменшуємо амплітуду (*посилення*) **шуму**, можна отримати деталізованіший шум та більше дрібних деталей. Ця техніка називається "фрактальний броунівський рух" (*fBM*) або просто "фрактальний шум". У найпростішому вигляді її можна створити за допомогою наступного коду: + +
+ +* Поступово збільшуйте кількість октав від 1 до 2, 4, 8 і 10. Спостерігайте за результатом. +* Коли матимете понад чотири октави, спробуйте змінити значення лакунарності. +* Також, коли октав понад 4, змініть значення для посилення (gain) та подивіться, що станеться. + +Зверніть увагу, що з кожною додатковою октавою крива стає деталізованішою. Також зверніть увагу на прояви самоподібності, зі збільшенням кількості октав. Якщо збільшити масштаб кривої, менша її частина виглядатиме приблизно так само, як і вся крива, а кожен окремий відрізок виглядає більш-менш схоже на будь-який інший. Це важлива властивість математичних фракталів, яку ми моделюємо у нашому циклі. Ми не створюємо *справжній* фрактал, оскільки зупиняємо модуляцію після кількох ітерацій, але теоретично можна отримати справжній математичний фрактал, якщо дозволити циклу тривати вічно та додавати нескінченну кількість компонентів шуму. У комп'ютерній графіці ми завжди маємо обмеження щодо найдрібніших деталей, які можемо розпізнати. Наприклад, якщо об'єкти стають меншими за піксель, немає потреби робити нескінченні обрахунки, щоб створити видимість фракталу. Іноді може знадобитися багато доданків, але ніколи не знадобиться їх нескінченна кількість. + +Наступний код показує реалізацію двомірного fBm, схожого на фрактальний візерунок: + +
+ +* Знизьте кількість октав, змінивши значення в рядку 37 +* Змініть значення лакунарності у рядку 47 +* Дослідіть результати, змінюючи значення підсилення в рядку 48 + +Ця техніка зазвичай використовується для побудови процедурних ландшафтів. Самоподібність fBm ідеально підходить для створення гір, тому що процеси ерозії, які створюють реальні гори, також надають їм вигляд самоподібності в широкому діапазоні масштабів. Якщо це вас зацікавило, вам варто прочитати [цю чудову статтю Inigo Quiles про вдосконалений шум](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm). + +![Blackout - Dan Holdsworth (2010)](holdsworth.jpg) + +Використовуючи більш-менш таку саму техніку, можна також отримати й інші ефекти, такі як **турбулентність**. По суті, це fBm, але побудований з абсолютних значень шуму, що створює різкі впадини. + +```glsl +for (int i = 0; i < OCTAVES; i++) { + value += amplitude * abs(snoise(st)); + st *= 2.; + amplitude *= .5; +} +``` + + + +Іншим представником цього сімейства алгоритмів є **хребти**, де гострі долини перевернуті догори дном, щоб натомість вийшли гострі гребні: + +```glsl + n = abs(n); // створюємо складки + n = offset - n; // інвертуємо складки догори дном + n = n * n; // загострюємо складки ще більше +``` + + + +Ще один варіант з корисними варіаціями можна здобути за допомогою перемноження компонентів шуму замість їх додавання. Також цікаво масштабувати наступні шумові функції на основі чогось, що залежить від попередніх сум складових. Коли ми робимо подібні речі, то віддаляємося від суворого визначення фракталу та переходимо у відносно невідому область "мультифракталів". Мультифрактали поки що не мають чіткого математичного визначення, але це не робить їх менш корисними для графіки. Насправді мультифрактальне моделювання дуже поширене в сучасному комерційному програмному забезпеченні для генерації рельєфу. Детальніше про це можна прочитати у 16 розділі 3-го видання книги "Текстурування та моделювання: процедурний підхід" ("Texturing and Modeling: a Procedural Approach"), автор Kenton Musgrave. На жаль, цю книгу перестали друкувати, але її все ще можна знайти в бібліотеках та вторинному ринку. Майте на увазі, що в інтернеті продається PDF-версія 1-го видання, яку не варто купувати, оскільки воно не містить жодного матеріалу про моделювання ландшафтів. + +### Викривлення домену (просторової області) + +[Inigo Quiles написав ще одну захопливу статтю](http://www.iquilezles.org/www/articles/warp/warp.htm) про використання fBm для деформації простору fBm. Вибух мозку, правда? Це як сон уві сні у фільмі "Початок" (Inception). + +![f(p) = fbm(p + fbm(p + fbm(p))) - Inigo Quiles (2002)](quiles.jpg) + +Менш екстремальний приклад цієї техніки показано у наступному коді, де викривлення використовується для отримання текстури, схожої на хмари. Зверніть увагу, що властивість самоподібності все ще присутня у результаті: + +
+ +Викривлення координат текстури за допомогою шуму може бути дуже корисним, дуже веселим та диявольськи складним для освоєння. Це потужний інструмент, але щоб добре його використовувати, потрібен певний досвід. Корисним підходом для подібних маніпуляцій є зміщення координат за допомогою похідної (градієнта) шуму. На цій ідеї базується відома стаття під назвою ["Шум потоку"](http://evasion.imag.fr/Publications/2001/PN01/), автори Ken Perlin та Fabrice Neyret. Деякі сучасні реалізації шуму Перліна включають обчислення як функції, так і її аналітичного градієнта. diff --git a/14/README-ua.md b/14/README-ua.md new file mode 100644 index 0000000..4773633 --- /dev/null +++ b/14/README-ua.md @@ -0,0 +1,16 @@ +## Фрактали + +Coming soon ... + +А поки що можете подивитися приклади з фракталами на платформі [shadertoy.com](https://www.shadertoy.com/results?query=fractals): + +[Basic Fractal](https://www.shadertoy.com/view/Mss3Wf) +[Mandelbrot - distance](https://www.shadertoy.com/view/lsX3W4) +[Mandelbrot - smooth](https://www.shadertoy.com/view/4df3Rn) +[Mandelbrot: Power Transitioning](https://www.shadertoy.com/view/lls3D7) +[IFS - brute force](https://www.shadertoy.com/view/lss3zs) +[Julia - Distance 1](https://www.shadertoy.com/view/Mss3R8) +[Julia - Distance 3](https://www.shadertoy.com/view/4dXGDX) +[Julia - Traps 2](https://www.shadertoy.com/view/4dfGRn) +[Fractal Wheel 2.0](https://www.shadertoy.com/view/llfGD2) +[Koch Snowflake again](https://www.shadertoy.com/view/Mlf3RX) diff --git a/14/README.md b/14/README.md index 68c5506..37a1d5e 100644 --- a/14/README.md +++ b/14/README.md @@ -1,3 +1,16 @@ ## Fractals -Comming soon ... \ No newline at end of file +Coming soon ... + +In the meantime, you can check out some examples with fractals on the [shadertoy.com](https://www.shadertoy.com/results?query=fractals) platform: + +[Basic Fractal](https://www.shadertoy.com/view/Mss3Wf) +[Mandelbrot - distance](https://www.shadertoy.com/view/lsX3W4) +[Mandelbrot - smooth](https://www.shadertoy.com/view/4df3Rn) +[Mandelbrot: Power Transitioning](https://www.shadertoy.com/view/lls3D7) +[IFS - brute force](https://www.shadertoy.com/view/lss3zs) +[Julia - Distance 1](https://www.shadertoy.com/view/Mss3R8) +[Julia - Distance 3](https://www.shadertoy.com/view/4dXGDX) +[Julia - Traps 2](https://www.shadertoy.com/view/4dfGRn) +[Fractal Wheel 2.0](https://www.shadertoy.com/view/llfGD2) +[Koch Snowflake again](https://www.shadertoy.com/view/Mlf3RX) diff --git a/15/README-ua.md b/15/README-ua.md new file mode 100644 index 0000000..ee1ba03 --- /dev/null +++ b/15/README-ua.md @@ -0,0 +1,81 @@ +# Обробка зображень + +## Текстури + +![](01.jpg) + +Графічні карти (GPU) мають для зображень спеціальні типи пам’яті. Зазвичай CPU зберігають зображення у вигляді масиву байтів, а GPU зберігають зображення як ```sampler2D```, що більше схоже на таблицю (або матрицю) векторів типу float. Що ще цікавіше, значення цієї *таблиці* векторів безперервні. Це означає, що значення між пікселями інтерполюються на низькому рівні. + +Щоб скористатися цим функціоналом, нам спочатку потрібно *завантажити* зображення з CPU на GPU, а потім передати ```id``` текстури до відповідної [```uniform```](../05/?lan=ua)-змінної. Початкове завантаження зображення відбувається поза шейдером. + +Після того, як текстуру завантажено та прив'язано до змінної через ```uniform sampler2D```, ви можете отримати конкретне значення кольору у певних координатах типу [```vec2```](../glossary/?lan=ua&search=vec2) за допомогою функції [```texture2D()```](../glossary/?lan=ua&search=texture2D) яка поверне колір типу [```vec4```](../glossary/?lan=ua&search=vec4). + +```glsl +vec4 texture2D(sampler2D texture, vec2 coordinates) +``` + +Перегляньте наступний код, у якому ми завантажуємо зображення [Хвилі Хокусая (1830)](https://en.wikipedia.org/wiki/The_Great_Wave_off_Kanagawa) як ```uniform sampler2D u_tex0```, отримуємо та відображаємо кожен її піксель всередині полотна: + +
+ +Якщо ви звернете увагу, то помітите, що координати для текстури нормалізовані! Який сюрприз, правда? Координати текстур консистентні з нормалізованими координатами простору, що також знаходяться в діапазоні від 0.0 до 1.0. + +Тепер, коли ви побачили, як правильно завантажувати текстуру, настав час поекспериментувати та дізнатися, що можна з нею зробити: + +* Змініть масштаб текстури вдвічі. +* Поверніть текстуру на 90 градусів. +* Прив'яжіть координати до позиції курсору, щоб переміщати зображення. + +Чому ви повинні бути в захваті від текстур? По-перше, забудьте про сумні 255 значень для кожного каналу. Як тільки ваше зображення перетворено на ```uniform sampler2D```, ви працюватимете у діапазоні значень від 0.0 до 1.0. Ось чому шейдери можуть створювати дійсно красиві ефекти постобробки. + +По-друге, за допомогою координат [```vec2```](../glossary/?lan=ua&search=vec2) ви можете отримати значення кольору текстури навіть між пікселями. Як ми вже говорили раніше, значення текстури є континуумом. Це означає, що ви можете отримувати значення вашого зображення по всій його поверхні. Ці значення плавно змінюватимуться від пікселя до пікселя без стрибків! + +Нарешті, ви можете налаштувати шейдер для повторення вашого зображення вздовж полотна. Наприклад, при використанні значень, що менше або більше від нормалізованих 0.0 та 1.0 ви можете "загорнути" їх у цей самий діапазон та знову отримати кольори в межах зображення. + +Усі ці можливості роблять ваші зображення схожими на нескінченну тканину спандекс. Ви можете розтягувати та звужувати свою текстуру, не зважаючи на сітку байтів, з яких вона складалася початково. Щоб відчути це, подивіться на наступний код, де ми деформуємо текстуру за допомогою [функції шуму, з попередніх розділів](../11/?lan=ua). + +
+ +## Роздільна здатність текстури + +Наведені вище приклади добре працюють з квадратними зображеннями, де обидві сторони рівні та збігаються з нашим квадратним полотном. Але для неквадратних зображень все може бути трохи складніше. Століття художнього мистецтва та фотографії знайшли для зображень більш приємні для ока неквадратні пропорції. + +![Joseph Nicéphore Niépce (1826)](nicephore.jpg) + +Як ми можемо розв'язати цю проблему? Щоб дізнатися як правильно розтягнути текстуру, нам потрібно знати оригінальні пропорції зображення, що дозволить отримати його [*співвідношення сторін*](http://en.wikipedia.org/wiki/Aspect_ratio). Для цього ширина та висота текстури також передаються шейдеру через ```uniform```, який у нашому прикладі буде мати тип ```vec2```. Ми надали цій змінній таку саму назву як і для текстури, але з доповненням ```Resolution```. Отримавши цю інформацію, ми можемо отримати у шейдері співвідношення сторін, поділивши ```ширину``` на ```висоту```. Нарешті, помноживши це співвідношення на координату ```y```, ми змінимо цю вісь таким чином, щоб вона відповідала бажаним пропорціям. + +Розкоментуйте рядок 21 наступного коду, щоб побачити це в дії: + +
+ +* Поміркуйте, що потрібно зробити, щоб відцентрувати це зображення по центру полотна? + +## Цифрова оббивка + +![](03.jpg) + +Ви можете подумати, що все це трохи ускладнено... й, напевно, матимете рацію. Але такий спосіб роботи з зображеннями залишає достатньо місця для різних хитрощів та творчих прийомів. Спробуйте уявити, що ви робите оббивку, а натягуючи та огортаючи тканину поверх конструкції, ви можете створювати нові патерни та цікавіші результати. + +![Eadweard's Muybridge study of motion](muybridge.jpg) + +Подібний рівень ремісництва нагадує деякі з перших оптичних експериментів. Наприклад, в іграх дуже поширена *спрайтова анімація*, що навіває спогади про [фенакістископ](https://en.wikipedia.org/wiki/Phenakistiscope), [зоотроп](https://en.wikipedia.org/wiki/Zoetrope) та [праксиноскоп](https://en.wikipedia.org/wiki/Praxinoscope). + +Виглядає просто, але можливості для зміни текстурних координат просто величезні. + +
+ +Тепер ваша черга: + +* Спробуйте зробити калейдоскоп: + + + +* Задовго до [Oculus](https://en.wikipedia.org/wiki/Oculus_Rift) та [google cardboard](https://en.wikipedia.org/wiki/Google_Cardboard) стереоскопічна фотографія була неабиякою справою. Чи можете ви закодувати простий шейдер, щоб повторно використати ці чудові зображення? + +![](texture-stereo-00.jpg) +![](texture-stereo-01.jpg) +![](texture-stereo-03.jpg) + +* Які ще оптичні іграшки можна відтворити за допомогою текстур? + +У наступних розділах ми побачимо як за допомогою шейдерів можна обробляти зображення, виконуючи певні операції. Зрештою шейдери не в останню чергу розроблені саме для цього. diff --git a/15/README.md b/15/README.md index 2b73db0..f86abfc 100644 --- a/15/README.md +++ b/15/README.md @@ -8,7 +8,7 @@ Graphic cards (GPUs) have special memory types for images. Usually on CPUs image In order to use this feature we first need to *upload* the image from the CPU to the GPU, to then pass the ```id``` of the texture to the right [```uniform```](../05). All that happens outside the shader. -Once the texture is loaded and linked to a valid ```uniform sampler2D``` you can ask for specific color value at specific coordinates (formated on a [```vec2```](index.html#vec2.md) variable) using the [```texture2D()```](index.html#texture2D.md) function which will return a color formatted on a [```vec4```](index.html#vec4.md) variable. +Once the texture is loaded and linked to a valid ```uniform sampler2D``` you can ask for specific color value at specific coordinates (formatted on a [```vec2```](index.html#vec2.md) variable) using the [```texture2D()```](index.html#texture2D.md) function which will return a color formatted on a [```vec4```](index.html#vec4.md) variable. ```glsl vec4 texture2D(sampler2D texture, vec2 coordinates) @@ -58,7 +58,7 @@ You may be thinking that this is unnecessarily complicated... and you are probab ![Eadweard's Muybridge study of motion](muybridge.jpg) -This level of craftsmanship links back to some of the first optical experiments ever made. For example on games *sprite animations* are very common, and is inevitably to see on it reminiscence to phenakistoscope, zoetrope and praxinoscope. +This level of craftsmanship links back to some of the first optical experiments ever made. For example on games *sprite animations* are very common, and is inevitably to see on it reminiscence to [phenakistoscope](https://en.wikipedia.org/wiki/Phenakistiscope), [zoetrope](https://en.wikipedia.org/wiki/Zoetrope) and [praxinoscope](https://en.wikipedia.org/wiki/Praxinoscope). This could seem simple but the possibilities of modifying textures coordinates are enormous. For example: @@ -68,10 +68,13 @@ Now is your turn: * Can you make a kaleidoscope using what we have learned? -* Way before Oculus or google cardboard, stereoscopic photography was a big thing. Could you code a simple shader to re-use these beautiful images? + - +* Way before [Oculus](https://en.wikipedia.org/wiki/Oculus_Rift) or [google cardboard](https://en.wikipedia.org/wiki/Google_Cardboard), stereoscopic photography was a big thing. Could you code a simple shader to re-use these beautiful images? +![](texture-stereo-00.jpg) +![](texture-stereo-01.jpg) +![](texture-stereo-03.jpg) * What other optical toys can you re-create using textures? diff --git a/15/index.php b/15/index.php index 3ee01f6..d0e13db 100644 --- a/15/index.php +++ b/15/index.php @@ -1,6 +1,7 @@ + +### Додавання, віднімання, множення та інші варіанти + +В даному шейдері завантажено два зображення, які розташовано один над одним. По черзі розкоментовуйте рядки 22-27 та спостерігайте за результатами поєднання цих зображень залежно від операції. Перш ніж розкоментувати рядок, поміркуйте над тим який має бути результат і чому: + +![](02.jpg) + +
+ +### Режими змішування як у Photoshop + +![](03.jpg) + +
diff --git a/16/README.md b/16/README.md index 622ed23..79712f5 100644 --- a/16/README.md +++ b/16/README.md @@ -1,18 +1,19 @@ ## Image operations +Below you will see some examples with images where you can play around and uncomment some lines to see the corresponding results. ### Invert -
+
### Add, Substract, Multiply and others ![](02.jpg) -
+
### PS Blending modes ![](03.jpg) -
+
diff --git a/16/index.php b/16/index.php index 3ee01f6..0d6c399 100644 --- a/16/index.php +++ b/16/index.php @@ -1,6 +1,7 @@ - '; include($path."/footer.php"); ?> + + + diff --git a/README-ch.md b/README-ch.md index f5be68f..64df50e 100644 --- a/README-ch.md +++ b/README-ch.md @@ -100,6 +100,8 @@ Patricio 研习和实践精神疗法(psychotherapy)和表达性艺术治疗 感谢 Nahuel Coppero (Necsoft) 的 [西班牙语(español)](?lan=es) 翻译。 +感谢 [Manoylov Andriy](https://twitter.com/ManoylovAC) 的 [乌克兰语(українська)](?lan=ua) 翻译。 + 感谢 [Karim Naaji](http://karim.naaji.fr/) 在代码和想法上的支持和贡献。 感谢所有相信这个项目的人[contributed with fixes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) 以及大家的捐赠. diff --git a/README-de.md b/README-de.md index 690c386..d1e2402 100644 --- a/README-de.md +++ b/README-de.md @@ -97,6 +97,8 @@ Dank an [Andrea Rovescalli](https://www.earove.info) für die [italienische Üb Dank an [Michael Tischer](http://www.mitinet.de) für die [deutsche Übersetzung des Textes](?lan=de) +Dank an [Manoylov Andriy](https://twitter.com/ManoylovAC) für die [ukrainische Übersetzung des Textes (українська)](?lan=ua) + Und natürlich Danke an alle, die an dieses Projekt geglaubt, dafür gespendet oder durch Hinweise und Korrekturen [daran mitgewirkt haben](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors). ## Hol Dir die neuen Kapitel diff --git a/README-es.md b/README-es.md index 076d55b..ba8796b 100644 --- a/README-es.md +++ b/README-es.md @@ -83,6 +83,8 @@ Gracias a [Tong Li](https://www.facebook.com/tong.lee.9484) y a [Yi Zhang](https Gracias a [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) por la [Traducción al coreano (한국어).](?lan=kr) +Gracias a [Manoylov Andriy](https://twitter.com/ManoylovAC) por la [traducción al ucraniano (українська)](?lan=ua) + Gracias a [Karim Naaji](http://karim.naaji.fr/) por su contribución, su apoyo, su código y sus buenas ideas. Gracias a todos los que creyeron en este proyecto y [contribuyeron con sus aportes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) o donaciones. @@ -97,4 +99,4 @@ Suscribirse al newsletter o seguirnos en [Twitter](https://twitter.com/bookofsha formId: '623359074e5181d777e479f9', containerEl: '#fd-form-623359074e5181d777e479f9' }); - \ No newline at end of file + diff --git a/README-fa.md b/README-fa.md index 5fc851c..0da9cbf 100644 --- a/README-fa.md +++ b/README-fa.md @@ -102,6 +102,8 @@ ممنون از [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) برای Russian [translation (russian)](?lan=ru) +ممنون از [Manoylov Andriy](https://twitter.com/ManoylovAC) برای Ukrainian [translation (українська)](?lan=ua) + ممنون از [Andy Stanton](https://andy.stanton.is/) برای اصلاح و بهبود [the pdf/epub export pipeline](https://thebookofshaders.com/appendix/02/) ممنون از همه کسانی که به این پروژه ایمان داشتند و[در اصلاحات مشارکت کردند](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) و یا اهدا کردند. @@ -116,4 +118,4 @@ formId: '623359074e5181d777e479f9', containerEl: '#fd-form-623359074e5181d777e479f9' }); - \ No newline at end of file + diff --git a/README-fr.md b/README-fr.md index 5b07ca8..784a407 100644 --- a/README-fr.md +++ b/README-fr.md @@ -85,6 +85,8 @@ Merci à [Tong Li](https://www.facebook.com/tong.lee.9484) et [Yi Zhang](https:/ Merci à [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) pour la [traduction (한국어)](?lan=kr) coréenne +Merci à [Manoylov Andriy](https://twitter.com/ManoylovAC) pour la [traduction (українська)](?lan=ua) l'ukrainien + Merci à [Karim Naaji](http://karim.naaji.fr/) qui a contribué par son support, ses bonnes idées et son code. Merci à tous ceux qui ont cru en ce projet et à ceux qui ont [contributé aux corrections](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) ou qui ont fait des dons. diff --git a/README-id.md b/README-id.md index ec8bc38..1bcf0e3 100644 --- a/README-id.md +++ b/README-id.md @@ -106,6 +106,8 @@ Terima kasih kepada [Andy Stanton](https://andy.stanton.is/) untuk perbaikan dan Terima kasih kepada [Naufal Adriansyah](https://www.facebook.com/naufal.adrna08) untuk terjemahan [Bahasa Indonesia](?lan=id) +Terima kasih kepada [Manoylov Andriy](https://twitter.com/ManoylovAC) untuk terjemahan [Bahasa Ukraina (українська)](?lan=ua) + Terima kasih kepada semua orang yang telah percaya pada proyek ini dan [telah berkontribusi dalam perbaikan](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) atau donasi. ## Dapatkan bagian baru @@ -118,4 +120,4 @@ Daftar untuk surat berita atau follow di [Twitter](https://twitter.com/bookofsha formId: '623359074e5181d777e479f9', containerEl: '#fd-form-623359074e5181d777e479f9' }); - \ No newline at end of file + diff --git a/README-it.md b/README-it.md index 397a4aa..a274247 100644 --- a/README-it.md +++ b/README-it.md @@ -96,6 +96,8 @@ Grazie a [Nicolas Barradeau](https://twitter.com/nicoptere) e a [Karim Naaji](ht Grazie a [Andrea Rovescalli](https://www.earove.info) per la [traduzione](?lan=it) italiana +Grazie a [Manoylov Andriy](https://twitter.com/ManoylovAC) per la [traduzione ucraina (українська)](?lan=ua) + Grazie a tutti coloro i quali hanno creduto in questo progetto e [contribuito con correzioni](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) o donazioni. ## Come ottenere i nuovi capitoli? diff --git a/README-jp.md b/README-jp.md index 13d2f65..e14b761 100644 --- a/README-jp.md +++ b/README-jp.md @@ -89,6 +89,8 @@ Patricioは心理療法(psychotherapy)と表現療法(expressive art thera インスピレーションとアドバイスを与えてくれた[Scott Murray](http://alignedleft.com/)、日本語訳を担当してくれた[Kynd](https://twitter.com/kyndinfo)、素晴らしいアイデアとコードで貢献してくれた[Karim Naaji](http://karim.naaji.fr/) にも感謝します。 +[(українська) ウクライナ語](?lan=ua)の翻訳をしてくれた [Manoylov Andriy](https://twitter.com/ManoylovAC) にも感謝します。 + そして最後に、このプロジェクトを応援し[改善の手助けをしてくれた方々](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors)、寄付をくださったすべての皆様に感謝を述べたいと思います。 ## アップデートのお知らせ diff --git a/README-kr.md b/README-kr.md index 1b12b2b..57e1337 100644 --- a/README-kr.md +++ b/README-kr.md @@ -108,6 +108,8 @@ Patricio는 심리치료 및 표현예술을 공부했다. 그는 파슨스대 러시아어 번역을 맡고 있는 [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) 에게 감사를 표합니다. [Russian translation](?lan=ru) +러시아어 번역을 맡고 있는 [Manoylov Andriy](https://twitter.com/ManoylovAC) 에게 감사를 표합니다. [Ukrainian translation (українська)](?lan=ua) + [pdf/epub 배포](https://thebookofshaders.com/appendix/02/) 수정 및 개선을 맡고 있는 [Andy Stanton](https://andy.stanton.is/) 에게 감사를 표합니다. 이 프로젝트를 격려해주시고 기부해주신 모든 분들께 감사를 드립니다. [Contributed with fixes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) @@ -122,4 +124,4 @@ Patricio는 심리치료 및 표현예술을 공부했다. 그는 파슨스대 formId: '623359074e5181d777e479f9', containerEl: '#fd-form-623359074e5181d777e479f9' }); - \ No newline at end of file + diff --git a/README-pl.md b/README-pl.md index 3a7b1e3..c3ffe1a 100644 --- a/README-pl.md +++ b/README-pl.md @@ -106,6 +106,8 @@ Podziękowania dla [Vu Phuong Hoang](https://www.facebook.com/vuphuonghoang88) z Podziękowania dla [Wojciecha Pachowiaka](https://github.com/WojtekPachowiak) za polskie [tłumaczenie (polski)](?lan=pl) +Podziękowania dla [Manoylov Andriy](https://twitter.com/ManoylovAC) za ukraińskie [tłumaczenie (українська)](?lan=ua) + Podziękowania dla [Andy Stanton](https://andy.stanton.is/) za naprawę i usprawnienie funkcji [eksportu pdf/epub ](https://thebookofshaders.com/appendix/02/) Podziękowania dla każdego, kto [współtworzy](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) ten projekt poprzez swoje rady, korekty lub finansowe wsparcie. diff --git a/README-pt.md b/README-pt.md index 282ff4b..a45f17c 100644 --- a/README-pt.md +++ b/README-pt.md @@ -100,6 +100,8 @@ Obrigado [Michael Tischer](http://www.mitinet.de) pela [tradução em Alemão (d Obrigado [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) pela [tradução em Russo (russian)](?lan=ru) +Obrigado [Manoylov Andriy](https://twitter.com/ManoylovAC) pela [tradução em Ucraniano (українська)](?lan=ua) + Obrigado [Andy Stanton](https://andy.stanton.is/) por corrigir e melhorar [a pipeline para exportar pdf/epub](https://thebookofshaders.com/appendix/02/) Obrigado a todos que acreditaram neste projeto e [contribuíram com correções](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) ou doações. @@ -114,4 +116,4 @@ Assine a newsletter ou nos siga no [Twitter](https://twitter.com/bookofshaders) formId: '623359074e5181d777e479f9', containerEl: '#fd-form-623359074e5181d777e479f9' }); - \ No newline at end of file + diff --git a/README-ru.md b/README-ru.md index 5f0f1b9..33f142c 100644 --- a/README-ru.md +++ b/README-ru.md @@ -100,6 +100,8 @@ Спасибо [Сергею Карчевскому](https://www.facebook.com/sergey.karchevsky.3) за [русский перевод](?lan=ru) +Спасибо [Андрею Манойлову](https://twitter.com/ManoylovAC) за [украинский перевод](?lan=ua) + Спасибо всем кто поверил в этот проект и поддержал его [исправлениями](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) или пожертвованиями. ## Новые параграфы diff --git a/README-ua.md b/README-ua.md new file mode 100644 index 0000000..7e68747 --- /dev/null +++ b/README-ua.md @@ -0,0 +1,130 @@ + + +# The Book of Shaders +*автори: [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) і [Jen Lowe](http://jenlowe.net/)* + +Легкий покроковий провідник через абстрактний і складний всесвіт фрагментних шейдерів. + +
+ +
+ +## Зміст + +* [Про книгу](00/?lan=ua) + +* Вступ + * [Що таке шейдер?](01/?lan=ua) + * [“Hello world!”](02/?lan=ua) + * [Uniforms](03/?lan=ua) + * [Запуск шейдера](04/?lan=ua) + +* Алгоритмічне малювання + * [Формотворчі функції](05/?lan=ua) + * [Кольори](06/?lan=ua) + * [Фігури](07/?lan=ua) + * [Матриці](08/?lan=ua) + * [Патерни](09/?lan=ua) + +* Генеративний дизайн + * [Випадковість](10/?lan=ua) + * [Шум](11/?lan=ua) + * [Клітинний шум](12/?lan=ua) + * [Фрактальний броунівський рух](13/?lan=ua) + * Фрактали + +* Обробка зображень + * Текстури + * Операції із зображеннями + * Згортка ядра + * Фільтри + * Інші ефекти + +* Симуляції + * Пінг-понг + * Conway + * Брижі води + * Акварель + * Реакційно-дифузійна система + +* 3D-графіка + * Освітлення + * Карти нормалей + * Карти висот + * Ray marching + * Карти оточення (сферичні та кубічні) + * Відображення та заломлення + +* [Додаток:](appendix/?lan=ua) Інші способи використання цієї книги + * [Як можна переглядати книгу офлайн?](appendix/00/?lan=ua) + * [Як запустити приклади на Raspberry Pi?](appendix/01/?lan=ua) + * [Як надрукувати книгу?](appendix/02/?lan=ua) + * [Як прийняти участь у розвитку книги?](appendix/03/?lan=ua) + * [Вступ для тих, хто прийшов із JS](appendix/04/?lan=ua) від [Nicolas Barradeau](http://www.barradeau.com/) + +* [Галерея прикладів](examples/?lan=ua) + +* [Глосарій](glossary/?lan=ua) + +## Про авторів + +[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Буенос-Айрес, Аргентина) — митець і розробник із Нью-Йорка. Досліджує інтерстиціальний простір між органічним і синтетичним, аналоговим і цифровим, індивідуальним і колективним. У своїй роботі він використовує код як виразну мову з метою створення кращого разом. + +Патрісіо вивчав і практикував психотерапію та арттерапію. Він здобув ступінь магістра мистецтва в галузі дизайну та технологій у Parsons The New School, де зараз і викладає. Наразі він працює як графічний інженер в компанії Mapzen, розробляючи open-source інструменти для картографування. + +
WebSite - Twitter - GitHub - Vimeo - Flickr
+ +[Jen Lowe](http://jenlowe.net/) - незалежна наукова фахівчиня у галузі обробки та передачі даних в компанії Datatelling, де вона поєднує людей, числа та слова. Вона викладає у SVA Design для програми соціальних інновацій, співзасновниця School for Poetic Computation, викладала математику для художників в NYU ITP, проводила дослідження в Лабораторії просторового інформаційного дизайну у Колумбійському університеті та допомагала з ідеями в Білому домі стосовно управління науки та технологічної політики. Вона виступала на конференціях SXSW та Eyeo. Її роботи висвітлювалися в The New York Times та Fast Company. У своїх дослідженнях, публікаціях та виступах вона досліджує перспективи та наслідки використання даних і технологій у суспільстві. Має ступінь бакалавра з прикладної математики та магістра інформаційних наук. Часто займаючи опозиційну позицію, вона завжди на боці любові. + +
WebSite - Twitter - GitHub
+ +## Подяки + +Дякую [Scott Murray](http://alignedleft.com/) за натхнення та поради. + +Дякую [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo), [Nicolas Barradeau](https://twitter.com/nicoptere), [Karim Naaji](http://karim.naaji.fr/) за підтримку, гарні ідеї та код. + +Дякую [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) і [Sawako](https://twitter.com/sawakohome) за [японський переклад (日本語訳)](?lan=jp) + +Дякую [Tong Li](https://www.facebook.com/tong.lee.9484) і [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) за [китайський переклад (中文版)](?lan=ch) + +Дякую [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) і [June Kim](https://github.com/rlawns324) за [корейський переклад (한국어)](?lan=kr) + +Дякую Nahuel Coppero (Necsoft) за [іспанський переклад (español)](?lan=es) + +Дякую [Raphaela Protásio](https://github.com/Rawphs) і [Lucas Mendonça](https://github.com/luuchowl) за [португальський переклад (portugues)](?lan=pt) + +Дякую [Nicolas Barradeau](https://twitter.com/nicoptere) і [Karim Naaji](http://karim.naaji.fr/) за [французький переклад (français)](?lan=fr) + +Дякую [Andrea Rovescalli](https://www.earove.info) за [італійський переклад (italiano)](?lan=it) + +Дякую [Michael Tischer](http://www.mitinet.de) за [німецький переклад (deutsch)](?lan=de) + +Дякую [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) за [російський переклад](?lan=ru) + +Дякую [Vu Phuong Hoang](https://www.facebook.com/vuphuonghoang88) за [в'єтнамський переклад (Tiếng Việt)](?lan=vi) + +Дякую [Wojciech Pachowiak](https://github.com/WojtekPachowiak) за [польський переклад (polski)](?lan=pl) + +Дякую [Манойлову Андрію](https://twitter.com/ManoylovAC) за [український переклад](?lan=ua) + +Дякую [Andy Stanton](https://andy.stanton.is/) за виправлення та вдосконалення [the pdf/epub export pipeline](https://thebookofshaders.com/appendix/02/?lan=ua) + +Дякую всім, хто повірив у цей проект і [підтримував його виправленнями](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) або пожертвуваннями. + +## Нові розділи + +Для оповіщення про нові розділи, підпишіться на поштову розсилку або на [Twitter](https://twitter.com/bookofshaders) / Mastodon / [Discord](shader.zone) + +
+ + +## LICENSE + +Copyright (c) Patricio Gonzalez Vivo, 2015 - http://patriciogonzalezvivo.com/ +All rights reserved. diff --git a/README-vi.md b/README-vi.md index 6e37748..389be2a 100644 --- a/README-vi.md +++ b/README-vi.md @@ -104,6 +104,8 @@ Cảm ơn [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) vì Cảm ơn [Vu Phuong Hoang](https://github.com/DancingPhoenix88) và [Minh-Phuc Bui](https://github.com/phucbm) vì [Bản dịch tiếng Việt](?lan=vi) +Cảm ơn [Manoylov Andriy](https://twitter.com/ManoylovAC) vì [Bản dịch tiếng Ukraina (українська)](?lan=ua) + Cảm ơn [Andy Stanton](https://andy.stanton.is/) vì đã sửa lỗi và cải tiến [cách export quyển sách ra định dạng pdf/epub](https://thebookofshaders.com/appendix/02/?lan=vi) Cảm ơn tất cả mọi người đã tin tưởng, [cùng sửa lỗi](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) và quyên góp cho dự án này. diff --git a/README.md b/README.md index 13a12f7..d82c896 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ Thanks [Vu Phuong Hoang](https://www.facebook.com/vuphuonghoang88) for the Vietn Thanks [Wojciech Pachowiak](https://github.com/WojtekPachowiak) for the Polish [translation (polski)](?lan=pl) +Thanks [Manoylov Andriy](https://twitter.com/ManoylovAC) for the Ukrainian [translation (український переклад)](?lan=ua) + Thanks [Andy Stanton](https://andy.stanton.is/) for fixing and improving [the pdf/epub export pipeline](https://thebookofshaders.com/appendix/02/) Thanks to everyone who has believed in this project and [contributed with fixes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) or donations. diff --git a/appendix/00/README-ua.md b/appendix/00/README-ua.md new file mode 100644 index 0000000..90641f7 --- /dev/null +++ b/appendix/00/README-ua.md @@ -0,0 +1,33 @@ +## Як користуватись книгою офлайн? + +Припустимо, у вас довга подорож і ви хочете за цей час повчити шейдери. У такому випадку ви можете скопіювати книгу на свій комп'ютер і запустити її на локальному сервері. + +Для цього вам потрібні лише PHP, Python 3 і git-клієнт. На комп'ютерах MacOS і Raspberry Pi Python встановлено за замовчуванням, але потрібно ще встановити PHP і git-клієнт. Це можна зробити наступним чином: + +Для **MacOSX** переконайтесь, що у вас встановлено [homebrew](http://brew.sh/), після чого в терміналі виконайте наступні команди: + +```bash +brew update +brew upgrade +brew install git php +``` + +На **Raspberry Pi** встановіть [Raspbian](https://www.raspberrypi.org/downloads/raspbian/), дистрибутив Linux для Raspberry Pi на основі Debian, а потім виконайте наступні команди: + +```bash +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install git-core glslviewer php +``` + +Після того, як все буде встановлено, склонуйте проєкт та запустіть локальний сервер: + +```bash +cd ~ +git clone --recursive https://github.com/patriciogonzalezvivo/thebookofshaders.git +cd thebookofshaders +git submodule foreach git submodule init && git submodule update +php -S localhost:8000 +``` + +Потім відкрийте у своєму браузері адресу [`http://localhost:8000/`](http://localhost:8000/) diff --git a/appendix/00/index.php b/appendix/00/index.php index 00f2758..831b9fe 100644 --- a/appendix/00/index.php +++ b/appendix/00/index.php @@ -1,6 +1,7 @@ +``` + +Або так: + +```html +
+``` + +#### Тестування + +Запустіть локальний PHP-сервер у теці локального репозиторію: + +```bash +php -S localhost:8000 +``` + +Тепер у вашому браузері зайдіть на адресу [```localhost:8000```](http://localhost:8000), перейдіть до розділу, який ви перекладаєте, і додайте в кінці адреси такий рядок ```?lan=```, а після нього дві літери для позначення мови перекладу. + +Наприклад, якщо ви перекладаєте розділ ```03``` на французьку мову, значить ви працювали з файлом ```03/README-fr.md```, і ви можете перевірити його за адресою: ``` http://localhost:8000/03/?lan=fr``` + +### Покращення глосарію + +Цей розділ знаходиться в розробці. Ми раді вислухати ваші ідеї щодо його покращення, щоб зробити його корисним інструментом для всіх. Надсилайте свої пропозиції на [@bookofshaders](https://twitter.com/bookofshaders). + +### Редагування контенту + +Ми всі люди. Якщо ви побачите помилку, то сповістіть про неї, зробіть pull-request з виправленням або відкрийте issue. Дякую! + +### Діліться своїми прикладами шейдерів + +Ви побачите багато посилань на [онлайн-редактор](http://editor.thebookofshaders.com/) і його вбудовані у сторінки приклади з кодом. +Коли ви закодуєте щось корисне чи цікаве, натисніть «Export» (або піктограму ```⇪```) і надішліть його на адресу [@bookofshaders](https://twitter.com/bookofshaders) або [@kyndinfo](https://twitter.com/kyndinfo). Ми будемо раді переглянути його і додати до [галереї прикладів](https://thebookofshaders.com/examples/). diff --git a/appendix/03/index.php b/appendix/03/index.php index 00f2758..bcd5311 100644 --- a/appendix/03/index.php +++ b/appendix/03/index.php @@ -1,6 +1,7 @@ = 8.) break; +} +``` +Зауважте, що на деяких типах пристроїв ```break``` не працює належним чином і завчасно не перериває виконання циклу. + +Загалом, кількість ітерацій має бути якомога меншою, та і в цілому бажано уникати використання циклів і умовних галужень. + + +#### кваліфікатори + +Окрім типів змінних, GLSL використовує **кваліфікатори**. +Коротко кажучи, кваліфікатори допомагають повідомити компілятору призначення змінних. +Наприклад, деякі дані для GPU можуть бути надані тільки від CPU і називаються **атрибутами** та **уніформами**. +**Атрибути** використовуються у вершинних шейдерах, а **уніформи** можна використовувати як у вершинних, так і у фрагментних шейдерах. +Існує також кваліфікатор ```variying```, який використовується для передачі змінних від вершинного шейдеру до фрагментного. + +Я не буду вдаватися в деталі, оскільки ми зосереджені на **фрагментних шейдерах**, але далі в книзі ви побачите щось на кшталт: +```glsl +uniform vec2 u_resolution; +``` +Бачите, що ми тут зробили? Ми додали кваліфікатор ```uniform``` перед типом змінної. +Це означає, що змінна, яка відповідає за роздільну здатність полотна з яким ми працюємо, передається шейдеру з CPU. +Ширина полотна зберігається в x, а висота в y-компоненті даного 2D-вектора. + +Коли компілятор бачить змінну, якій передує цей кваліфікатор, він простежить, щоб ви не могли *змінити* такі значення під час рантайму. + +Те саме стосується нашої змінної ```count```, яка слугувала обмеженням для циклу ```for```: +```glsl +const float count = 10.; +for ( ... ) +``` +Коли ми використовуємо кваліфікатор ```const```, компілятор не дає змогу перезаписувати значення такої змінної, інакше вона не була б константою. + +У сигнатурах функцій можуть використовуватися 3 додаткові кваліфікатори: ```in```, ```out``` та ```inout```. +У JavaScript передані до функції значення скалярних аргументів доступні лише для читання. Якщо ви змінюєте їхні значення всередині функції, то ці зміни не застосовуються до змінної поза функцією. +```glsl +function banana(a) { + a += 1; +} + +var value = 0; +banana(value); +console.log(value); // 0 - значення за межами функції не змінилося +``` + +За допомогою кваліфікаторів перед аргументами ви можете вказати їх поведінку: +* ```in``` - лише для читання (за замовчуванням) +* ```out``` - лише для запису: можна змінити, але не можна прочитати значення +* ```inout``` - читання і запис: можна і прочитати й встановити нове значення + +Переписаний метод banana у GLSL виглядає так: +```glsl +void banana(inout float a) { + a += 1.; +} + +float A = 0.; +banana(A); // тепер A = 1.; +``` +Це дуже відрізняється від JS і є досить потужною можливістю, але вам не обов'язково вказувати кваліфікатори аргументів. За замовчуванням вони доступні лише для зчитування. + +#### простір і координати + +Останнє зауваження: у DOM і Canvas 2D ми звикли, що вісь Y спрямована 'вниз'. +Це має сенс у контексті DOM, оскільки відповідає способу розгортання вебсторінки: панель навігації вгорі, а контент прокручується донизу. +У полотні WebGL вісь Y перевернута і вказує 'вгору'. + +Це означає, що початок координат, точка (0, 0), знаходиться в нижньому лівому куті контексту WebGL, а не у верхньому лівому куті, як у 2D Canvas. +Координати текстур також дотримуються цього правила, що спочатку може бути контрінтуїтивним. + +## Ось і все! +Звісно, ми б могли більше заглибитися в різноманітні концепції, але, як згадувалося раніше, цей розділ написаний як просте введення для новачків. +Тут вже написано достатньо для того, щоб за деякий час переварити нові знання, але з терпінням і практикою ця мова ставатиме для вас все більш природною. + +Сподіваюся, цей матеріал був корисним для вас. А тепер як щодо початку вашої подорожі основною частиною книги? diff --git a/appendix/04/index.php b/appendix/04/index.php index 00f2758..9d42472 100644 --- a/appendix/04/index.php +++ b/appendix/04/index.php @@ -1,6 +1,7 @@ Створено за участі by kynd(@kyndinfo) та Patricio Gonzalez Vivo(@patriciogv)

+ +Це колекція прикладів, взятих із розділів цієї книги разом із шейдерами, люб'язно наданими іншими читачами за допомогою [онлайн-редактора](http://editor.thebookofshaders.com/). Не соромтеся досліджувати та змінювати їх. Якщо у вас вийде приклад, яким ви пишаєтеся, зробіть експорт своїх роботи та надішліть його на адресу [@bookofshaders](https://twitter.com/bookofshaders) або [@kyndinfo](https://twitter.com/kyndinfo). Ми з нетерпінням чекатимемо! diff --git a/glossary/README-ua.md b/glossary/README-ua.md new file mode 100644 index 0000000..335d9b9 --- /dev/null +++ b/glossary/README-ua.md @@ -0,0 +1,278 @@ +# Глосарій + +## За темою + +* ТИПИ + +[void](./?lan=ua&search=void) +[bool](./?lan=ua&search=bool) +[int](./?lan=ua&search=int) +[float](./?lan=ua&search=float) +[bvec2](./?lan=ua&search=bvec2) +[bvec3](./?lan=ua&search=bvec3) +[bvec4](./?lan=ua&search=bvec4) +[ivec2](./?lan=ua&search=ivec2) +[ivec3](./?lan=ua&search=ivec3) +[ivec4](./?lan=ua&search=ivec4) +[vec2](./?lan=ua&search=vec2) +[vec3](./?lan=ua&search=vec3) +[vec4](./?lan=ua&search=vec4) +[mat2](./?lan=ua&search=mat2) +[mat3](./?lan=ua&search=mat3) +[mat4](./?lan=ua&search=mat4) +[sampler2D](./?lan=ua&search=sampler2D) +[samplerCube](./?lan=ua&search=samplerCube) +[struct](./?lan=ua&search=struct) + +* КВАЛІФІКАТОРИ + +[attribute](./?lan=ua&search=attribute) +[const](./?lan=ua&search=const) +[uniform](./?lan=ua&search=uniform) +[varying](./?lan=ua&search=varying) +[precision](./?lan=ua&search=precision) +[highp](./?lan=ua&search=highp) +[mediump](./?lan=ua&search=mediump) +[lowp](./?lan=ua&search=lowp) +[in](./?lan=ua&search=in) +[out](./?lan=ua&search=out) +[inout](./?lan=ua&search=inout) + +* ВБУДОВАНІ ЗМІННІ + +[gl_Position](./?lan=ua&search=gl_Position) +[gl_PointSize](./?lan=ua&search=gl_PointSize) +[gl_PointCoord](./?lan=ua&gl_PointCoord) +[gl_FrontFacing](./?lan=ua&search=gl_FrontFacing) +[gl_FragCoord](./?lan=ua&search=gl_FragCoord) +[gl_FragColor](./?lan=ua&search=gl_FragColor) + +* ВБУДОВАНІ КОНСТАНТИ + +[gl_MaxVertexAttribs](./?lan=ua&search=gl_MaxVertexAttribs) +[gl_MaxVaryingVectors](./?lan=ua&search=gl_MaxVaryingVectors) +[gl_MaxVertexTextureImageUnits](./?lan=ua&search=gl_MaxVertexTextureImageUnits) +[gl_MaxCombinedTextureImageUnits](./?lan=ua&search=gl_MaxCombinedTextureImageUnits) +[gl_MaxTextureImageUnits](./?lan=ua&search=gl_MaxTextureImageUnits) +[gl_MaxFragmentUniformVectors](./?lan=ua&search=gl_MaxFragmentUniformVectors) +[gl_MaxDrawBuffers](./?lan=ua&search=gl_MaxDrawBuffers) + +* ТРИГОНОМЕТРИЧНІ ТА КУТОВІ ФУНКЦІЇ + +[radians()](./?lan=ua&search=radians) +[degrees()](./?lan=ua&search=degrees) +[sin()](./?lan=ua&search=sin) +[cos()](./?lan=ua&search=cos) +[tan()](./?lan=ua&search=tan) +[asin()](./?lan=ua&search=asin) +[acos()](./?lan=ua&search=acos) +[atan()](./?lan=ua&search=atan) + +* ЕКСПОНЕНЦІАЛЬНІ ФУНКЦІЇ + +[pow()](./?lan=ua&search=pow) +[exp()](./?lan=ua&search=exp) +[log()](./?lan=ua&search=log) +[exp2()](./?lan=ua&search=exp2) +[log2()](./?lan=ua&search=log2) +[sqrt()](./?lan=ua&search=sqrt) +[inversesqrt()](./?lan=ua&search=inversesqrt) + +* ЗАГАЛЬНІ ФУНКЦІЇ + +[abs()](./?lan=ua&search=abs) +[sign()](./?lan=ua&search=sign) +[floor()](./?lan=ua&search=floor) +[ceil()](./?lan=ua&search=ceil) +[fract()](./?lan=ua&search=fract) +[mod()](./?lan=ua&search=mod) +[min()](./?lan=ua&search=min) +[max()](./?lan=ua&search=max) +[clamp()](./?lan=ua&search=clamp) +[mix()](./?lan=ua&search=mix) +[step()](./?lan=ua&search=step) +[smoothstep()](./?lan=ua&search=smoothstep) + +* ГЕОМЕТРИЧНІ ФУНКЦІЇ + +[length()](./?lan=ua&search=length) +[distance()](./?lan=ua&search=distance) +[dot()](./?lan=ua&search=dot) +[cross()](./?lan=ua&search=cross) +[normalize()](./?lan=ua&search=normalize) +[facefoward()](./?lan=ua&search=facefoward) +[reflect()](./?lan=ua&search=reflect) +[refract()](./?lan=ua&search=refract) + +* МАТРИЧНІ ФУНКЦІЇ + +[matrixCompMult()](./?lan=ua&search=matrixCompMult) + +* ФУНКЦІЇ ПОВ'ЯЗАНІ З ВЕКТОРАМИ + +[lessThan()](./?lan=ua&search=lessThan) +[lessThanEqual()](./?lan=ua&search=lessThanEqual) +[greaterThan()](./?lan=ua&search=greaterThan) +[greaterThanEqual()](./?lan=ua&search=greaterThanEqual) +[equal()](./?lan=ua&search=equal) +[notEqual()](./?lan=ua&search=notEqual) +[any()](./?lan=ua&search=any) +[all()](./?lan=ua&search=all) +[not()](./?lan=ua&search=not) + +* ФУНКЦІЇ ПОВ'ЯЗАНІ З ТЕКСТУРАМИ + +[texture2D()](./?lan=ua&search=texture2D) +[textureCube()](./?lan=ua&search=textureCube) + +## За алфавітом + +* A + +[abs()](./?lan=ua&search=abs) +[acos()](./?lan=ua&search=acos) +[all()](./?lan=ua&search=all) +[any()](./?lan=ua&search=any) +[asin()](./?lan=ua&search=asin) +[atan()](./?lan=ua&search=atan) +[attribute](./?lan=ua&search=attribute) + +* B + +[bool](./?lan=ua&search=bool) +[bvec2](./?lan=ua&search=bvec2) +[bvec3](./?lan=ua&search=bvec3) +[bvec4](./?lan=ua&search=bvec4) + +* C + +[ceil()](./?lan=ua&search=ceil) +[clamp()](./?lan=ua&search=clamp) +[const](./?lan=ua&search=const) +[cos()](./?lan=ua&search=cos) +[cross()](./?lan=ua&search=cross) + +* D + +[degrees()](./?lan=ua&search=degrees) +[dFdx()](./?lan=ua&search=dFdx) +[dFdy()](./?lan=ua&search=dFdy) +[distance()](./?lan=ua&search=distance) +[dot()](./?lan=ua&search=dot) + +* E + +[equal()](./?lan=ua&search=equal) +[exp()](./?lan=ua&search=exp) +[exp2()](./?lan=ua&search=exp2) + +* F + +[faceforward()](./?lan=ua&search=faceforward) +[float](./?lan=ua&search=float) +[floor()](./?lan=ua&search=floor) +[fract()](./?lan=ua&search=fract) + +* G + +[greaterThan()](./?lan=ua&search=greaterThan) +[greaterThanEqual()](./?lan=ua&search=greaterThanEqual) +[gl_FragColor](./?lan=ua&search=gl_FragColor) +[gl_FragCoord](./?lan=ua&search=gl_FragCoord) +[gl_FrontFacing](./?lan=ua&search=gl_FrontFacing) +[gl_PointCoord](./?lan=ua&gl_PointCoord) +[gl_PointSize](./?lan=ua&search=gl_PointSize) +[gl_Position](./?lan=ua&search=gl_Position) +[gl_MaxCombinedTextureImageUnits](./?lan=ua&search=gl_MaxCombinedTextureImageUnits) +[gl_MaxDrawBuffers](./?lan=ua&search=gl_MaxDrawBuffers) +[gl_MaxFragmentUniformVectors](./?lan=ua&search=gl_MaxFragmentUniformVectors) +[gl_MaxVaryingVectors](./?lan=ua&search=gl_MaxVaryingVectors) +[gl_MaxVertexAttribs](./?lan=ua&search=gl_MaxVertexAttribs) +[gl_MaxVertexTextureImageUnits](./?lan=ua&search=gl_MaxVertexTextureImageUnits) +[gl_MaxTextureImageUnits](./?lan=ua&search=gl_MaxTextureImageUnits) + +* H + +[highp](./?lan=ua&search=highp) + +* I + +[in](./?lan=ua&search=in) +[inout](./?lan=ua&search=inout) +[int](./?lan=ua&search=int) +[inversesqrt()](./?lan=ua&search=inversesqrt) +[ivec2](./?lan=ua&search=ivec2) +[ivec3](./?lan=ua&search=ivec3) +[ivec4](./?lan=ua&search=ivec4) + +* L + +[length()](./?lan=ua&search=length) +[lessThan()](./?lan=ua&search=lessThan) +[lessThanEqual()](./?lan=ua&search=lessThanEqual) +[log()](./?lan=ua&search=log) +[log2()](./?lan=ua&search=log2) +[lowp](./?lan=ua&search=lowp) + +* M + +[matrixCompMult()](./?lan=ua&search=matrixCompMult) +[mat2](./?lan=ua&search=mat2) +[mat3](./?lan=ua&search=mat3) +[mat4](./?lan=ua&search=mat4) +[max()](./?lan=ua&search=max) +[mediump](./?lan=ua&search=mediump) +[min()](./?lan=ua&search=min) +[mix()](./?lan=ua&search=mix) +[mod()](./?lan=ua&search=mod) + +* N + +[normalize()](./?lan=ua&search=normalize) +[not()](./?lan=ua&search=not) +[notEqual()](./?lan=ua&search=notEqual) + +* O + +[out](./?lan=ua&search=out) + +* P + +[precision](./?lan=ua&search=precision) +[pow()](./?lan=ua&search=pow) + +* R + +[radians()](./?lan=ua&search=radians) +[reflect()](./?lan=ua&search=reflect) +[refract()](./?lan=ua&search=refract) +[return](./?lan=ua&search=return) + +* S + +[sampler2D](./?lan=ua&search=sampler2D) +[samplerCube](./?lan=ua&search=samplerCube) +[sign()](./?lan=ua&search=sign) +[sin()](./?lan=ua&search=sin) +[smoothstep()](./?lan=ua&search=smoothstep) +[sqrt()](./?lan=ua&search=sqrt) +[step()](./?lan=ua&search=step) +[struct](./?lan=ua&search=struct) + +* T + +[tan()](./?lan=ua&search=tan) +[texture2D()](./?lan=ua&search=texture2D) +[textureCube()](./?lan=ua&search=textureCube) + +* U + +[uniform](./?lan=ua&search=uniform) + +* V + +[varying](./?lan=ua&search=varying) +[vec2](./?lan=ua&search=vec2) +[vec3](./?lan=ua&search=vec3) +[vec4](./?lan=ua&search=vec4) +[void](./?lan=ua&search=void) diff --git a/glossary/abs/README-ua.md b/glossary/abs/README-ua.md new file mode 100644 index 0000000..f161f02 --- /dev/null +++ b/glossary/abs/README-ua.md @@ -0,0 +1,21 @@ +## abs +Повертає абсолютне значення параметра. + +### Оголошення +```glsl +float abs(float x) +vec2 abs(vec2 x) +vec3 abs(vec3 x) +vec4 abs(vec4 x) +``` + +### Параметри +**```x```** — значення, яке потрібно повернути в абсолют. + +### Опис +**```abs()```** повертає абсолютне значення **`x`**. + +
+ +### Дивіться також +[sign()](/glossary/?lan=ua&search=sign), [min()](/glossary/?lan=ua&search=min), [max()](/glossary/?lan=ua&search=max), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/acos/README-ua.md b/glossary/acos/README-ua.md new file mode 100644 index 0000000..b6d0672 --- /dev/null +++ b/glossary/acos/README-ua.md @@ -0,0 +1,21 @@ +## acos +Повертає арккосинус параметра + +### Оголошення +```glsl +float acos(float x) +vec2 acos(vec2 x) +vec3 acos(vec3 x) +vec4 acos(vec4 x) +``` + +### Параметри +**```x```** — значення, арккосинус якого потрібно повернути. + +### Опис +**```acos()```** повертає кут, тригонометричний косинус якого дорівнює **`x`**. + +
+ +### Дивіться також +[cos()](/glossary/?lan=ua&search=cos), [sin()](/glossary/?lan=ua&search=sin), [asin()](/glossary/?lan=ua&search=asin), [tan()](/glossary/?lan=ua&search=tan), [atan()](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/all/README-ua.md b/glossary/all/README-ua.md new file mode 100644 index 0000000..78e42e5 --- /dev/null +++ b/glossary/all/README-ua.md @@ -0,0 +1,31 @@ +## all +Перевіряє чи всі елементи логічного вектора істинні + +### Оголошення +```glsl +bool any(bvec2 x) +bool any(bvec3 x) +bool any(bvec4 x) +``` + +### Параметри +**```x```** — вектор, який буде перевірено на істинність. + +### Опис +**```all()```** повертає **`true`**, якщо всі елементи **`x`** мають значення **`true`**, інакше повертається **`false`**. Функціонально це еквівалентно до наступного коду: + +```glsl +bool all(bvec x) { // bvec може бути bvec2, bvec3 або bvec4 + bool result = true; + int i; + + for (i = 0; i < x.length(); ++i) { + result &= x[i]; + } + + return result; +} +``` + +### Дивіться також +[any()](/glossary/?lan=ua&search=any), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/any/README-ua.md b/glossary/any/README-ua.md new file mode 100644 index 0000000..502334e --- /dev/null +++ b/glossary/any/README-ua.md @@ -0,0 +1,31 @@ +## any +Перевіряє чи хоча б один елемент булевого вектора має значення true + +### Оголошення +```glsl +bool all(bvec2 x) +bool all(bvec3 x) +bool all(bvec4 x) +``` + +### Параметри +**```x```** — вектор, який буде перевірено на істинність. + +### Опис +**```any()```** повертає **`true`**, якщо будь-який елемент **`x`** має значення **`true`**, інакше повертається **`false`**. Функціонально це еквівалентно до наступного коду: + +```glsl +bool any(bvec x) { // bvec може бути bvec2, bvec3 або bvec4 + bool result = false; + int i; + + for (i = 0; i < x.length(); ++i) { + result |= x[i]; + } + + return result; +} +``` + +### Дивіться також +[any()](/glossary/?lan=ua&search=any), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/asin/README-ua.md b/glossary/asin/README-ua.md new file mode 100644 index 0000000..74137e5 --- /dev/null +++ b/glossary/asin/README-ua.md @@ -0,0 +1,21 @@ +## asin +Повертає арксинус параметра + +### Оголошення +```glsl +float asin(float x) +vec2 asin(vec2 x) +vec3 asin(vec3 x) +vec4 asin(vec4 x) +``` + +### Параметри +**```x```** — значення, арксинус якого потрібно повернути. + +### Опис +```asin()``` повертає кут, тригонометричний синус якого дорівнює **`x`** + +
+ +### Дивіться також +[cos](/glossary/?lan=ua&search=cos), [sin](/glossary/?lan=ua&search=sin), [acos](/glossary/?lan=ua&search=acos), [tan](/glossary/?lan=ua&search=tan), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/atan/README-ua.md b/glossary/atan/README-ua.md new file mode 100644 index 0000000..0db3065 --- /dev/null +++ b/glossary/atan/README-ua.md @@ -0,0 +1,32 @@ +## atan +Повертає арктангенс параметрів + +### Оголошення +```glsl +float atan(float y, float x) +vec2 atan(vec2 y, vec2 x) +vec3 atan(vec3 y, vec3 x) +vec4 atan(vec4 y, vec4 x) + +float atan(float y_over_x) +vec2 atan(vec2 y_over_x) +vec3 atan(vec3 y_over_x) +vec4 atan(vec4 y_over_x) +``` + +### Параметри +**```y```** — чисельник дробу, арктангенс якого потрібно повернути. + +**```x```** — знаменник дробу, арктангенс якого потрібно повернути. + +**```y_over_x```** — дріб, арктангенс якого потрібно повернути. + +### Опис +**```atan()```** повертає кут, тригонометричний арктангенс якого дорівнює **`y,x`** або **`y_over_x`**, залежно від того, яке саме перевантаження функції викликається. + +У першому перевантаженні знаки **`y`** і **`x`** використовуються для визначення квадранта, в якому лежить кут. Значення, які повертає **`atan`** у цьому випадку, знаходяться в діапазоні від -PI до PI. Результати не визначені, якщо **`x`** дорівнює нулю. + +Для другого перевантаження **```atan()```** повертає кут, тангенс якого дорівнює **```y_over_x```**. Значення, що повертаються в цьому випадку, знаходяться в діапазоні від -PI до PI. + +### Дивіться також +[cos](/glossary/?lan=ua&search=cos), [acos](/glossary/?lan=ua&search=acos), [sin](/glossary/?lan=ua&search=sin), [asin](/glossary/?lan=ua&search=asin), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua), [Розділ 06: Кольори](/06/?lan=ua) diff --git a/glossary/attribute/README-ua.md b/glossary/attribute/README-ua.md new file mode 100644 index 0000000..9d2ff73 --- /dev/null +++ b/glossary/attribute/README-ua.md @@ -0,0 +1,15 @@ +## attribute +Дані атрибутів вершин. + +### Приклад +```glsl +attribute vec4 v_color; +``` + +### Опис +**```attribute```** — змінні доступні лише для читання, що містять дані, які передаються із середовища WebGL/OpenGL у вершинний шейдер. + +Оскільки вершинний шейдер виконується один раз для кожної вершини, атрибути визначають дані для кожної вершини, як правило, з такою інформацією, як: положення в просторі, колір, напрямок нормалі та координати текстури вершини. + +### Дивіться також +[const](/glossary/?lan=ua&search=const), [uniform](/glossary/?lan=ua&search=uniform), [varying](/glossary/?lan=ua&search=varying), [Розділ 03: Uniforms](/03/?lan=ua) diff --git a/glossary/bool/README-ua.md b/glossary/bool/README-ua.md new file mode 100644 index 0000000..3fdcf2e --- /dev/null +++ b/glossary/bool/README-ua.md @@ -0,0 +1,15 @@ +## bool +Логічний тип даних (також булів, булевий, булівський) + +### Приклад +```glsl +bool aBool = true; +bool bBool = bool(aInt); +bool cBool = bool(aFloat); +``` + +### Опис +**```bool```** — використовується для позначення логічного типу даних. Приймає значення **true** або **false**. Також є одноіменна функція для приведення даних до відповідного типу. + +### Дивіться також +[void](/glossary/?lan=ua&search=void), [bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [struct](/glossary/?lan=ua&search=struct) diff --git a/glossary/bvec2/README-ua.md b/glossary/bvec2/README-ua.md new file mode 100644 index 0000000..f1a2826 --- /dev/null +++ b/glossary/bvec2/README-ua.md @@ -0,0 +1,21 @@ +## bvec2 +2-вимірний булевий вектор + +### Оголошення +```glsl +bvec2 aBvec2 = bvec2(true, true); +bvec2 bBvec2 = bvec2(true); + +bvec2 cBvec2 = bvec2(aBvec3); +bvec2 dBvec2 = bvec2(aBvec3.x, aBvec3.y); +``` + +### Опис +**```bvec2```** — булевий вектор з двома компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/bvec3/README-ua.md b/glossary/bvec3/README-ua.md new file mode 100644 index 0000000..eec750e --- /dev/null +++ b/glossary/bvec3/README-ua.md @@ -0,0 +1,25 @@ +## bvec3 +3-вимірний булевий вектор + +### Оголошення +```glsl +vec3 aBvec3 = bvec3(true, true, true); +vec3 bBvec3 = bvec3(true); + +vec3 cBvec3 = bvec3(aBvec4); +vec3 dBvec3 = bvec3(aBvec4.x, aBvec4.y, aBvec4.z); + +vec3 eBvec3 = bvec3(aBvec2, aBool); +vec3 fBvec3 = bvec3(aBvec2.x, aBvec2.y, aBool); +``` + +### Опис +**```bvec3```** — булевий вектор з трьома компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/bvec4/README-ua.md b/glossary/bvec4/README-ua.md new file mode 100644 index 0000000..febe74b --- /dev/null +++ b/glossary/bvec4/README-ua.md @@ -0,0 +1,21 @@ +## bvec4 +4-вимірний булевий вектор + +### Оголошення +```glsl +vec4 aBvec4 = bvec4(true, true, true, true); +vec4 bBvec4 = bvec4(true); + +vec4 cBvec4 = bvec4(aBvec2, aBool, aBvec3); +vec4 dBvec4 = bvec4(aBvec2.x, aBvec2.y, aBool, aBvec3.x); +``` + +### Опис +**```bvec4```** — булевий вектор з чотирма компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/ceil/README-ua.md b/glossary/ceil/README-ua.md new file mode 100644 index 0000000..fba3eeb --- /dev/null +++ b/glossary/ceil/README-ua.md @@ -0,0 +1,21 @@ +## ceil +Знаходить і повертає найближче ціле число, яке більше або дорівнює параметру + +### Оголошення +```glsl +float ceil(float x) +vec2 ceil(vec2 x) +vec3 ceil(vec3 x) +vec4 ceil(vec4 x) +``` + +### Параметри +**```x```** — значення для обробки. + +### Опис +**```ceil()```** повертає значення, що дорівнює найближчому цілому числу, яке більше або дорівнює **`x`**. + +
+ +### Дивіться також +[floor](/glossary/?lan=ua&search=floor), [fract](/glossary/?lan=ua&search=fract), [mod](/glossary/?lan=ua&search=mod), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/clamp/README-ua.md b/glossary/clamp/README-ua.md new file mode 100644 index 0000000..20e08bb --- /dev/null +++ b/glossary/clamp/README-ua.md @@ -0,0 +1,29 @@ +## clamp +Повертає значення в діапазоні між двома обмежувачами + +### Оголошення +```glsl +float clamp(float x, float minVal, float maxVal) +vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal) +vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal) +vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal) + +vec2 clamp(vec2 x, float minVal, float maxVal) +vec3 clamp(vec3 x, float minVal, float maxVal) +vec4 clamp(vec4 x, float minVal, float maxVal) +``` + +### Параметри +**```x```** — значення для обмеження. + +**```minVal```** — нижня межа діапазону. + +**```maxVal```** — верхня межа діапазону. + +### Опис +**```clamp()```** повертає значення **`x`** обмежене діапазоном від **`minVal`** до **`maxVal`**. Повернене значення обчислюється як **```min(max(x, minVal), maxVal)```**. + +
+ +### Дивіться також +[min](/glossary/?lan=ua&search=min), [abs](/glossary/?lan=ua&search=abs), [max](/glossary/?lan=ua&search=max), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/const/README-ua.md b/glossary/const/README-ua.md new file mode 100644 index 0000000..b42db54 --- /dev/null +++ b/glossary/const/README-ua.md @@ -0,0 +1,13 @@ +## const +Константний кваліфікатор + +### Приклад +```glsl +const float PI = 3.14159265359; +``` + +### Опис +**```const```** — кваліфікатор, який застосується перед оголошенням будь-якої змінної, щоб вказати, що значення цієї змінної не буде і не може бути змінено. + +### Дивіться також +[attribute](/glossary/?lan=ua&search=attribute), [uniform](/glossary/?lan=ua&search=uniform), [varying](/glossary/?lan=ua&search=varying) diff --git a/glossary/cos/README-ua.md b/glossary/cos/README-ua.md new file mode 100644 index 0000000..a79f3c9 --- /dev/null +++ b/glossary/cos/README-ua.md @@ -0,0 +1,21 @@ +## cos +Повертає косинус параметра + +### Оголошення +```glsl +float cos(float angle) +vec2 cos(vec2 angle) +vec3 cos(vec3 angle) +vec4 cos(vec4 angle) +``` + +### Параметри +**```angle```** — величина в радіанах, косинус якої потрібно повернути. + +### Опис +**```cos()```** повертає тригонометричний косинус кута. + +
+ +### Дивіться також +[acos](/glossary/?lan=ua&search=acos), [sin](/glossary/?lan=ua&search=sin), [asin](/glossary/?lan=ua&search=asin), [tan](/glossary/?lan=ua&search=tan), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/cross/README-ua.md b/glossary/cross/README-ua.md new file mode 100644 index 0000000..79e67bd --- /dev/null +++ b/glossary/cross/README-ua.md @@ -0,0 +1,18 @@ +## cross +Обчислює перехресний добуток двох векторів + +### Оголошення +```glsl +vec3 cross(vec3 x, vec3 y) +``` + +### Параметри +**```x```** — перший вектор. + +**```y```** — другий вектор. + +### Опис +**```cross()```** повертає перехресний добуток двох векторів, **`x`** та **`y`**. Вхідними параметрами можуть бути лише 3-компонентні вектори — **`vec3`**. Перехресний добуток еквівалентний добутку довжини векторів на синус (меншого) кута між **`x`** і **`y`**. + +### Дивіться також +[dot()](/glossary/?lan=ua&search=dot) diff --git a/glossary/dFdx/README-ua.md b/glossary/dFdx/README-ua.md new file mode 100644 index 0000000..6f210c5 --- /dev/null +++ b/glossary/dFdx/README-ua.md @@ -0,0 +1,16 @@ +## dFdx +Повертає часткову похідну аргументу відносно x + +### Оголошення +```glsl +genType dFdx(float x); +``` + +### Параметри +**```p```** — вираз, від якого потрібно взяти часткову похідну. + +### Опис +Доступний лише у фрагментному шейдері, **```dFdx```** повертає часткову похідну від виразу **`p`** у **`x`**. Похідні обчислюються за допомогою локальної різниці. Вирази, які передбачають похідні вищого порядку, такі як **```dFdx(dFdx(n))```** мають невизначені результати, як і похідні змішаного порядку, такі як **```dFdx(dFdy(n))```**. Передбачається, що вираз **`p`** є безперервним, і тому вирази, обчислені за допомогою нерівномірного потоку керування, можуть бути невизначеними. + +### Дивіться також +[dFdy()](/glossary/?lan=ua&search=dFdy) diff --git a/glossary/dFdy/README-ua.md b/glossary/dFdy/README-ua.md new file mode 100644 index 0000000..6d1f329 --- /dev/null +++ b/glossary/dFdy/README-ua.md @@ -0,0 +1,16 @@ +## dFdy +Повертає часткову похідну аргументу відносно y. + +### Оголошення +```glsl +genType dFdy(float y); +``` + +### Параметри +**```p```** — вираз, від якого потрібно взяти часткову похідну. + +### Опис +Ця функція доступна тільки у фрагментному шейдері, **```dFdy```** повертає часткову похідну виразу **```p```** по вісі **```y```**. Похідні обчислюються за допомогою локального диференціювання. Вирази, які передбачають похідні вищих порядків, такі як **```dFdy(dFdy(n))```** мають невизначені результати, так само як і похідні змішаних порядків, наприклад **```dFdy(dFdx(n))```**. Припускається, що вираз **```p```** є неперервним, тому вирази, які обчислюються з використанням нерівномірного потоку керування, можуть бути невизначеними. + +### Дивіться також +[dFdx()](/glossary/?lan=ua&search=dFdx) diff --git a/glossary/degrees/README-ua.md b/glossary/degrees/README-ua.md new file mode 100644 index 0000000..5c831a1 --- /dev/null +++ b/glossary/degrees/README-ua.md @@ -0,0 +1,21 @@ +## degrees +Конвертує передане значення у градуси + +### Оголошення +```glsl +float degrees(float radians) +vec2 degrees(vec2 radians) +vec3 degrees(vec3 radians) +vec4 degrees(vec4 radians) +``` + +### Параметри +**```radians```** — значення у радіанах, яке потрібно перетворити в градуси. + +### Опис +**```degrees()```** перетворює значення, передане в радіанах, у градуси. + +Обрахунок по формулі: ```(180.0 * radians) / PI``` + +### Дивіться також +[radians](/glossary/?lan=ua&search=radians) diff --git a/glossary/distance/README-ua.md b/glossary/distance/README-ua.md new file mode 100644 index 0000000..8d2770a --- /dev/null +++ b/glossary/distance/README-ua.md @@ -0,0 +1,23 @@ +## distance +Обчислює відстань між двома точками + +### Оголошення +```glsl +float distance(float p0, float p1) +float distance(vec2 p0, vec2 p1) +float distance(vec3 p0, vec3 p1) +float distance(vec4 p0, vec4 p1) +``` + +### Параметри +**```p0```** — перша точка. + +**```p1```** — друга точка. + +### Опис +**```distance()```** повертає відстань між двома точками **`p0`** і **`p1`**. + +
+ +### Дивіться також +[length()](/glossary/?lan=ua&search=length), [normalize()](/glossary/?lan=ua&search=normalize), [Розділ 07: Фігури](/07/?lan=ua) diff --git a/glossary/dot/README-ua.md b/glossary/dot/README-ua.md new file mode 100644 index 0000000..ca6245e --- /dev/null +++ b/glossary/dot/README-ua.md @@ -0,0 +1,24 @@ +## dot +Обчислює скалярний добуток двох векторів + +### Оголошення +```glsl +float dot(float x, float y) +float dot(vec2 x, vec2 y) +float dot(vec3 x, vec3 y) +float dot(vec4 x, vec4 y) +``` + +### Параметри +**```x```** — перший вектор. + +**```y```** — другий вектор. + +### Опис +**```dot()```** повертає скалярний добуток двох векторів, **`x`** та **`y`**. Тобто: "**```x[0] * y[0] + x[1] * y[1] +...```**" +Якщо **`x`** і **`y`** однакові, квадратний корінь із скалярного добутку еквівалентний довжині вектора. Вхідними параметрами можуть бути скаляри з типом **`float`** або відповідні вектори. У випадку скалярів функція **```dot()```** є тривіальною та повертає добуток **`x`** та **`y`**. + +
+ +### Дивіться також +[cross()](/glossary/?lan=ua&search=cross), [Розділ 07: Фігури](/07/?lan=ua) diff --git a/glossary/equal/README-ua.md b/glossary/equal/README-ua.md new file mode 100644 index 0000000..e2da5ed --- /dev/null +++ b/glossary/equal/README-ua.md @@ -0,0 +1,24 @@ +## equal +Виконує по-компонентне порівняння двох векторів + +### Оголошення +```glsl +bvec2 equal(vec2 x, vec2 y) +bvec3 equal(vec3 x, vec3 y) +bvec4 equal(vec4 x, vec4 y) + +bvec2 equal(ivec2 x, ivec2 y) +bvec3 equal(ivec3 x, ivec3 y) +bvec4 equal(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```equal()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] == y[i]```**". + +### Дивіться також +[lessThanEqual()](/glossary/?lan=ua&search=lessThanEqual), [lessThan()](/glossary/?lan=ua&search=lessThan), [greaterThanEqual()](/glossary/?lan=ua&search=greaterThanEqual), [greaterThan()](/glossary/?lan=ua&search=greaterThan), [notEqual()](/glossary/?lan=ua&search=notEqual), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/exp/README-ua.md b/glossary/exp/README-ua.md new file mode 100644 index 0000000..3b5a4d3 --- /dev/null +++ b/glossary/exp/README-ua.md @@ -0,0 +1,22 @@ +## exp +Повертає експоненту параметра — число Ейлера піднесене до заданого степеня. +Число Ейлера або **`e`** приблизно дорівнює 2.718281828 + +### Оголошення +```glsl +float exp(float x) +vec2 exp(vec2 x) +vec3 exp(vec3 x) +vec4 exp(vec4 x) +``` + +### Параметри +**```x```** — степінь до якого потрібно піднести число Ейлера. + +### Опис +**```exp()```** повертає число **`e`** піднесене до степеня **`x`**. + +
+ +### Дивіться також +[log](/glossary/?lan=ua&search=log), [log2](/glossary/?lan=ua&search=log2), [exp2](/glossary/?lan=ua&search=exp2), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/exp2/README-ua.md b/glossary/exp2/README-ua.md new file mode 100644 index 0000000..f51b4a3 --- /dev/null +++ b/glossary/exp2/README-ua.md @@ -0,0 +1,21 @@ +## exp2 +Повертає число 2 піднесене до заданого степеня. + +### Оголошення +```glsl +float exp2(float x) +vec2 exp2(vec2 x) +vec3 exp2(vec3 x) +vec4 exp2(vec4 x) +``` + +### Параметри +**```x```** — значення степеня, до якого буде піднесено число 2. + +### Опис +**```exp2()```** повертає число 2 у степені **`x`**. + +
+ +### Дивіться також +[log](/glossary/?lan=ua&search=log), [log2](/glossary/?lan=ua&search=log2), [exp](/glossary/?lan=ua&search=exp), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/faceforward/README-ua.md b/glossary/faceforward/README-ua.md new file mode 100644 index 0000000..79ce5e4 --- /dev/null +++ b/glossary/faceforward/README-ua.md @@ -0,0 +1,23 @@ +## faceforward +Повертає вектор, що вказує в тому ж напрямку, що й інший + +### Оголошення +```glsl +float faceforward(float N, float I, float Nref) +vec2 faceforward(vec2 N, vec2 I, vec2 Nref) +vec3 faceforward(vec3 N, vec3 I, vec3 Nref) +vec4 faceforward(vec4 N, vec4 I, vec4 Nref) +``` + +### Параметри +**```N```** — вектор для орієнтації. + +**```I```** — вектор інциденту. + +**```Nref```** — опорний вектор. + +### Опис +**```faceforward()```** орієнтує вектор так, щоб він був направлений від поверхні, яка визначена її нормаллю. Якщо **```If dot(Nref, I) < 0```** функція повертає **`N`**, інакше **`-N`**. + +### Дивіться також +[reflect()](/glossary/?lan=ua&search=reflect), [refract()](/glossary/?lan=ua&search=refract) diff --git a/glossary/float/README-ua.md b/glossary/float/README-ua.md new file mode 100644 index 0000000..ea55469 --- /dev/null +++ b/glossary/float/README-ua.md @@ -0,0 +1,15 @@ +## float +Тип даних для чисел з рухомою крапкою + +### Приклад +```glsl +float aFloat = 1.0; +float bFloat = float(aBool); +float cFloat = float(aInt); +``` + +### Опис +**```float```** — використовується для позначення змінних із числами з рухомою крапкою. Також є одноіменна функція для приведення даних до відповідного типу. + +### Дивіться також +[void](/glossary/?lan=ua&search=void), [bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [struct](/glossary/?lan=ua&search=struct) diff --git a/glossary/floor/README-ua.md b/glossary/floor/README-ua.md new file mode 100644 index 0000000..1c12a4c --- /dev/null +++ b/glossary/floor/README-ua.md @@ -0,0 +1,21 @@ +## floor +Знаходить і повертає найближче ціле число, яке менше або дорівнює параметру + +### Оголошення +```glsl +float floor(float x) +vec2 floor(vec2 x) +vec3 floor(vec3 x) +vec4 floor(vec4 x) +``` + +### Параметри +**```x```** — значення для обробки. + +### Опис +**```floor()```** повертає значення, що дорівнює найближчому цілому числу, яке менше або дорівнює **`x`**. + +
+ +### Дивіться також +[ceil](/glossary/?lan=ua&search=ceil), [fract](/glossary/?lan=ua&search=fract), [mod](/glossary/?lan=ua&search=mod), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/fract/README-ua.md b/glossary/fract/README-ua.md new file mode 100644 index 0000000..6e3b06b --- /dev/null +++ b/glossary/fract/README-ua.md @@ -0,0 +1,21 @@ +## fract +Повертає дробову частину аргументу + +### Оголошення +```glsl +float fract(float x) +vec2 fract(vec2 x) +vec3 fract(vec3 x) +vec4 fract(vec4 x) +``` + +### Параметри +**```x```** — значення для обробки. + +### Опис +**```fract()```** повертає дробову частину від **`x`**. Це обчислюється як **```x - floor(x)```**. + +
+ +### Дивіться також +[floor](/glossary/?lan=ua&search=floor), [ceil](/glossary/?lan=ua&search=ceil), [mod](/glossary/?lan=ua&search=mod), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/gl_FragColor/README-ua.md b/glossary/gl_FragColor/README-ua.md new file mode 100644 index 0000000..79163a8 --- /dev/null +++ b/glossary/gl_FragColor/README-ua.md @@ -0,0 +1,9 @@ +## gl_FragColor + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_FragCoord/README-ua.md b/glossary/gl_FragCoord/README-ua.md new file mode 100644 index 0000000..2b0eea5 --- /dev/null +++ b/glossary/gl_FragCoord/README-ua.md @@ -0,0 +1,9 @@ +## gl_FragCoord + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_FragCoord/README.md b/glossary/gl_FragCoord/README.md index 8aac4f7..acd76d3 100644 --- a/glossary/gl_FragCoord/README.md +++ b/glossary/gl_FragCoord/README.md @@ -1,4 +1,4 @@ -## G_FragCoord +## Gl_FragCoord ### Declaration / Example diff --git a/glossary/gl_FrontFacing/README-ua.md b/glossary/gl_FrontFacing/README-ua.md new file mode 100644 index 0000000..c8a81e3 --- /dev/null +++ b/glossary/gl_FrontFacing/README-ua.md @@ -0,0 +1,9 @@ +## gl_FrontFacing + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxCombinedTextureImageUnits/README-ua.md b/glossary/gl_MaxCombinedTextureImageUnits/README-ua.md new file mode 100644 index 0000000..05e28dc --- /dev/null +++ b/glossary/gl_MaxCombinedTextureImageUnits/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxCombinedTextureImages + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxDrawBuffers/README-ua.md b/glossary/gl_MaxDrawBuffers/README-ua.md new file mode 100644 index 0000000..943596a --- /dev/null +++ b/glossary/gl_MaxDrawBuffers/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxDrawBuffers + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxFragmentUniformVectors/README-ua.md b/glossary/gl_MaxFragmentUniformVectors/README-ua.md new file mode 100644 index 0000000..d8c4df0 --- /dev/null +++ b/glossary/gl_MaxFragmentUniformVectors/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxFragmentUniformVectors + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxTextureImageUnits/README-ua.md b/glossary/gl_MaxTextureImageUnits/README-ua.md new file mode 100644 index 0000000..965ca6a --- /dev/null +++ b/glossary/gl_MaxTextureImageUnits/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxTextureImageUnits + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxVaryingVectors/README-ua.md b/glossary/gl_MaxVaryingVectors/README-ua.md new file mode 100644 index 0000000..a377986 --- /dev/null +++ b/glossary/gl_MaxVaryingVectors/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxVaryingVectors + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxVertexAttribs/README-ua.md b/glossary/gl_MaxVertexAttribs/README-ua.md new file mode 100644 index 0000000..1afd967 --- /dev/null +++ b/glossary/gl_MaxVertexAttribs/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxVertexAttribs + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_MaxVertexTextureImageUnits/README-ua.md b/glossary/gl_MaxVertexTextureImageUnits/README-ua.md new file mode 100644 index 0000000..d86d6b1 --- /dev/null +++ b/glossary/gl_MaxVertexTextureImageUnits/README-ua.md @@ -0,0 +1,9 @@ +## gl_MaxVertexTextureImageUnits + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_PointCoord/README-ua.md b/glossary/gl_PointCoord/README-ua.md new file mode 100644 index 0000000..a11af02 --- /dev/null +++ b/glossary/gl_PointCoord/README-ua.md @@ -0,0 +1,9 @@ +## gl_PointCoord + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_PointSize/README-ua.md b/glossary/gl_PointSize/README-ua.md new file mode 100644 index 0000000..7363cfe --- /dev/null +++ b/glossary/gl_PointSize/README-ua.md @@ -0,0 +1,9 @@ +## gl_PointSize + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/gl_Position/README-ua.md b/glossary/gl_Position/README-ua.md new file mode 100644 index 0000000..3eaafb0 --- /dev/null +++ b/glossary/gl_Position/README-ua.md @@ -0,0 +1,9 @@ +## gl_Position + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/greaterThan/README-ua.md b/glossary/greaterThan/README-ua.md new file mode 100644 index 0000000..3b1d0eb --- /dev/null +++ b/glossary/greaterThan/README-ua.md @@ -0,0 +1,24 @@ +## greaterThan +Виконує по-компонентне порівняння двох векторів на більшість компонентів першого вектора по відношенню до другого + +### Оголошення +```glsl +bvec2 greaterThan(vec2 x, vec2 y) +bvec3 greaterThan(vec3 x, vec3 y) +bvec4 greaterThan(vec4 x, vec4 y) + +bvec2 greaterThan(ivec2 x, ivec2 y) +bvec3 greaterThan(ivec3 x, ivec3 y) +bvec4 greaterThan(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```greaterThan()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] > y[i]```**". + +### Дивіться також +[lessThanEqual()](/glossary/?lan=ua&search=lessThanEqual), [lessThan()](/glossary/?lan=ua&search=lessThan), [greaterThanEqual()](/glossary/?lan=ua&search=greaterThanEqual), [equal()](/glossary/?lan=ua&search=equal), [notEqual()](/glossary/?lan=ua&search=notEqual), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/greaterThanEqual/README-ua.md b/glossary/greaterThanEqual/README-ua.md new file mode 100644 index 0000000..09ae957 --- /dev/null +++ b/glossary/greaterThanEqual/README-ua.md @@ -0,0 +1,24 @@ +## greaterThanEqual +Виконує по-компонентне порівняння двох векторів на більшість або рівність компонентів першого вектора по відношенню до другого + +### Оголошення +```glsl +bvec2 greaterThanEqual(vec2 x, vec2 y) +bvec3 greaterThanEqual(vec3 x, vec3 y) +bvec4 greaterThanEqual(vec4 x, vec4 y) + +bvec2 greaterThanEqual(ivec2 x, ivec2 y) +bvec3 greaterThanEqual(ivec3 x, ivec3 y) +bvec4 greaterThanEqual(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```greaterThanEqual()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] ≥ y[i]```**". + +### Дивіться також +[lessThanEqual()](/glossary/?lan=ua&search=lessThanEqual), [lessThan()](/glossary/?lan=ua&search=lessThan), [greaterThan()](/glossary/?lan=ua&search=greaterThan), [equal()](/glossary/?lan=ua&search=equal), [notEqual()](/glossary/?lan=ua&search=notEqual), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/highp/README-ua.md b/glossary/highp/README-ua.md new file mode 100644 index 0000000..c39e41f --- /dev/null +++ b/glossary/highp/README-ua.md @@ -0,0 +1,16 @@ +## highp +Кваліфікатор точності, задається на початку шейдера + +### Приклад +```glsl +precision highp float; +precision highp int; +``` + +### Опис +Кваліфікатор точності оголошує мінімальний діапазон і точність, які повинні використовуватися під час зберігання змінних відповідного типу. + +**```highp```** — 32+ біт, діапазон для **`float`** від -2^62 to +2^62, діапазон для **`int`** від -2^16 до 2^16 + +### Дивіться також +[lowp](/glossary/?lan=ua&search=lowp), [mediump](/glossary/?lan=ua&search=mediump), [precision](/glossary/?lan=ua&search=precision) diff --git a/glossary/in/README-ua.md b/glossary/in/README-ua.md new file mode 100644 index 0000000..5d71ade --- /dev/null +++ b/glossary/in/README-ua.md @@ -0,0 +1,26 @@ +## in +Кваліфікатор доступу аргументів. Позначає аргумент лише на читання. Застосовується по замовчуванню. + +### Приклад +```glsl +// Кваліфікатор "in" можна не прописувати явно, бо він застосовується по замовчуванню +float updateValue(in float x) { + // ці зміни для змінної "х" відбудуться лише усередині функції + x = x + x; // x = (0.5 + 0.5) = 1.0 + + return x; // 1.0 +} + +void main() { + float x = 0.5; + float totalSum = updateValue(x); // totalSum == 1.0 + + // x == 0.5, оскільки параметр був переданий лише на читання, то після виконання функції його значення залишається як і було +} +``` + +### Опис +**```in```** — кваліфікатор доступу аргументів, який дозволяє лише читати позначену змінну. Зміни всередині функції не вплинуть на значення переданої змінної поза її межами. + +### Дивіться також +[out](/glossary/?lan=ua&search=out), [inout](/glossary/?lan=ua&search=inout) diff --git a/glossary/index.php b/glossary/index.php index 104e1be..842fe37 100644 --- a/glossary/index.php +++ b/glossary/index.php @@ -1,9 +1,10 @@ + +### Дивіться також +[pow](/glossary/?lan=ua&search=pow), [sqrt](/glossary/?lan=ua&search=sqrt), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/ivec2/README-ua.md b/glossary/ivec2/README-ua.md new file mode 100644 index 0000000..c1689eb --- /dev/null +++ b/glossary/ivec2/README-ua.md @@ -0,0 +1,21 @@ +## ivec2 +2-вимірний цілочисельний вектор + +### Оголошення +```glsl +bvec2 aIvec2 = ivec2(1, 1); +bvec2 bIvec2 = ivec2(1); + +bvec2 cIvec2 = ivec2(aIvec3); +bvec2 dIvec2 = ivec2(aIvec3.x, aIvec3.y); +``` + +### Опис +**```ivec2```** — цілочисельний вектор із двома компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?slan=ua&earch=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/ivec3/README-ua.md b/glossary/ivec3/README-ua.md new file mode 100644 index 0000000..04a0d6b --- /dev/null +++ b/glossary/ivec3/README-ua.md @@ -0,0 +1,25 @@ +## ivec3 +3-вимірний цілочисельний вектор + +### Оголошення +```glsl +vec3 aIvec3 = ivec3(1, 1, 1); +vec3 bIvec3 = ivec3(1); + +vec3 cIvec3 = ivec3(aIvec4); +vec3 dIvec3 = ivec3(aIvec4.x, aIvec4.y, aIvec4.z); + +vec3 eIvec3 = ivec3(aIvec2, aInt); +vec3 fIvec3 = ivec3(aIvec2.x, aIvec2.y, aInt); +``` + +### Опис +**```ivec3```** — цілочисельний вектор із трьома компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/ivec4/README-ua.md b/glossary/ivec4/README-ua.md new file mode 100644 index 0000000..59870aa --- /dev/null +++ b/glossary/ivec4/README-ua.md @@ -0,0 +1,21 @@ +## ivec4 +4-вимірний цілочисельний вектор + +### Оголошення +```glsl +vec4 aIvec4 = ivec4(1, 1, 1, 1); +vec4 bIvec4 = ivec4(1); + +vec4 cIvec4 = ivec4(aIvec2, aInteger, aIvec3); +vec4 dIvec4 = ivec4(aIvec2.x, aIvec2.y, aInt, aIvec3.x); +``` + +### Опис +**```ivec4```** — цілочисельний вектор із чотирма компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/length/README-ua.md b/glossary/length/README-ua.md new file mode 100644 index 0000000..ae93043 --- /dev/null +++ b/glossary/length/README-ua.md @@ -0,0 +1,21 @@ +## length +Обчислює довжину вектора + +### Оголошення +```glsl +float length(float x) +float length(vec2 x) +float length(vec3 x) +float length(vec4 x) +``` + +### Параметри +**```x```** — вектор, довжину якого потрібно обчислити. + +### Опис +**```length()```** повертає довжину вектора. + +
+ +### Дивіться також +[distance()](/glossary/?lan=ua&search=distance), [normalize()](/glossary/?lan=ua&search=normalize), [Розділ 07: Фігури](/07/?lan=ua) diff --git a/glossary/lessThan/README-ua.md b/glossary/lessThan/README-ua.md new file mode 100644 index 0000000..62e5b8a --- /dev/null +++ b/glossary/lessThan/README-ua.md @@ -0,0 +1,24 @@ +## lessThan +Виконує по-компонентне порівняння двох векторів на меншість компонентів першого вектора по відношенню до другого + +### Оголошення +```glsl +bvec2 lessThan(vec2 x, vec2 y) +bvec3 lessThan(vec3 x, vec3 y) +bvec4 lessThan(vec4 x, vec4 y) + +bvec2 lessThan(ivec2 x, ivec2 y) +bvec3 lessThan(ivec3 x, ivec3 y) +bvec4 lessThan(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```lessThan()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] < y[i]```**". + +### Дивіться також +[lessThanEqual()](/glossary/?lan=ua&search=lessThanEqual), [greaterThan()](/glossary/?lan=ua&search=greaterThan), [greaterThanEqual()](/glossary/?lan=ua&search=greaterThanEqual), [equal()](/glossary/?lan=ua&search=equal), [notEqual()](/glossary/?lan=ua&search=notEqual), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/lessThanEqual/README-ua.md b/glossary/lessThanEqual/README-ua.md new file mode 100644 index 0000000..2a857d4 --- /dev/null +++ b/glossary/lessThanEqual/README-ua.md @@ -0,0 +1,24 @@ +## lessThanEqual +Виконує по-компонентне порівняння двох векторів на меншість або рівність компонентів першого вектора по відношенню до другого + +### Оголошення +```glsl +bvec2 lessThanEqual(vec2 x, vec2 y) +bvec3 lessThanEqual(vec3 x, vec3 y) +bvec4 lessThanEqual(vec4 x, vec4 y) + +bvec2 lessThanEqual(ivec2 x, ivec2 y) +bvec3 lessThanEqual(ivec3 x, ivec3 y) +bvec4 lessThanEqual(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```lessThanEqual()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] ≤ y[i]```**". + +### Дивіться також +[lessThan()](/glossary/?lan=ua&search=lessThan), [greaterThan()](/glossary/?lan=ua&search=greaterThan), [greaterThanEqual()](/glossary/?lan=ua&search=greaterThanEqual), [equal()](/glossary/?lan=ua&search=equal), [notEqual()](/glossary/?lan=ua&search=notEqual), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/log/README-ua.md b/glossary/log/README-ua.md new file mode 100644 index 0000000..e247410 --- /dev/null +++ b/glossary/log/README-ua.md @@ -0,0 +1,22 @@ +## log +Повертає натуральний логарифм параметра. +Тобто повертає значення до якого степеня слід піднести число Ейлера, щоб одержати вказане число. Число Ейлера або **`e`** приблизно дорівнює 2.718281828. + +### Оголошення +```glsl +float log(float x) +vec2 log(vec2 x) +vec3 log(vec3 x) +vec4 log(vec4 x) +``` + +### Параметри +**```x```** — значення, яке потрібно взяти в натуральний логарифм. + +### Опис +**```log()```** повертає натуральний логарифм числа **`x`**. + +
+ +### Дивіться також +[log2](/glossary/?lan=ua&search=log2), [exp](/glossary/?lan=ua&search=exp), [exp2](/glossary/?lan=ua&search=exp2), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/log2/README-ua.md b/glossary/log2/README-ua.md new file mode 100644 index 0000000..ab2be95 --- /dev/null +++ b/glossary/log2/README-ua.md @@ -0,0 +1,22 @@ +## log2 +Повертає логарифм числа за основою 2. +Тобто повертає степінь яка необхідна для двійки, щоб отримати передане число. + +### Оголошення +```glsl +float log2(float x) +vec2 log2(vec2 x) +vec3 log2(vec3 x) +vec4 log2(vec4 x) +``` + +### Параметри +**```x```** — значення, яке потрібно взяти за логарифмом з основою 2. + +### Опис +**```log2()```** повертає логарифм числа **`x`** з основою 2. + +
+ +### Дивіться також +[log](/glossary/?lan=ua&search=log), [exp](/glossary/?lan=ua&search=exp), [exp2](/glossary/?lan=ua&search=exp2), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/lowp/README-ua.md b/glossary/lowp/README-ua.md new file mode 100644 index 0000000..7f63306 --- /dev/null +++ b/glossary/lowp/README-ua.md @@ -0,0 +1,16 @@ +## lowp +Кваліфікатор точності, задається на початку шейдера + +### Приклад +```glsl +precision lowp float; +precision lowp int; +``` + +### Опис +Кваліфікатор точності оголошує мінімальний діапазон і точність, які повинні використовуватися під час зберігання змінних відповідного типу. + +**```lowp```** — 8+ біт, діапазон для **`float`** від -2 до 2, діапазон для **`int`** від -2^8 до 2^8 + +### Дивіться також +[mediump](/glossary/?lan=ua&search=mediump), [highp](/glossary/?lan=ua&search=highp), [precision](/glossary/?lan=ua&search=precision) diff --git a/glossary/main/README-ua.md b/glossary/main/README-ua.md new file mode 100644 index 0000000..54ce069 --- /dev/null +++ b/glossary/main/README-ua.md @@ -0,0 +1,9 @@ +## main + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/mat2/README-ua.md b/glossary/mat2/README-ua.md new file mode 100644 index 0000000..5dc0731 --- /dev/null +++ b/glossary/mat2/README-ua.md @@ -0,0 +1,37 @@ +## mat2 +Матриця розміром 2x2 зі значеннями типу float + +### Оголошення +```glsl +mat2 aMat2 = mat2( + 1.0, 0.0, // 1. column + 0.0, 1.0 // 2. column +); +mat2 bMat2 = mat2(1.0); + +mat2 cMat2 = mat2(aVec2, bVec2); +mat2 dMat2 = mat2(aVec3, aFloat); +``` + +### Опис +**```mat2```** — тип даних, що є матрицею розміром 2x2 із значеннями типу **`float`**. Як видно із прикладу вище, ініціалізувати можна різними способами: + +- надання значень для кожного компонента стовпець за стовпцем; + +- надання одного значення, яке використовується для компонентів на головній діагоналі; + +- надання комбінації векторів і скалярів; + +Так само можна отримати доступ до даних покомпонентно або стовпець за стовпцем: + +```glsl +mat2 aMat2; +aMat2[1][1] = 1.0; +float aFloat = aMat2[1][1]; + +aMat2[0] = vec2(1.0); +vec2 aVec2 = aMat2[0]; +``` + +### Дивіться також +[mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4), [matrixCompMult()](/glossary/?lan=ua&search=matrixCompMult) diff --git a/glossary/mat3/README-ua.md b/glossary/mat3/README-ua.md new file mode 100644 index 0000000..bc9a5f5 --- /dev/null +++ b/glossary/mat3/README-ua.md @@ -0,0 +1,38 @@ +## mat3 +Матриця розміром 3x3 зі значеннями типу float + +### Оголошення +```glsl +mat3 aMat3 = mat3( + 1.0, 0.0, 0.0, // 1. column + 0.0, 1.0, 0.0, // 2. column + 0.0, 0.0, 1.0 // 3. column +); +mat3 bMat3 = mat3(1.0); + +mat3 cMat3 = mat3(aVec3, bVec3, cVec3); +mat3 dMat3 = mat3(aVec4, aVec3, bVec4, aFloat); +``` + +### Опис +**```mat3```** — тип даних, що є матрицею розміром 3x3 із значеннями типу **`float`**. Як видно із прикладу вище, ініціалізувати можна різними способами: + +- надання значень для кожного компонента стовпець за стовпцем; + +- надання одного значення, яке використовується для компонентів на головній діагоналі; + +- надання комбінації векторів і скалярів; + +Так само можна отримати доступ до даних покомпонентно або стовпець за стовпцем: + +```glsl +mat3 aMat3; +aMat3[2][2] = 1.0; +float aFloat = aMat3[2][2]; + +aMat3[0] = vec3(1.0); +vec3 aVec3 = aMat3[0]; +``` + +### Дивіться також +[mat2](/glossary/?lan=ua&search=mat2), [mat4](/glossary/?lan=ua&search=mat4), [matrixCompMult()](/glossary/?lan=ua&search=matrixCompMult) diff --git a/glossary/mat4/README-ua.md b/glossary/mat4/README-ua.md new file mode 100644 index 0000000..b6ee111 --- /dev/null +++ b/glossary/mat4/README-ua.md @@ -0,0 +1,38 @@ +## mat4 +Матриця розміром 4x4 зі значеннями типу float + +### Оголошення +```glsl +mat4 aMat4 = mat4( + 1.0, 0.0, 0.0, 0.0, // 1. column + 0.0, 1.0, 0.0, 0.0, // 2. column + 0.0, 0.0, 1.0, 0.0, // 3. column + 0.0, 0.0, 0.0, 1.0 // 4. column +); +mat4 bMat4 = mat4(1.0); + +mat4 cMat4 = mat4(aVec4, bVec4, cVec4, dVec4); +mat4 dMat4 = mat4(aVec4, aVec3, bVec4, cVec4, aFloat); +``` + +### Опис +**```mat4```** — тип даних, що є матрицею розміром 4x4 із значеннями типу **`float`**. Як видно із прикладу вище, ініціалізувати можна різними способами: + +- надання значень для кожного компонента стовпець за стовпцем; + +- надання одного значення, яке використовується для компонентів на головній діагоналі; + +- надання комбінації векторів і скалярів; + +Так само можна отримати доступ до даних покомпонентно або стовпець за стовпцем: + +```glsl +aMat4[3][3] = 1.0; +float aFloat = aMat4[3][3]; + +aMat4[0] = vec4(1.0); +vec4 aVec4 = aMat4[0]; +``` + +### Дивіться також +[mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [matrixCompMult()](/glossary/?lan=ua&search=matrixCompMult) diff --git a/glossary/matrixCompMult/README-ua.md b/glossary/matrixCompMult/README-ua.md new file mode 100644 index 0000000..ceafd3e --- /dev/null +++ b/glossary/matrixCompMult/README-ua.md @@ -0,0 +1,20 @@ +## matrixCompMult +Виконує покомпонентне множення двох матриць + +### Оголошення +```glsl +mat2 matrixCompMult(mat2 x, mat2 y) +mat3 matrixCompMult(mat3 x, mat3 y) +mat4 matrixCompMult(mat4 x, mat4 y) +``` + +### Параметри +**```x```** — перший матричний множник. + +**```y```** — другий матричний множник. + +### Опис +**```matrixCompMult()```** виконує покомпонентне множення двох матриць, повертаючи нову матрицю, де кожен компонент **```result[i][j]```** обчислюється як скалярний добуток **```x[i][j]```** та **```y[i][j]```**. + +### Дивіться також +[mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4), [Розділ 08: Матриці](../08/?lan=ua) diff --git a/glossary/max/README-ua.md b/glossary/max/README-ua.md new file mode 100644 index 0000000..a06913a --- /dev/null +++ b/glossary/max/README-ua.md @@ -0,0 +1,27 @@ +## max +Повертає більше з двох значень + +### Оголошення +```glsl +float max(float x, float y) +vec2 max(vec2 x, vec2 y) +vec3 max(vec3 x, vec3 y) +vec4 max(vec4 x, vec4 y) + +vec2 max(vec2 x, float y) +vec3 max(vec3 x, float y) +vec4 max(vec4 x, float y) +``` + +### Параметри +**```x```** — перше значення для порівняння. + +**```y```** — друге значення для порівняння. + +### Опис +**```max()```** повертає максимальне значення із двох параметрів. Повертає **`y`**, якщо він більше за **`x`**, інакше повертає **`x`**. + +
+ +### Дивіться також +[min](/glossary/?lan=ua&search=min), [abs](/glossary/?lan=ua&search=abs), [clamp](/glossary/?lan=ua&search=clamp), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/mediump/README-ua.md b/glossary/mediump/README-ua.md new file mode 100644 index 0000000..8623c69 --- /dev/null +++ b/glossary/mediump/README-ua.md @@ -0,0 +1,16 @@ +## mediump +Кваліфікатор точності, задається на початку шейдера + +### Приклад +```glsl +precision mediump float; +precision mediump int; +``` + +### Опис +Кваліфікатор точності оголошує мінімальний діапазон і точність, які повинні використовуватися під час зберігання змінних відповідного типу. + +**```mediump```** — 16+ біт, діапазон для **`float`** від -2^14 to +2^14, діапазон для **`int`** від -2^10 до 2^10 + +### Дивіться також +[lowp](/glossary/?lan=ua&search=lowp), [highp](/glossary/?lan=ua&search=highp), [precision](/glossary/?lan=ua&search=precision) diff --git a/glossary/min/README-ua.md b/glossary/min/README-ua.md new file mode 100644 index 0000000..64408b9 --- /dev/null +++ b/glossary/min/README-ua.md @@ -0,0 +1,27 @@ +## min +Повертає менше з двох значень + +### Оголошення +```glsl +float min(float x, float y) +vec2 min(vec2 x, vec2 y) +vec3 min(vec3 x, vec3 y) +vec4 min(vec4 x, vec4 y) + +vec2 min(vec2 x, float y) +vec3 min(vec3 x, float y) +vec4 min(vec4 x, float y) +``` + +### Параметри +**```x```** — перше значення для порівняння. + +**```y```** — друге значення для порівняння. + +### Опис +**```min()```** повертає мінімальне значення із двох параметрів. Повертає **`y`**, якщо він менше за **`x`**, інакше повертає **`x`**. + +
+ +### Дивіться також +[max](/glossary/?lan=ua&search=max), [abs](/glossary/?lan=ua&search=abs), [clamp](/glossary/?lan=ua&search=clamp), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/mix/README-ua.md b/glossary/mix/README-ua.md new file mode 100644 index 0000000..e20f7f5 --- /dev/null +++ b/glossary/mix/README-ua.md @@ -0,0 +1,31 @@ +## mix +Виконує лінійну інтерполяцію між двома значеннями. + +### Оголошення +```glsl +float mix(float x, float y, float a) +vec2 mix(vec2 x, vec2 y, vec2 a) +vec3 mix(vec3 x, vec3 y, vec3 a) +vec4 mix(vec4 x, vec4 y, vec4 a) + +vec2 mix(vec2 x, vec2 y, float a) +vec3 mix(vec3 x, vec3 y, float a) +vec4 mix(vec4 x, vec4 y, float a) +``` + +### Параметри +**```x```** — початок діапазону інтерполяції. + +**```y```** — кінець діапазону інтерполяції. + +**```a```** — процентне значення ваги для інтерполяції, від 0.0 до 1.0. + +### Опис +**```mix()```** виконує лінійну інтерполяцію між **`x`** та **`y`** використовуючи **`a`** для зважування між ними. Повернене значення обчислюється як "**```x * (1 − a) + y * a```**". + +
+ +
+ +### Дивіться також +[min](/glossary/?lan=ua&search=min), [max](/glossary/?lan=ua&search=max), [Розділ 06: Кольори](/06/?lan=ua) diff --git a/glossary/mod/README-ua.md b/glossary/mod/README-ua.md new file mode 100644 index 0000000..2876f75 --- /dev/null +++ b/glossary/mod/README-ua.md @@ -0,0 +1,27 @@ +## mod +Повертає залишок від ділення першого параметра на другий. Результат має такий самий знак, як і дільник. + +### Оголошення +```glsl +float mod(float x, float y) +vec2 mod(vec2 x, vec2 y) +vec3 mod(vec3 x, vec3 y) +vec4 mod(vec4 x, vec4 y) + +vec2 mod(vec2 x, float y) +vec3 mod(vec3 x, float y) +vec4 mod(vec4 x, float y) +``` + +### Параметри +**```x```** — число, для якого потрібно знайти залишок. + +**```y```** — число, на яке потрібно виконати ділення. + +### Опис +**```mod()```** повертає значення операції модуля **`x`** на **`y`**. Обчислюється як "**```x - y ⋅ floor(x / y)```**". + +
+ +### Дивіться також +[floor](/glossary/?lan=ua&search=floor), [fract](/glossary/?lan=ua&search=fract), [ceil](/glossary/?lan=ua&search=ceil), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/normalize/README-ua.md b/glossary/normalize/README-ua.md new file mode 100644 index 0000000..dab8edd --- /dev/null +++ b/glossary/normalize/README-ua.md @@ -0,0 +1,19 @@ +## normalize +Обчислює одиничний вектор у тому ж напрямку, що й вхідний вектор + +### Оголошення +```glsl +float normalize(float x) +vec2 normalize(vec2 x) +vec3 normalize(vec3 x) +vec4 normalize(vec4 x) +``` + +### Параметри +**```x```** — вектор який потрібно нормалізувати. + +### Опис +**```normalize()```** повертає вектор із тим же напрямком, що і його параметр **`x`**, але з довжиною 1. + +### Дивіться також +[length()](/glossary/?lan=ua&search=length) diff --git a/glossary/not/README-ua.md b/glossary/not/README-ua.md new file mode 100644 index 0000000..237a54a --- /dev/null +++ b/glossary/not/README-ua.md @@ -0,0 +1,18 @@ +## not +Логічно інвертує булевий вектор + +### Оголошення +```glsl +bvec2 not(bvec2 x) +bvec3 not(bvec3 x) +bvec4 not(bvec4 x) +``` + +### Параметри +**```x```** — вектор, який потрібно інвертувати. + +### Опис +**```not()```** логічно інвертує булів вектор **`x`**. Повертає новий булів вектор, для якого кожен елемент **`i`** обчислено як **`!x[i]`**. + +### Дивіться також +[any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all) diff --git a/glossary/notEqual/README-ua.md b/glossary/notEqual/README-ua.md new file mode 100644 index 0000000..1d32340 --- /dev/null +++ b/glossary/notEqual/README-ua.md @@ -0,0 +1,24 @@ +## notEqual +Виконує по-компонентне порівняння двох векторів на нерівність + +### Оголошення +```glsl +bvec2 notEqual(vec2 x, vec2 y) +bvec3 notEqual(vec3 x, vec3 y) +bvec4 notEqual(vec4 x, vec4 y) + +bvec2 notEqual(ivec2 x, ivec2 y) +bvec3 notEqual(ivec3 x, ivec3 y) +bvec4 notEqual(ivec4 x, ivec4 y) +``` + +### Параметри +**```x```** — перший вектор для порівняння. + +**```y```** — другий вектор для порівняння. + +### Опис +**```notEqual()```** повертає булів вектор, у якому кожен елемент **`i`** обчислюється як "**```x[i] != y[i]```**". + +### Дивіться також +[lessThanEqual()](/glossary/?lan=ua&search=lessThanEqual), [lessThan()](/glossary/?lan=ua&search=lessThan), [greaterThanEqual()](/glossary/?lan=ua&search=greaterThanEqual), [greaterThan()](/glossary/?lan=ua&search=greaterThan), [equal()](/glossary/?lan=ua&search=equal), [any()](/glossary/?lan=ua&search=any), [all()](/glossary/?lan=ua&search=all), [not()](/glossary/?lan=ua&search=not) diff --git a/glossary/out/README-ua.md b/glossary/out/README-ua.md new file mode 100644 index 0000000..22b46b0 --- /dev/null +++ b/glossary/out/README-ua.md @@ -0,0 +1,25 @@ +## out +Кваліфікатор доступу аргументів. Позначає аргумент лише на запис. + +### Приклад +```glsl +void increment(out float x) { + // x = x; // оскілки змінну x не можна читати, то як варіант замість її реального значення буде 0, тому так краще не робити + + x = 1.0; // фактично ми знмінюємо змінну за межами функції +} + +void main() { + float count = 0.5; + + increment(count); + + // тепер count == 1.0, оскільки змінна була передана у функцію із out кваліфікатором і була оновлена там +} +``` + +### Опис +**```out```** — кваліфікатор доступу аргументів, який дозволяє лише змінювати позначену змінну, але не дозволяє читати її значення. Зміна буде доступна так само і за межами функції. + +### Дивіться також +[in](/glossary/?lan=ua&search=in), [inout](/glossary/?lan=ua&search=inout) diff --git a/glossary/pow/README-ua.md b/glossary/pow/README-ua.md new file mode 100644 index 0000000..bf20977 --- /dev/null +++ b/glossary/pow/README-ua.md @@ -0,0 +1,23 @@ +## pow +Підносить значення першого параметра в заданому степені другим параметром. + +### Оголошення +```glsl +float pow(float x, float y) +vec2 pow(vec2 x, vec2 y) +vec3 pow(vec3 x, vec3 y) +vec4 pow(vec4 x, vec4 y) +``` + +### Параметри +**```x```** — значення, яке потрібно піднести до степеня **`y`**. + +**```y```** — степінь, до якої потрібно піднести **`x`**. + +### Опис +**```pow()```** повертає значення **`x`**, зведене до степеня **`y`**. + +
+ +### Дивіться також +[inversesqrt](/glossary/?lan=ua&search=inversesqrt), [sqrt](/glossary/?lan=ua&search=sqrt), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/precision/README-ua.md b/glossary/precision/README-ua.md new file mode 100644 index 0000000..404f4da --- /dev/null +++ b/glossary/precision/README-ua.md @@ -0,0 +1,22 @@ +## precision +Кваліфікатор точності оголошує мінімальний діапазон і точність, які базова реалізація повинна використовувати під час зберігання відповідних змінних. + +### Приклад +```glsl +precision lowp float; +precision mediump float; +precision highp float; +precision lowp int; +precision mediump int; +precision highp int; +``` + +### Значення +**```lowp```** — 8+ біт, діапазон для **`float`** від -2 до 2, діапазон для **`int`** від -2^8 до 2^8 + +**```mediump```** — 16+ біт, діапазон для **`float`** від -2^14 to +2^14, діапазон для **`int`** від -2^10 до 2^10 + +**```highp```** — 32+ біт, діапазон для **`float`** від -2^62 to +2^62, діапазон для **`int`** від -2^16 до 2^16 + +### Дивіться також +[lowp](/glossary/?lan=ua&search=lowp), [mediump](/glossary/?lan=ua&search=mediump), [highp](/glossary/?lan=ua&search=highp) diff --git a/glossary/radians/README-ua.md b/glossary/radians/README-ua.md new file mode 100644 index 0000000..5037424 --- /dev/null +++ b/glossary/radians/README-ua.md @@ -0,0 +1,21 @@ +## radians +Конвертує передане значення у радіани + +### Оголошення +```glsl +float radians(float degrees) +vec2 radians(vec2 degrees) +vec3 radians(vec3 degrees) +vec4 radians(vec4 degrees) +``` + +### Параметри +**```degrees```** — значення у градусах, яке потрібно перетворити в радіани. + +### Опис +**```radians()```** перетворює значення, передане в градусах, у радіани. + +Обрахунок по формулі: ```(PI * degrees) / 180.0``` + +### Дивіться також +[degrees](/glossary/?lan=ua&search=degrees) diff --git a/glossary/reflect/README-ua.md b/glossary/reflect/README-ua.md new file mode 100644 index 0000000..fa76eb4 --- /dev/null +++ b/glossary/reflect/README-ua.md @@ -0,0 +1,23 @@ +## reflect +Обчислює напрямок відбиття для падаючого вектора + +### Оголошення +```glsl +float reflect(float I, float N) +vec2 reflect(vec2 I, vec2 N) +vec3 reflect(vec3 I, vec3 N) +vec4 reflect(vec4 I, vec4 N) +``` + +### Параметри +**```I```** — вектор інциденту (падаючий вектор). + +**```N```** — вектор нормалі. + +### Опис +Для вектора падіння **`I`** і нормалі до поверхні **`N`**, **`reflect`** повертає напрямок відбиття, обчислений як "**```I - 2.0 * dot(N, I) * N```**". + +**```N```** має бути нормалізованим, щоб досягти бажаного результату. + +### Дивіться також +[dot()](/glossary/?lan=ua&search=dot), [refract()](/glossary/?lan=ua&search=refract) diff --git a/glossary/reflect/README.md b/glossary/reflect/README.md index 4455e22..1b4db08 100644 --- a/glossary/reflect/README.md +++ b/glossary/reflect/README.md @@ -12,7 +12,7 @@ vec4 reflect(vec4 I, vec4 N) ### Parameters ```I``` specifies the incident vector. -```N``` specifies the normal vector.or. +```N``` specifies the normal vector. ### Description For a given incident vector ```I``` and surface normal ```N``` reflect returns the reflection direction calculated as ```I - 2.0 * dot(N, I) * N```. diff --git a/glossary/refract/README-ua.md b/glossary/refract/README-ua.md new file mode 100644 index 0000000..c08b902 --- /dev/null +++ b/glossary/refract/README-ua.md @@ -0,0 +1,33 @@ +## refract +Обчислює напрямок заломлення для падаючого вектора + +### Оголошення +```glsl +float refract(float I, float N, float eta) +vec2 refract(vec2 I, vec2 N, float eta) +vec3 refract(vec3 I, vec3 N, float eta) +vec4 refract(vec4 I, vec4 N, float eta) +``` + +### Параметри +**```I```** — вектор інциденту (падаючий вектор). + +**```N```** — вектор нормалі. + +**```eta```** — співвідношення показників заломлення. + +### Опис +Для вектора падіння **`I`**, нормалі до поверхні **`N`** та співвідношення показників заломлення **`eta`**, **`refract`** повертає вектор заломлення **`R`**. + +**```R```** обчислюється як: +```glsl +k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); +if (k < 0.0) + R = genType(0.0); // or genDType(0.0) +else + R = eta * I - (eta * dot(N, I) + sqrt(k)) * N; +``` +Вхідні параметри **`I`** та **`N`** повинні бути нормалізовані для досягнення бажаного результату. + +### Дивіться також +[dot()](/glossary/?lan=ua&search=dot), [reflect()](/glossary/?lan=ua&search=reflect) diff --git a/glossary/return/README-ua.md b/glossary/return/README-ua.md new file mode 100644 index 0000000..16819ea --- /dev/null +++ b/glossary/return/README-ua.md @@ -0,0 +1,12 @@ +## return + Оператор зупиняє роботу функції та повертає вказане після нього значення + +### Приклад +```glsl +float getSum(float a, float b) { + return a + b; +} +``` + +### Опис +Оператор **`return`** зупиняє роботу функції та повертає вказане після нього обов'язкове значення того типу, який має повертати функція diff --git a/glossary/sampler2D/README-ua.md b/glossary/sampler2D/README-ua.md new file mode 100644 index 0000000..64a9000 --- /dev/null +++ b/glossary/sampler2D/README-ua.md @@ -0,0 +1,9 @@ +## sampler2D + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/samplerCube/README-ua.md b/glossary/samplerCube/README-ua.md new file mode 100644 index 0000000..fe9e990 --- /dev/null +++ b/glossary/samplerCube/README-ua.md @@ -0,0 +1,9 @@ +## samplerCube + +### Оголошення / Приклад + +### Параметри + +### Опис + +### Дивіться також diff --git a/glossary/sign/README-ua.md b/glossary/sign/README-ua.md new file mode 100644 index 0000000..ccc4389 --- /dev/null +++ b/glossary/sign/README-ua.md @@ -0,0 +1,21 @@ +## sign +Виділяє знак параметра + +### Оголошення +```glsl +float sign(float x) +vec2 sign(vec2 x) +vec3 sign(vec3 x) +vec4 sign(vec4 x) +``` + +### Параметри +**```x```** — значення, з якого слід витягти знак. + +### Опис +**```sign()```** повертає: -1.0, якщо x менше 0.0; 0.0, якщо x дорівнює 0.0; +1.0, якщо x більше 0.0. + +
+ +### Дивіться також +[abs](/glossary/?lan=ua&search=abs), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/sin/README-ua.md b/glossary/sin/README-ua.md new file mode 100644 index 0000000..60cfa65 --- /dev/null +++ b/glossary/sin/README-ua.md @@ -0,0 +1,21 @@ +## sin +Повертає синус параметра + +### Оголошення +```glsl +float sin(float angle) +vec2 sin(vec2 angle) +vec3 sin(vec3 angle) +vec4 sin(vec4 angle) +``` + +### Параметри +**```angle```** — величина в радіанах, синус якої потрібно повернути. + +### Опис +**```sin()```** — повертає тригонометричний синус кута. + +
+ +### Дивіться також +[acos](/glossary/?lan=ua&search=acos), [cos](/glossary/?lan=ua&search=cos), [asin](/glossary/?lan=ua&search=asin), [tan](/glossary/?lan=ua&search=tan), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/smoothstep/README-ua.md b/glossary/smoothstep/README-ua.md new file mode 100644 index 0000000..4090cea --- /dev/null +++ b/glossary/smoothstep/README-ua.md @@ -0,0 +1,38 @@ +## smoothstep +Виконує плавну інтерполяцію Ерміта між двома значеннями + +### Оголошення +```glsl +float smoothstep(float edge0, float edge1, float x) +vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x) +vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x) +vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x) + +vec2 smoothstep(float edge0, float edge1, vec2 x) +vec3 smoothstep(float edge0, float edge1, vec3 x) +vec4 smoothstep(float edge0, float edge1, vec4 x) +``` + +### Параметри +**```edge0```** — значення нижнього краю функції Ерміта. + +**```edge1```** — значення верхнього краю функції Ерміта. + +**```x```** — значення для інтерполяції. + +### Опис +**```smoothstep()```** виконує плавну інтерполяцію Ерміта між **`0`** і **`1`**, коли **`edge0 < x < edge1`**. Це корисно у випадках, коли потрібна порогова функція з плавним переходом. Результат **`smoothstep()`** еквівалентний до: +```glsl + genType t; /* Or genDType t; */ + t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +``` + +Результат не визначено, якщо **`edge0 ≥ edge1`**. + +
+ +
+ +### Дивіться також +[mix](/glossary/?lan=ua&search=mix), [step](/glossary/?lan=ua&search=step), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/sqrt/README-ua.md b/glossary/sqrt/README-ua.md new file mode 100644 index 0000000..29d5a48 --- /dev/null +++ b/glossary/sqrt/README-ua.md @@ -0,0 +1,23 @@ +## sqrt +Повертає значення квадратного кореня + +### Оголошення +```glsl +float sqrt(float x) +vec2 sqrt(vec2 x) +vec3 sqrt(vec3 x) +vec4 sqrt(vec4 x) +``` + +### Параметри +**```x```** — значення, з якого потрібно взяти квадратний корінь. + +### Опис +**```sqrt()```** повертає квадратний корінь з **`x`**. + +
+ +
+ +### Дивіться також +[inversesqrt](/glossary/?lan=ua&search=inversesqrt), [pow](/glossary/?lan=ua&search=pow), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/step/README-ua.md b/glossary/step/README-ua.md new file mode 100644 index 0000000..860bcb0 --- /dev/null +++ b/glossary/step/README-ua.md @@ -0,0 +1,31 @@ +## step +Генерує східчасту функцію, порівнюючи два значення + +### Оголошення +```glsl +float step(float edge, float x) +vec2 step(vec2 edge, vec2 x) +vec3 step(vec3 edge, vec3 x) +vec4 step(vec4 edge, vec4 x) + +vec2 step(float edge, vec2 x) +vec3 step(float edge, vec3 x) +vec4 step(float edge, vec4 x) +``` + +### Параметри +**```edge```** — порогове значення. + +**```x```** — значення для генерації східчастої функції. + +### Опис +**```step()```** генерує східчасту функцію шляхом порівняння **`x`** із **`edge`**. + +Якщо передане значення **`x`** менше за **`edge`**, то функція повертає **`0.0`**, інакше повертається **`1.0`**. + +
+ +
+ +### Дивіться також +[mix](/glossary/?lan=ua&search=mix), [smoothstep](/glossary/?lan=ua&search=smoothstep), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/struct/README-ua.md b/glossary/struct/README-ua.md new file mode 100644 index 0000000..97234f0 --- /dev/null +++ b/glossary/struct/README-ua.md @@ -0,0 +1,27 @@ +## struct +Визначає тип користувацької структури. + +### Приклад +```glsl +struct matStruct { + vec4 ambientColor; + vec4 diffuseColor; + vec4 specularColor; + float specularExponent; +} newMaterialOne, newMaterialTwo; // одночасне оголошення змінних newMaterialOne та newMaterialTwo з типом matStruct + +// перед змінною newMaterialOne вже не потрібно вказувати тип matStruct, оскільки вона вже була оголошена раніше +newMaterialOne = matStruct( + vec4(0.1, 0.1, 0.1, 1.0), + vec4(1.0, 0.0, 0.0, 1.0), + vec4(0.7, 0.7, 0.7, 1.0), + 50.0 +); + +// matStruct тепер використовується для позначення змінних відповідного типу +matStruct anotherNewMaterial = matStruct(...); + +``` + +### Опис +**```struct```** оголошує користувацьку структуру даних на основі стандартних типів. Конструктор для такої структури створюється автоматично. Оголошення змінної, в даному прикладі "newMaterialOne", є необов'язковим, якщо її назва була перечислена одразу після оголошення структури. diff --git a/glossary/tan/README-ua.md b/glossary/tan/README-ua.md new file mode 100644 index 0000000..b68fdd2 --- /dev/null +++ b/glossary/tan/README-ua.md @@ -0,0 +1,21 @@ +## tan +Повертає тангенс переданого кута + +### Оголошення +```glsl +float tan(float angle) +vec2 tan(vec2 angle) +vec3 tan(vec3 angle) +vec4 tan(vec4 angle) +``` + +### Параметри +**```angle```** — величина кута в радіанах, тангенс якого потрібно повернути. + +### Опис +**```tan()```** повертає тригонометричний тангенс кута. + +
+ +### Дивіться також +[cos](/glossary/?lan=ua&search=cos), [acos](/glossary/?lan=ua&search=acos), [sin](/glossary/?lan=ua&search=sin), [asin](/glossary/?lan=ua&search=asin), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/texture2D/README-ua.md b/glossary/texture2D/README-ua.md new file mode 100644 index 0000000..2248e34 --- /dev/null +++ b/glossary/texture2D/README-ua.md @@ -0,0 +1,25 @@ +## texture2D +Отримує текселі (texels) з текстури + +### Оголошення +```glsl +vec4 texture2D(sampler2D sampler, vec2 coord) +vec4 texture2D(sampler2D sampler, vec2 coord, float bias) +``` + +### Параметри +**```sampler```** — семплер, до якого прив'язана текстура, з якої будуть отримані текселі. + +**```coord```** — координати текстури, за якими буде взята текстура. + +**```bias```** — необов'язкове зміщення, яке буде застосовано під час обчислення рівня деталізації. + +### Опис +Функція **`texture2D`** повертає тексель, тобто значення (кольору) текстури для заданих координат. Функція має перший вхідний параметр типу **`sampler2D`** і другий вхідний параметр типу **`vec2`**: семплер, до якої прив'язана текстура, і двовимірні координати текселя. + +Існує додатковий третій вхідний параметр типу **`float`**. Після обчислення відповідного рівня деталізації для текстури з MIP-картами зміщення додається перед виконанням фактичної операції пошуку текстури. + +Додаткова примітка: на пристроях iOS функція пошуку текстури доступна лише у фрагментному шейдері. + +### Дивіться також +[textureCube](/glossary/?lan=ua&search=textureCube) diff --git a/glossary/textureCube/README-ua.md b/glossary/textureCube/README-ua.md new file mode 100644 index 0000000..ef93021 --- /dev/null +++ b/glossary/textureCube/README-ua.md @@ -0,0 +1,25 @@ +## textureCube +Отримує текселі (texels) з текстури + +### Оголошення +```glsl +vec4 textureCube(samplerCube sampler, vec3 coord) +vec4 textureCube(samplerCube sampler, vec3 coord, float bias) +``` + +### Параметри +**```sampler```** — семплер, до якого прив'язана текстура, з якої будуть отримані текселі. + +**```coord```** — координати текстури, за якими буде взята текстура. + +**```bias```** — необов'язкове зміщення, яке буде застосовано під час обчислення рівня деталізації. + +### Опис +Функція **`textureCube`** повертає тексель, тобто значення (кольору) текстури для заданих координат. Функція має перший вхідний параметр типу **`samplerCube`** і другий вхідний параметр типу **`vec3`**: семплер, до якої прив'язана текстура, і тривимірні координати текселя. + +Існує додатковий третій вхідний параметр типу **`float`**. Після обчислення відповідного рівня деталізації для текстури з MIP-картами зміщення додається перед виконанням фактичної операції пошуку текстури. + +Додаткова примітка: на пристроях iOS функція пошуку текстури доступна лише у фрагментному шейдері. + +### Дивіться також +[texture2D](/glossary/?lan=ua&search=texture2D) diff --git a/glossary/textureCube/README.md b/glossary/textureCube/README.md index ee196a9..b3d81eb 100644 --- a/glossary/textureCube/README.md +++ b/glossary/textureCube/README.md @@ -1,4 +1,4 @@ -## Texture2D +## TextureCube Retrieves texels from a texture ### Declaration diff --git a/glossary/uniform/README-ua.md b/glossary/uniform/README-ua.md new file mode 100644 index 0000000..0a45339 --- /dev/null +++ b/glossary/uniform/README-ua.md @@ -0,0 +1,15 @@ +## uniform +Кваліфікатор уніфікованої змінної. + +### Приклад +```glsl +uniform vec4 direction; +``` + +### Опис +**```uniform```**-змінні містять дані лише для читання, які передаються із середовища WebGL/OpenGL у вершинний або фрагментний шейдер. + +Значення на рівні примітивів, тому вони корисні для змінних, які залишаються постійними вздовж примітива, кадру або сцени. + +### Дивіться також +[attribute](/glossary/?lan=ua&search=attribute), [const](/glossary/?lan=ua&search=const), [varying](/glossary/?lan=ua&search=varying), [Розділ 03: Uniforms](/03/?lan=ua) diff --git a/glossary/varying/README-ua.md b/glossary/varying/README-ua.md new file mode 100644 index 0000000..a279213 --- /dev/null +++ b/glossary/varying/README-ua.md @@ -0,0 +1,15 @@ +## varying +Кваліфікатор varying змінної. + +### Приклад +```glsl +varying vec3 position; +``` + +### Опис +**```varying```**-змінні містять дані, які передаються від вершинного шейдера у фрагментний. + +Змінна має бути спочатку оголошена у вершинному шейдері. У фрагментному шейдері її дані доступні лише для читання і є інтерполяцією з вершин, які складають фрагмент. + +### Дивіться також +[attribute](/glossary/?lan=ua&search=attribute), [const](/glossary/?lan=ua&search=const), [uniform](/glossary/?lan=ua&search=uniform), [Розділ 03: Uniforms](/03/?lan=ua) diff --git a/glossary/vec2/README-ua.md b/glossary/vec2/README-ua.md new file mode 100644 index 0000000..23c3199 --- /dev/null +++ b/glossary/vec2/README-ua.md @@ -0,0 +1,21 @@ +## vec2 +2-вимірний вектор із float-компонентами + +### Оголошення +```glsl +vec2 aVec2 = vec2(1.0, 1.0); +vec2 bVec2 = vec2(1.0); + +vec2 cVec2 = vec2(aVec3); +vec2 dVec2 = vec2(aVec3.x, aVec3.y); +``` + +### Опис +**```vec2```** — вектор з двома float-компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для обох компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/vec3/README-ua.md b/glossary/vec3/README-ua.md new file mode 100644 index 0000000..6bb0bb4 --- /dev/null +++ b/glossary/vec3/README-ua.md @@ -0,0 +1,25 @@ +## vec3 +3-вимірний вектор із float-компонентами + +### Оголошення +```glsl +vec3 aVec3 = vec3(1.0, 1.0, 1.0); +vec3 bVec3 = vec3(1.0); + +vec3 cVec3 = vec3(aVec4); +vec3 dVec3 = vec3(aVec4.x, aVec4.y, aVec4.z); + +vec3 eVec3 = vec3(aVec2, aFloat); +vec3 fVec3 = vec3(aVec2.x, aVec2.y, aFloat); +``` + +### Опис +**```vec3```** — вектор з трьома float-компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання вектора вищої розмірності, де відповідні значення будуть використані для ініціалізації компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/vec4/README-ua.md b/glossary/vec4/README-ua.md new file mode 100644 index 0000000..b35545d --- /dev/null +++ b/glossary/vec4/README-ua.md @@ -0,0 +1,21 @@ +## vec4 +4-вимірний вектор із float-компонентами + +### Оголошення +```glsl +vec4 aVec4 = vec4(1.0, 1.0, 1.0, 1.0); +vec4 bVec4 = vec4(1.0); + +vec4 cVec4 = vec4(aVec2, aFloat, aVec3); +vec4 dVec4 = vec4(aBvec2.x, aBvec2.y, aFloat, aBvec3.x); +``` + +### Опис +**```vec4```** — вектор з чотирма float-компонентами. Способи ініціалізації: + +- надання скалярного значення для кожного компонента; +- надання одного скалярного значення, що буде використано для всіх компонентів; +- надання комбінації векторів та/або скалярів. Для ініціалізації вектора використовуються відповідні значення. Аргументи конструктора повинні містити принаймні стільки ж компонентів, скільки ініціалізований вектор. + +### Дивіться також +[bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float), [bvec2](/glossary/?lan=ua&search=bvec2), [bvec3](/glossary/?lan=ua&search=bvec3), [bvec4](/glossary/?lan=ua&search=bvec4), [ivec2](/glossary/?lan=ua&search=ivec2), [ivec3](/glossary/?lan=ua&search=ivec3), [ivec4](/glossary/?lan=ua&search=ivec4), [vec2](/glossary/?lan=ua&search=vec2), [vec3](/glossary/?lan=ua&search=vec3), [vec4](/glossary/?lan=ua&search=vec4), [mat2](/glossary/?lan=ua&search=mat2), [mat3](/glossary/?lan=ua&search=mat3), [mat4](/glossary/?lan=ua&search=mat4) diff --git a/glossary/void/README-ua.md b/glossary/void/README-ua.md new file mode 100644 index 0000000..0111d73 --- /dev/null +++ b/glossary/void/README-ua.md @@ -0,0 +1,14 @@ +## void + +### Приклад +```glsl +void main(void); +int aFunction(void); +void bFunction(float); +``` + +### Опис +**```void```** — використовується для позначення функції без параметрів або коли вона не повертає значення. + +### Дивіться також +[void](/glossary/?lan=ua&search=void), [bool](/glossary/?lan=ua&search=bool), [int](/glossary/?lan=ua&search=int), [float](/glossary/?lan=ua&search=float) diff --git a/src/main.js b/src/main.js index d0cfd8d..17b2d16 100644 --- a/src/main.js +++ b/src/main.js @@ -259,7 +259,13 @@ function previusPage() { } function homePage() { - window.location.href = "../"; + var language = getParameterByName('lan'); + + if (language !== ""){ + language = "?lan=" + language; + } + + window.location.href = "../" + language; } function nextPage() { diff --git a/toc-header.php b/toc-header.php index 75fc8d8..0118782 100644 --- a/toc-header.php +++ b/toc-header.php @@ -1,3 +1,18 @@
-

Bahasa Indonesia - Tiếng Việt - 日本語 - 中文版 - 한국어 - Español - Portugues - Français - Italiano - Deutsch - Русский - Polski - English

+

+ Українська - + Bahasa Indonesia - + Tiếng Việt - + 日本語 - + 中文版 - + 한국어 - + Español - + Portugues - + Français - + Italiano - + Deutsch - + Русский - + Polski - + English +

From fedc025724448768e7d9b234aa395cd01b3838b6 Mon Sep 17 00:00:00 2001 From: alextoudic Date: Wed, 9 Aug 2023 15:31:25 +0200 Subject: [PATCH 02/47] fix a few typos in french version --- 07/README-fr.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/07/README-fr.md b/07/README-fr.md index cfd7467..c2467d2 100644 --- a/07/README-fr.md +++ b/07/README-fr.md @@ -64,7 +64,7 @@ le programme va devoir évaluer les 2 branches de toutes façons et cette évalu Une stratégie pour parer à ce problème est de structurer le code de manière à éliminer les conditions, donc les branches. En l'occurrence, se servir du résultat (0 ou 1) de `step()` et le multiplier par une autre variable (la couleur par exemple). Si le `step()` renvoie 1, la couleur se multipliera par 1 et restera la même, si le `step()` renvoie 0, la couleur se multipliera par 0 donc elle passe au noir. -C'est une technique que voue retrouverez souvent dans les shaders. +C'est une technique que vous retrouverez souvent dans les shaders. ![](rect-01.jpg) @@ -215,12 +215,12 @@ Prenez le code suivant:
On commence par déplacer le système de coordonnées au centre et à le diviser par deux pour obtenir des valeurs comprises entre -1 et 1. -A la *ligne 24*, nous visualisons le champ de distances grâce à la fonction [`fract()`](../glossary/?search=fract) ce qui nous permet de mieux voir le motif qu'il crée. +À la *ligne 24*, nous visualisons le champ de distances grâce à la fonction [`fract()`](../glossary/?search=fract) ce qui nous permet de mieux voir le motif qu'il crée. Le motif du champ de distances se répète en cercles concentriques, à la manière d'un jardin zen. Regardons la formule du champ de distances *ligne 19*. Nous calculons la distance entre chaque position et la coordonnée `( .3,.3 )` ( entre `st` et le vecteur `vec2(.3)`) pour chaque quadrant, c'est à ça que sert l'appel à [`abs()`](../glossary/?search=abs). -Si vous décommentez la *ligne 20*, vouz noterez que nous combinons les distances à ces 4 points en utilisant la fonction [`min()`](../glossary/?search=min) contre 0, ce qui produit un nouveau motif. +Si vous décommentez la *ligne 20*, vous noterez que nous combinons les distances à ces 4 points en utilisant la fonction [`min()`](../glossary/?search=min) contre 0, ce qui produit un nouveau motif. L'idée est qu'il n'y a qu'un seul point, et non '4', celui en haut à droite mais il est *reflété* dans les 3 autres *quadrants* du fait qu'on a changé la taille de l'espace *ligne 16* ! From d377c0dfc241915d3963921a2be6a264892013d8 Mon Sep 17 00:00:00 2001 From: Valentin Manceaux-Panot Date: Sat, 4 Nov 2023 19:49:55 +0100 Subject: [PATCH 03/47] Fixed a typo in the glossary The `faceforward` function was missing its first `r`, leading to an empty page --- glossary/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/README.md b/glossary/README.md index 3e4f96f..116ddae 100644 --- a/glossary/README.md +++ b/glossary/README.md @@ -100,7 +100,7 @@ [dot()](./?search=dot) [cross()](./?search=cross) [normalize()](./?search=normalize) -[facefoward()](./?search=facefoward) +[faceforward()](./?search=faceforward) [reflect()](./?search=reflect) [refract()](./?search=refract) From 8342b39ffa89f431b34bbcd1f8c920d3d3505ad4 Mon Sep 17 00:00:00 2001 From: Dmitriy Aleksandrovich Chernukho Date: Wed, 15 Nov 2023 23:47:52 +0100 Subject: [PATCH 04/47] fix languages menu --- chap-header.php | 4 +++- languages.php | 16 ++++++++++++++++ toc-header.php | 19 +++---------------- 3 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 languages.php diff --git a/chap-header.php b/chap-header.php index 514c44f..80947ba 100644 --- a/chap-header.php +++ b/chap-header.php @@ -1,6 +1,8 @@
diff --git a/languages.php b/languages.php new file mode 100644 index 0000000..899f254 --- /dev/null +++ b/languages.php @@ -0,0 +1,16 @@ +

+ Українська - + Bahasa Indonesia - + Tiếng Việt - + 日本語 - + 中文版 - + 한국어 - + Español - + Portugues - + Français - + Italiano - + Deutsch - + Русский - + Polski - + English +

\ No newline at end of file diff --git a/toc-header.php b/toc-header.php index 0118782..5770b17 100644 --- a/toc-header.php +++ b/toc-header.php @@ -1,18 +1,5 @@ From 62a172de3cd2f509a7c36b3db5e9d5e2ea9cd116 Mon Sep 17 00:00:00 2001 From: Andrey Bakhvalov Date: Fri, 8 Dec 2023 09:46:09 +0100 Subject: [PATCH 05/47] fix ru typos --- appendix/04/README-ru.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appendix/04/README-ru.md b/appendix/04/README-ru.md index b7619f0..9471a01 100644 --- a/appendix/04/README-ru.md +++ b/appendix/04/README-ru.md @@ -325,7 +325,7 @@ for( float i = 0.0; i <= count; i+= 1.0 ){ #### квалификаторы -Помимо типов переменных в GLSL есть **квалификаторы**. Вкратце, квалификаторы сообщают компилятору какая переменная для чего предназначена. Например, некоторые данные для GPU могут приходить только со стороны CPU. Такие данные называются **атрибутами** и **юниформами**. **Атрибуты** встречаются только в вершинных шейдерах, а **юниформы** - и в вершинных, и во фрагментных. Так же есть квалификатор ```varying```, используемый для передачи переменных т вершинного шейдера ко фрагментному. +Помимо типов переменных в GLSL есть **квалификаторы**. Вкратце, квалификаторы сообщают компилятору какая переменная для чего предназначена. Например, некоторые данные для GPU могут приходить только со стороны CPU. Такие данные называются **атрибутами** и **юниформами**. **Атрибуты** встречаются только в вершинных шейдерах, а **юниформы** - и в вершинных, и во фрагментных. Так же есть квалификатор ```varying```, используемый для передачи переменных от вершинного шейдера к фрагментному. Я не буду сильно углубляться в подробности, ибо мы в основном рассматриваем **фрагментные шейдеры*, но далее в книге вам возможно встретится что-то вроде ```glsl From ac19f7ceadc3b2a63e96389cddd13095da86a5ce Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:11:40 +0100 Subject: [PATCH 06/47] Fix typo. --- 03/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03/README.md b/03/README.md index dedbaf1..6436c7c 100644 --- a/03/README.md +++ b/03/README.md @@ -44,7 +44,7 @@ In the same way GLSL gives us a default output, `vec4 gl_FragColor`, it also giv 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. -In shader-land we don’t 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. +In shader-land we don’t 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. It is equally hard, beautiful and gratifying. ![](08.png) From d2fe455a0a24c6fc8f64a5e656be58b81584e3af Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:14:12 +0100 Subject: [PATCH 07/47] Fix typo. --- 03/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03/README.md b/03/README.md index 6436c7c..3cf586d 100644 --- a/03/README.md +++ b/03/README.md @@ -54,7 +54,7 @@ Now it is time to try and challenge our understanding of this code. * 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 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? From 2eb5dd34f4e5c2973fd6c41742847101190fbf88 Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:16:40 +0100 Subject: [PATCH 08/47] Unify capitalization of word OpenGL. --- 00/README.md | 2 +- 01/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/00/README.md b/00/README.md index 34281ea..5e3497b 100644 --- a/00/README.md +++ b/00/README.md @@ -28,7 +28,7 @@ This book will focus on the use of GLSL pixel shaders. First we'll define what s What this book doesn't cover: -* This *is not* an openGL or webGL book. OpenGL/webGL is a bigger subject than GLSL or fragment shaders. To learn more about openGL/webGL I recommend taking a look at: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (also known as the red book) or [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) +* This *is not* an OpenGL or webGL book. OpenGL/webGL is a bigger subject than GLSL or fragment shaders. To learn more about OpenGL/webGL I recommend taking a look at: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (also known as the red book) or [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) * This *is not* a math book. Although we will cover a number of algorithms and techniques that rely on an understanding of algebra and trigonometry, we will not explain them in detail. For questions regarding the math I recommend keeping one of the following books nearby: [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) or [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). diff --git a/01/README.md b/01/README.md index ae1af21..cd08744 100644 --- a/01/README.md +++ b/01/README.md @@ -35,7 +35,7 @@ Another “super power” of the GPU is special math functions accelerated via h ## What is GLSL? -GLSL stands for openGL Shading Language, which is the specific standard of shader programs you'll see in the following chapters. There are other types of shaders depending on hardware and Operating Systems. Here we will work with the openGL specs regulated by [Khronos Group](https://www.khronos.org/opengl/). Understanding the history of OpenGL can be helpful for understanding most of its weird conventions, for that I recommend taking a look at: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html) +GLSL stands for OpenGL Shading Language, which is the specific standard of shader programs you'll see in the following chapters. There are other types of shaders depending on hardware and Operating Systems. Here we will work with the OpenGL specs regulated by [Khronos Group](https://www.khronos.org/opengl/). Understanding the history of OpenGL can be helpful for understanding most of its weird conventions, for that I recommend taking a look at: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html) ## Why are Shaders famously painful? From aaaa949b8e46d90982cb56aa6b6718bcac05a9a3 Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:20:38 +0100 Subject: [PATCH 09/47] Unify capitalization of OpenGL. --- 04/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04/README.md b/04/README.md index 444dcf0..7372e87 100644 --- a/04/README.md +++ b/04/README.md @@ -131,7 +131,7 @@ Below is an example of the HTML and JS you need to get started with shaders in t ### In **Processing** -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. +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; From 97de0721bf89698db36ad3b996ee041517085d33 Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:22:14 +0100 Subject: [PATCH 10/47] Remove trailing whitespace. --- 04/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04/README.md b/04/README.md index 7372e87..ade5d6f 100644 --- a/04/README.md +++ b/04/README.md @@ -220,7 +220,7 @@ For more information about shaders in openFrameworks go to this [excellent tutor ![](blender/00.png) -2. Change `width` and `height` size and `Source` file (which can be a path to an external file). +2. Change `width` and `height` size and `Source` file (which can be a path to an external file). ![](blender/01.png) From 417543b18ebeb28c8e28791141ca11243f6ae28f Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:25:24 +0100 Subject: [PATCH 11/47] Remove trailing whitespace. --- 05/README.md | 2 +- 06/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/05/README.md b/05/README.md index f0fd98f..54f199e 100644 --- a/05/README.md +++ b/05/README.md @@ -107,7 +107,7 @@ At the end of the last exercise we introduced some new functions. Now it’s tim Like chefs that collect spices and exotic ingredients, digital artists and creative coders have a particular love of working on their own shaping functions. -[Iñigo Quiles](http://www.iquilezles.org/) has a great collection of [useful functions](http://www.iquilezles.org/www/articles/functions/functions.htm). After reading [this article](http://www.iquilezles.org/www/articles/functions/functions.htm) take a look at the following translation of these functions to GLSL. Pay attention to the small changes required, like putting the "." (dot) on floating point numbers and using the GLSL name for *C functions*; for example instead of `powf()` use `pow()`: +[Iñigo Quiles](http://www.iquilezles.org/) has a great collection of [useful functions](http://www.iquilezles.org/www/articles/functions/functions.htm). After reading [this article](http://www.iquilezles.org/www/articles/functions/functions.htm) take a look at the following translation of these functions to GLSL. Pay attention to the small changes required, like putting the "." (dot) on floating point numbers and using the GLSL name for *C functions*; for example instead of `powf()` use `pow()`:
diff --git a/06/README.md b/06/README.md index addb535..0c2993e 100644 --- a/06/README.md +++ b/06/README.md @@ -93,7 +93,7 @@ By mapping the position on the x axis to the Hue and the position on the y axis ### HSB in polar coordinates -HSB was originally designed to be represented in polar coordinates (based on the angle and radius) instead of cartesian coordinates (based on x and y). To map our HSB function to polar coordinates we need to obtain the angle and distance from the center of the billboard to the pixel coordinate. For that we will use the [`length()`](../glossary/?search=length) function and [`atan(y,x)`](../glossary/?search=atan) (which is the GLSL version of the commonly used `atan2(y,x)`). +HSB was originally designed to be represented in polar coordinates (based on the angle and radius) instead of cartesian coordinates (based on x and y). To map our HSB function to polar coordinates we need to obtain the angle and distance from the center of the billboard to the pixel coordinate. For that we will use the [`length()`](../glossary/?search=length) function and [`atan(y,x)`](../glossary/?search=atan) (which is the GLSL version of the commonly used `atan2(y,x)`). When using vector and trigonometric functions, `vec2`, `vec3` and `vec4` are treated as vectors even when they represent colors. We will start treating colors and vectors similarly, in fact you will come to find this conceptual flexibility very empowering. From 91033a09fecc667b204db51790c8799a0bc81d93 Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Thu, 11 Jan 2024 16:28:30 +0100 Subject: [PATCH 12/47] Fix capitalization of word Cartesian. --- 07/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/07/README.md b/07/README.md index 61d6222..c82be50 100644 --- a/07/README.md +++ b/07/README.md @@ -90,7 +90,7 @@ Before going forward, try the following exercises: ### Circles -It's easy to draw squares on grid paper and rectangles on cartesian coordinates, but circles require another approach, especially since we need a "per-pixel" algorithm. One solution is to *re-map* the spatial coordinates so that we can use a [`step()`](../glossary/?search=step) function to draw a circle. +It's easy to draw squares on grid paper and rectangles on Cartesian coordinates, but circles require another approach, especially since we need a "per-pixel" algorithm. One solution is to *re-map* the spatial coordinates so that we can use a [`step()`](../glossary/?search=step) function to draw a circle. How? Let's start by going back to math class and the grid paper, where we opened a compass to the radius of a circle, pressed one of the compass points at the center of the circle and then traced the edge of the circle with a simple spin. @@ -184,7 +184,7 @@ Finish uncommenting *lines 27 to 29* one by one to understand the different uses ![Robert Mangold - Untitled (2008)](mangold.jpg) -In the chapter about color we map the cartesian coordinates to polar coordinates by calculating the *radius* and *angles* of each pixel with the following formula: +In the chapter about color we map the Cartesian coordinates to polar coordinates by calculating the *radius* and *angles* of each pixel with the following formula: ```glsl vec2 pos = vec2(0.5)-st; @@ -196,7 +196,7 @@ We use part of this formula at the beginning of the chapter to draw a circle. We This technique is a little restrictive but very simple. It consists of changing the radius of a circle depending on the angle to achieve different shapes. How does the modulation work? Yes, using shaping functions! -Below you will find the same functions in the cartesian graph and in a polar coordinates shader example (between *lines 21 and 25*). Uncomment the functions one-by-one, paying attention the relationship between one coordinate system and the other. +Below you will find the same functions in the Cartesian graph and in a polar coordinates shader example (between *lines 21 and 25*). Uncomment the functions one-by-one, paying attention the relationship between one coordinate system and the other.
-### Add, Substract, Multiply and others +### Add, Subtract, Multiply and others ![](02.jpg) From dd84fc93ab3a4b707cc6abbd33a1ec72c7f599fc Mon Sep 17 00:00:00 2001 From: Alex Kraasch Date: Fri, 12 Jan 2024 03:13:20 +0100 Subject: [PATCH 15/47] Check-reading the first pages of the German translation. --- 00/README-de.md | 26 +++++++++++++------------- 01/README-de.md | 7 ++++--- README-de.md | 6 +++--- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/00/README-de.md b/00/README-de.md index 624c98d..8c138d6 100644 --- a/00/README-de.md +++ b/00/README-de.md @@ -2,35 +2,35 @@ -Die oben abgebildeten Grafiken wurden auf ganz unterschiedliche Weise erstellt. Die linke Abbildung stammt aus den Händen des Malers Van Gogh, der die Farben in stundenlanger Arbeit Schicht für Schicht mit einem Pinsel aufgetragen hat. Die rechte Abbildung wurde dagegen innerhalb von Sekundenbruchteilen mit Hilfe von vier Punktmatrizen erzeugt: eine für Cyan, eine für Magenta, eine für Gelb und eine für Schwarz. Der entscheidende Unterschied: Das zweite Bild wurde nicht seriell erstellt, d.h. Strich für Strich, sondern parallel, alle Punkte zur gleichen Zeit. +Die oben abgebildeten Grafiken wurden auf verschiedene Weise erstellt. Die linke Abbildung stammt aus den Händen des Malers Van Gogh, der die Farben in stundenlanger Arbeit Schicht für Schicht mit einem Pinsel aufgetragen hat. Die rechte Abbildung wurde dagegen innerhalb von wenigen Sekunden mit Hilfe von vier Pixelmatrizen erzeugt: eine für cyan, eine für magenta, eine für gelb und eine für schwarz. Der entscheidende Unterschied ist, dass das zweite Bild nicht seriell erstellt wurde, also nicht Schritt für Schritt, sondern parallel, alle Punkte zur gleichen Zeit. -Dieses Buch handelt von einer Computertechnik mit Namen *Fragment Shader*, die die digitale Erzeugung von Bildern revolutioniert und zu neuen Höhen geführt hat. Man kann ihre Erfindung ein wenig vergleichen mit dem Schritt von der manuellen Vervielfältigung einzelner Grafiken und Dokumente hin zur massenhaften Replikation durch Gutenbergs Druckerpresse. +Dieses Buch handelt von der Rechentechnik mit dem Namen *Fragment-Shader*, die die digitale Erzeugung von Bildern revolutioniert und zu neuen Höhen geführt hat. Man kann ihre Erfindung ein wenig vergleichen mit dem Schritt von der manuellen Vervielfältigung einzelner Grafiken und Dokumente hin zur massenhaften Replikation durch Gutenbergs Druckerpresse. ![Gutenbergs Druckerpresse](gutenpress.jpg) -Fragment-Shader ermöglichen die vollständige Kontrolle über alle Bildpunkte, die als Grafik auf dem Bildschirm erscheinen. Und das mit ungeheurer Geschwindigkeit. Deshalb wird diese Technik mittlerweile in vielen Bereichen der Computergrafik angewandt, von Videofiltern auf Smartphones bis hin zu den neuesten fotorealistisch wirkenden 3D-Videospielen. +Fragment-Shader ermöglichen die vollständige Kontrolle über alle Bildpunkte, die als Grafik auf dem Bildschirm erscheinen. Und das mit ungeheurer Geschwindigkeit. Deshalb wird diese Technik mittlerweile in vielen Bereichen der Computergrafik angewandt, von Videofiltern auf Smartphones bis hin zu beeindruckenden 3D-Videospielen. ![Grafik aus dem Spiel „Journey“ von That Game Company](journey.jpg) -Die folgenden Kapitel wollen Dir zeigen, wie unglaublich schnell und leistungsfähig diese Technik ist, und wie Du sie im Rahmen von privaten und beruflichen Projekten einsetzen kannst. +Die folgenden Kapitel zeigen Dir, wie unglaublich schnell und leistungsfähig diese Technik ist und wie Du sie im Rahmen von privaten und beruflichen Projekten einsetzen kannst. ## Für wen ist dieses Buch geeignet? -Dieses Buch wendet sich an kreative Programmierer, Spieleentwickler und Ingenieure, die bereits über eine gewisse Programmiererfahrung, sowie grundlegende Kenntnisse aus den Bereichen der linearen Algebra und der Trigonometrie verfügen. (Falls Du erst noch Programmieren lernen möchtest, empfehle ich Dir, mit [Processing](https://processing.org/) zu beginnen und anschließend mit diesem Buch fortzufahren.) +Dieses Buch wendet sich an kreative Programmierer, Spieleentwickler und Ingenieure, die bereits Programmiererfahrung und grundlegende Kenntnisse in den Bereichen linearen Algebra und Trigonometrie haben. (Falls Du erst noch programmieren lernen möchtest, empfehle ich Dir, mit [Processing](https://processing.org/) zu beginnen und anschließend mit diesem Buch fortzufahren.) -Die folgenden Kapitel werden Dir zeigen, wie Du Shader in Deinen Projekten einsetzen kannst, um die Qualität und die Geschwindigkeit bei der Erzeugung von Grafiken zu verbessern. GLSL-Shader (GLSL steht für „OpenGL Shading Language“) lassen sich auf einer Vielzahl von Hardwareplattformen und Betriebssystemen kompilieren und ausführen. Dadurch kannst Du das erlernte Wissen in jeder Umgebung einsetzen, die OpenGL, OpenGL ES oder WebGL unterstützt. +Dieses Buch zeigt Dir, wie Du Shader in Deinen Projekten einsetzen kannst und wie Du die Qualität und die Geschwindigkeit von Shadern verbesserst. GLSL-Shader (GLSL steht für „OpenGL Shading Language“) lassen sich auf einer Vielzahl von Hardwareplattformen und Betriebssystemen kompilieren und ausführen. Dadurch kannst Du das erlernte Wissen in jeder Umgebung einsetzen, die OpenGL, OpenGL ES oder WebGL benutzt. -In anderen Worten, Du kannst Dein Know-how u.a. beim Malen mit [Processing](https://processing.org/), bei Anwendungen für [openFrameworks](http://openframeworks.cc/), interaktiven Installationen mit [Cinder](http://libcinder.org/), Webseiten mit [Three.js](http://threejs.org/) oder bei Spielen für iOS/Android nutzen. +In anderen Worten, Du kannst Dein Know-how u.a. beim Malen mit [Processing](https://processing.org/), bei Anwendungen für [openFrameworks](http://openframeworks.cc/), interaktiven Installationen mit [Cinder](http://libcinder.org/), Webseiten mit [Three.js](http://threejs.org/) oder bei Spielen für iOS und Android nutzen. ## Welchen Aspekten widmet sich dieses Buch? -Dieses Buch konzentriert sich auf den Einsatz von GLSL-Pixel-Shadern. Zunächst erklären wir, was Shader sind, dann wenden wir uns der algorithmischen Erzeugung von Formen, Mustern, Texturen und Animationen zu. Du lernst die Grundlagen der Programmiersprache für OpenGL-Shader kennen und erfährst, wie man sie für konkrete Zwecke nutzt. Dazu zählt die Bildbearbeitung (Bildmanipulationen, Matrizenoperationen, Farbfilter und weitere Effekte), sowie Simulationen (Conways Game of Life, Reaktion und Diffusion von Chemikalien nach Gray-Scott, Erzeugung von Wasserwellen, die Nachbildung des Malens mit Wasserfarben, Erzeugung von Voronoi-Zellen und mehr). Zum Ende des Buches hin lernst Du fortschrittliche Techniken kennen, bei denen etwa mit Hilfe des sogenannten „Ray Marchings“ beeindruckende 2D-Grafiken aus 3D-Daten generiert werden. +Dieses Buch behandelt hauptsächlich den Umgang mit GLSL-Pixel-Shadern. Zunächst erklären wir, was Shader sind, dann wenden wir uns der algorithmischen Erzeugung von Formen, Mustern, Texturen und Animationen zu. Du lernst die Grundlagen der Programmiersprache für OpenGL-Shader kennen und erfährst, wie man sie für konkrete Zwecke nutzt. Dazu zählt die Bildbearbeitung (Bildmanipulationen, Matrizenoperationen, Blurfilter, Farbfilter und weitere Effekte), sowie Simulationen (Conways Game of Life, Reaktion und Diffusion von Chemikalien nach Gray-Scott, Erzeugung von Wasserwellen, die Nachbildung des Malens mit Wasserfarben, Erzeugung von Voronoi-Zellen und mehr). Gegen Ende vom Buch lernst Du mehrere fortgeschrittene Techniken kennen, die mithilfe einer Technik namens *Ray-Marching* beeindruckende 2D-Grafiken aus 3D-Daten generiert werden. -*In jedem Kapitel gibt es interaktive Beispiele, mit denen Du vieles ausprobieren kannst.* Sobald du etwas am Programmcode änderst, erscheinen die daraus resultierenden Veränderungen an der erzeugten Grafik sofort auf dem Bildschirm. Die vorgestellten Konzepte sind teilweise abstrakt und auf den ersten Blick vielleicht ein wenig verwirrend. Aber mit Hilfe der interaktiven Beispiele kannst Du den Lernstoff leicht nachvollziehen. Je mehr Du ausprobierst, desto einfacher wird Dir das Lernen fallen. +*In jedem Kapitel gibt es interaktive Beispiele, mit denen Du vieles ausprobieren kannst.* Sobald du etwas am Programmcode änderst, erscheinen die daraus resultierenden Veränderungen an der erzeugten Grafik sofort. Die vorgestellten Konzepte sind teilweise abstrakt und auf den ersten Blick vielleicht ein wenig verwirrend. Aber mithilfe der interaktiven Beispiele kannst Du den Lernstoff leicht nachvollziehen. Je mehr Du ausprobierst, desto einfacher wird Dir das Lernen fallen. Was dieses Buch nicht behandelt: -* Dies *ist kein * Buch über openGL oder webGL. OpenGL/webGL ist ein umfassenderes Thema als GLSL- oder Fragment-Shader. Wenn Du mehr über openGL/webGL lernen möchtest, empfehle ich Dir die folgenden Materialien: [OpenGL Einführung (Englisch)](https://open.gl/introduction), [Die achte Ausgabe des „OpenGL Programming Guide“ (Englisch)](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (auch bekannt als das „Red Book“) oder [„WebGL: Up and Running“ (Englisch)](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) +* Dies *ist kein* Buch über OpenGL oder WebGL. OpenGL und WebGL sind ein umfassenderes Thema als GLSL- oder Fragment-Shader. Wenn Du mehr über OpenGL oder WebGL lernen möchtest, empfehle ich Dir die folgenden Materialien: [OpenGL Einführung (Englisch)](https://open.gl/introduction), [Die achte Ausgabe des „OpenGL Programming Guide“ (Englisch)](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (auch bekannt als das „Red Book“) oder [„WebGL: Up and Running“ (Englisch)](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) * Das vorliegende Werk *ist außerdem kein* Mathematik-Buch. Obwohl wir bei vielen Techniken und Algorithmen auf Algebra und Trigonometrie zurückgreifen, werden die mathematischen Grundlagen nicht an jeder Stelle vollständig in allen Details erklärt. Bei Fragen dazu empfehle ich Dir eines der folgenden Bücher: [Dritte Ausgabe von „Mathematics for 3D Game Programming and Computer Graphics“ (Englisch)](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) oder [Zweite Ausgabe von „Essential Mathematics for Games and Interactive Applications“ (Englisch)](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). @@ -40,10 +40,10 @@ Nicht viel! Wenn Du auf Deinem Rechner, Smartphone oder Tablet einen modernen We Alternativ kannst Du auch: -- [Eine Offline-Fassung dieses Buches erstellen](https://thebookofshaders.com/appendix/?lan=de) +- [Eine Offline-Fassung von diesem Buch erstellen](https://thebookofshaders.com/appendix/?lan=de) - [Die Beispielprogramme aus diesem Buch direkt auf einem RaspberryPi ausführen (ohne Internet-Browser)](https://thebookofshaders.com/appendix/?lan=de) -- [Eine PDF-Datei mit diesem Buch erzeugen, um es auszudrucken](https://thebookofshaders.com/appendix/?lan=de) +- [Eine druckbare PDF-Datei mit diesem Buch erzeugen](https://thebookofshaders.com/appendix/?lan=de) -- Die [Online-Ablage dieses Buches](https://github.com/patriciogonzalezvivo/thebookofshaders) bei GitHub nutzen, um Fehler zu melden und Programmcode mit anderen Lesern zu teilen. +- Die [Github-Seite von diesem Buch](https://github.com/patriciogonzalezvivo/thebookofshaders) nutzen, um Fehler zu melden und Programmcode mit anderen Lesern zu teilen. diff --git a/01/README-de.md b/01/README-de.md index ecdc774..15eaf80 100644 --- a/01/README-de.md +++ b/01/README-de.md @@ -1,13 +1,14 @@ # Einstieg + ## Was ist ein Fragment-Shader? -Im vorangegangenen Kapitel haben wir Fragment-Shader als eine Art Gutenbergsche Druckerpresse für Grafiken beschrieben. Nun, wie kommen wir darauf? Und vor allem: Was genau soll das sein, ein „Shader“? +Im vorangegangenen Kapitel haben wir Fragment-Shader als eine Art Gutenbergsche Druckerpresse für Computergrafiken beschrieben. Nun, wie kommen wir darauf? Und was genau soll ein Shader sein? ![Von Brief-für-Brief zu Seite-für-Seite. Rechts: William Blades (1891), links Rolt-Wheeler (1920).](print.png) -Falls Du schon Erfahrung mit der Erstellung von Computergrafiken gesammelt hast, kennst Du bestimmt die folgende Vorgehensweise: Man malt per Programmbefehl Kreise, Rechtecke, Dreiecke und Linien, damit auf dem Bildschirm nach und nach die gewünschte Grafik entsteht. Dieser Prozess erinnert stark an das Verfassen eines Dokuments per Hand, indem man einzelne Zeichen-Operationen Schritt für Schritt abarbeitet. +Falls Du schon Erfahrung mit der Erstellung von Computergrafiken gesammelt hast, kennst Du bestimmt die folgende Vorgehensweise: Man malt per Programmbefehl Kreise, Rechtecke, Dreiecke und Linien, damit auf dem Bildschirm nach und nach die gewünschte Grafik entsteht. Dieser Vorgang ähnelt von Hand einen Brief oder Buch zu verfassen. Es handelt sich um eine Folge von Anweisungen (den Zeichenoperationen), die Schritt für Schritt abgearbeiet werden müssen. -Auch Shader verkörpern eine Abfolge von Operationen, doch hier werden diese Operationen gleichzeitig für jeden Bildpunkt (Pixel) auf der Zeichenfläche ausgeführt. Das hat zur Folge, dass der Programmcode des Shaders in Abhängigkeit von der Lage des jeweils bearbeiteten Bildpunktes unterschiedlich agieren muss. Der Shader arbeitet dabei als eine Funktion, die die Koordinaten des jeweiligen Bildpunktes erhält und als Ergebnis die Farbe für diesen Bildpunkt zurückliefert. Ist der Shader einmal kompiliert, läuft dieser Prozess unglaublich schnell und für sehr viele Bildpunkte gleichzeitig ab. +Auch Shader sind nur eine Abfolge von Anweisungen, doch werden diese Anweisungen alle gleichzeitig für jeden Bildpunkt (Pixel) in der Grafik ausgeführt. Das bedeutet also, dass das von Dir geschriebene Shader-Programm die Grafik abhängig von der sich ändernden Position eines einzelnen Bildpunkts beschreiben muss. Der Shader arbeitet dabei als eine Funktion, die die Koordinaten des jeweiligen Bildpunktes erhält und als Ergebnis die Farbe für diesen Bildpunkt zurückliefert. Ist der Shader einmal kompiliert, läuft dieser Prozess unglaublich schnell und für sehr viele Bildpunkte gleichzeitig ab. ![Verschiebbare Lettern mit Chinesischen Symbolen](typepress.jpg) diff --git a/README-de.md b/README-de.md index d1e2402..5550a43 100644 --- a/README-de.md +++ b/README-de.md @@ -68,12 +68,12 @@ Dies ist eine behutsame Schritt-für-Schritt-Einführung in die komplexe und vie ## Über die Autoren -[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentinien) ist ein Künstler und Entwickler, der in New York lebt. Er erforscht die Räume zwischen Organischem und Synthetischem, Analogem und Digitalem, Individuen und Kollektiven. In seinen Arbeiten nutzt er Programmcode als Ausdrucksform, um das Zusammenwirken von Menschen zu verbessern. +[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentinien) ist ein Künstler und Entwickler, der in New York lebt. Er erforscht die Räume zwischen organisch und synthetisch, analog und digital, einzeln und zusammen. In seinen Arbeiten nutzt er Programmcode als Ausdrucksform, um das Zusammenwirken von Menschen zu verbessern. -Patricio hat Psychologie studiert, außerdem kunstorientiertes Handeln, die sogenannte „Expressive Arts Therapy“. Er hat einen MFA-Abschluss in „Design & Technology“ von der „Parsons The New School“, wo er auch unterrichtet. Zur Zeit arbeitet Patricio als Grafikingenieur bei der Firma Mapzen und entwickelt dort Open Source Werkzeuge für die Computer-Kartographie. +Patricio hat Psychologie studiert, außerdem kunstorientiertes Handeln (die sogenannte Expressive Arts Therapy). Er hat einen MFA-Abschluss in Design und Technologie von der Parsons New School For Design, wo er auch unterrichtet. Zur Zeit arbeitet Patricio als Grafikingenieur bei der Firma Mapzen und entwickelt dort Open-Source-Werkzeuge für die Computer-Kartographie. -[Jen Lowe](http://jenlowe.net/) ist eine unabhängige Datenwissenschaftlerin und Datenkommunikatorin bei der Firma Datatelling, wo sie Menschen, Zahlen und Sprache zusammenführt. Sie unterrichtet im Rahmen des „SVA Design for Social Innovation“-Programms, hat die Schule für „Poetic Computation“ mitbegründet, Mathematik für Künstler an der New Yorker ITP-Universität unterrichtet, Forschungen am „Spatial Information Design Lab“ der Columbia Universität durchgeführt und Beiträge für das „White House Office of Science and Technology“ geliefert, das den US-Präsidenten in Fragen des technischen Fortschritts berät. Als Sprecherin ist Jen auf Konferenzen wie der SXSW und der Eyeo aufgetreten. Von ihren Arbeiten hat unter anderem die New York Times, sowie das Magazin FastCompany berichtet. Ihre Forschungsarbeiten, Publikationen und Vorträge kreisen um die Versprechungen und Folgen von Daten und Technologien für die gesellschaftliche Entwicklung. Sie hat einen „Bachelor of Science“-Abschluss in angewandter Mathematik und einen Master-Abschluss in Informatik. Obwohl man angesichts dieser Biographie vielleicht etwas anderes vermuten könnte, schlägt sich Jen immer auf die Seite der Liebe. +[Jen Lowe](http://jenlowe.net/) ist eine unabhängige Datenwissenschaftlerin und Datenkommunikatorin bei der Firma Datatelling, wo sie Menschen, Zahlen und Sprache zusammenführt. Sie unterrichtet an der SVA das Fach Design for Social Innovation, hat die Schule für „Poetic Computation“ mitbegründet, Mathematik für Künstler an der New Yorker ITP-Universität unterrichtet, Forschungen am „Spatial Information Design Lab“ der Columbia Universität durchgeführt und Beiträge für das „White House Office of Science and Technology“ geliefert, das den US-Präsidenten in Fragen des technischen Fortschritts berät. Als Sprecherin ist Jen auf Konferenzen wie der SXSW und der Eyeo aufgetreten. Von ihren Arbeiten hat unter anderem die New York Times, sowie das Magazin FastCompany berichtet. Ihre Forschungsarbeiten, Publikationen und Vorträge kreisen um die Versprechungen und Folgen von Daten und Technologien für die gesellschaftliche Entwicklung. Sie hat einen Bachelor in angewandter Mathematik und einen Master in Informatik. Obwohl man angesichts dieser Biographie vielleicht etwas anderes vermuten könnte, schlägt sich Jen immer auf die Seite der Liebe. ## Danksagungen From 188740129dc4c3342a58a5c133ccb7e7f8c416fa Mon Sep 17 00:00:00 2001 From: Patricio Gonzalez Vivo Date: Mon, 11 Mar 2024 20:04:56 -0400 Subject: [PATCH 16/47] adding references to LYGIA and removing blender addon --- 04/README-fa.md | 22 ---------------------- 04/README-gr.md | 21 --------------------- 04/README-id.md | 18 ------------------ 04/README-pl.md | 25 ------------------------- 04/README-ua.md | 21 --------------------- 04/README-vi.md | 21 --------------------- 04/README.md | 21 --------------------- 04/blender/00.png | Bin 17253 -> 0 bytes 04/blender/01.png | Bin 9924 -> 0 bytes 04/blender/02.png | Bin 41868 -> 0 bytes 04/blender/03.png | Bin 446977 -> 0 bytes 05/README.md | 4 ++-- 06/README.md | 5 +++++ 07/README.md | 6 +++++- 08/README.md | 4 ++++ 10/README.md | 4 ++++ 11/README.md | 4 ++++ 12/README.md | 4 ++++ 13/README.md | 4 ++++ 19 files changed, 32 insertions(+), 152 deletions(-) delete mode 100644 04/blender/00.png delete mode 100644 04/blender/01.png delete mode 100644 04/blender/02.png delete mode 100644 04/blender/03.png diff --git a/04/README-fa.md b/04/README-fa.md index c27cfe3..9098cc8 100644 --- a/04/README-fa.md +++ b/04/README-fa.md @@ -208,25 +208,3 @@ void ofApp::draw(){ برای اطلاعات بیشتر در مورد استفاده از شیدر ها در openFrameworks سری به [excellent tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) ساخته شده توسط [Joshua Noble](http://thefactoryfactory.com/) بزنید. - - -### در **Blender** - -[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) یک افزونه است که امکان می‌دهد با برنامه نویسی و استفاده از GLSL، تکستچر تولید کنید. همچنین با بقیه محیط هم سازگار است. اینگونه کار می‌کند: - - -1. در سرچ بار: `F3` (یا spaceBar). تایپ کنید `GlslTexture` - -![](blender/00.png) - -2. طول و عرض و منبع را تغییر دهید (که میتواند مسیری به فایل خارجی باشد). - -![](blender/01.png) - -3. از این تصویر روی متریال خود اسفاده کنید. اسم عکس بر پایه اسم منبع تعریف می‌شود. - -![](blender/02.png) - -4. به Text Editor بروید (یا یک ادیتور خارجی در صورت تمایل) و شیدر را تغییر دهید. به صورت آنی(هات ریلود) تغییرات را مشاهده خواهید کرد. - -![](blender/03.png) diff --git a/04/README-gr.md b/04/README-gr.md index d7e0609..89741b1 100644 --- a/04/README-gr.md +++ b/04/README-gr.md @@ -210,24 +210,3 @@ void ofApp::draw(){ Για περισσότερες πληροφορίες για τους shaders σε openFrameworks δείτε αυτό το [εξαιρετικό μάθημα](http://openframeworks.cc/ofBook/chapters/shaders.html) από τον [Joshua Noble](http://thefactoryfactory.com/). - -### Σε **Blender** - -Το [GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) είναι ένα addon που επιτρέπει να παράξετε textures (υφές) προγραμματιστικά χρησιμοποιώντας GLSL Shaders, και είναι πλήρως συμβατό με τα υπόλοιπα απο τα sandboxes (περιβάλλοντα) αυτού του κεφαλαίου. Να πως λειτουργεί: - - -1. Αναζήτηση Operator: `F3` (ή `SpaceBar (διάστημα)` ανάλογα με τις επιλογές περιβάλλοντος του Blender). Γράψτε `GlslTexture` - -![](blender/00.png) - -2. Αλλάξτε τα μεγέθη `width` και `height` και το αρχείο `Source` (όπου μπορείτε να βάλετε το path -τοποθεσία- ενός εξωτερικού αρχείου). - -![](blender/01.png) - -3. Χρησιμοποιήστε την Εικόνα στα υλικά σας. Το όνομα της Εικόνας βασίζεται στο όνομα του αρχείου source (βλ. 2) - -![](blender/02.png) - -4. Πηγαίνετε στον Text Editor (επεξεργαστή κειμένου - ή έναν εξωτερικό επεξεργαστή κειμένου αν το source αρχείο είναι εξωτερικό) και αλλάξτε τον shader. Οι αλλαγές είναι άμεσα ορατές. - -![](blender/03.png) diff --git a/04/README-id.md b/04/README-id.md index 89c0178..2be74a1 100644 --- a/04/README-id.md +++ b/04/README-id.md @@ -209,22 +209,4 @@ void ofApp::draw(){ Untuk informasi lebih lanjut mengenai shader dalam openFrameworks lihatlah [tutorial bagus ini](https://processing.org/tutorials/pshader/). -### Dalam **Blender** -[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) adalah addon yang memperbolehkan menghasilkan tekstur menggunakan shader GLSL secara terprogram dan kompatibel sepenuhnya dengan sandbox lainnya di bab ini. Bagaimana itu bekerja: - -1. Operator Search: `F3` (atau `SpaceBar` tergantung pada setup). Cari `GlslTexture` - -![](blender/00.png) - -2. Ganti ukuran `width` and `height` dan berkas sumber `Source` (dapat menggunakan path file eksternal). - -![](blender/01.png) - -3. Gunakan gambar pada materialmu. Nama gambar akan berdasarkan pada nama file sumber. - -![](blender/02.png) - -4. Pergi ke Text Editor (atau eksternal editor jika file sumbermu di luar) dan edit shadernya. Ini akan memuat ulang. - -![](blender/03.png) diff --git a/04/README-pl.md b/04/README-pl.md index 1b231ea..6eb793c 100644 --- a/04/README-pl.md +++ b/04/README-pl.md @@ -249,28 +249,3 @@ void ofApp::draw(){ 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/). - -### W **Blender** - -[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) to addon pozwalający programistycznie generować textury z użyciem shaderów GLSL. Jest on w pełni kompatybilny z resztą sandboxów w tym rozdziale. Jak go użyć? - - - - -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. - - -![](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. - - -![](blender/03.png) diff --git a/04/README-ua.md b/04/README-ua.md index 6873511..884e11b 100644 --- a/04/README-ua.md +++ b/04/README-ua.md @@ -210,24 +210,3 @@ void ofApp::draw(){ Щоб дізнатися більше про шейдери в openFrameworks, перегляньте цей [чудовий посібник](http://openframeworks.cc/ofBook/chapters/shaders.html), створений [Joshua Noble](http://thefactoryfactory.com/). - -### **Blender** - -[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) — це доповнення, яке дозволяє програмно генерувати текстури за допомогою шейдерів GLSL і повністю сумісне з рештою прикладів даного розділу. Як це працює: - - -1. Ввімкніть пошук: `F3` або `пробіл`, залежно від налаштувань. Введіть `GlslTexture`: - -![](blender/00.png) - -2. Змініть значення розмірів для полів `width`, `height` та `Source`-шлях до зовнішнього файлу, якщо такий є. - -![](blender/01.png) - -3. Використовуйте зображення у своїх матеріалах. Ім’я зображення базуватиметься на назві вихідного файлу. - -![](blender/02.png) - -4. Перейдіть до текстового редактора (або зовнішнього редактора, якщо ваш вихідний файл також зовнішній) і відредагуйте шейдер. Після чого відбудеться оновлення результату. - -![](blender/03.png) diff --git a/04/README-vi.md b/04/README-vi.md index 1645388..70e4cc6 100644 --- a/04/README-vi.md +++ b/04/README-vi.md @@ -210,24 +210,3 @@ void ofApp::draw(){ Để tìm hiểu thêm về shader trong openFrameworks hãy đọc [bài hướng dẫn tuyệt vời này](http://openframeworks.cc/ofBook/chapters/shaders.html) của [Joshua Noble](http://thefactoryfactory.com/). - - -### Với **Blender** - -[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) là một addon giúp bạn tạo ra các texture theo công thức của GLSL và hoàn toàn tương thích với các sandbox khác trong chương này. Cách mà nó hoạt động: - -1. Operator Search: `F3` (hoặc gõ phím `Space` tuỳ theo chỉnh sửa của bạn). Gõ `GlslTexture` - -![](blender/00.png) - -2. Đổi kích thước `width` và `height` và tên file shader ở `Source` (có thể là đường dẫn tới 1 file khác) - -![](blender/01.png) - -3. Sử dụng ảnh trong chất liệu. Tên của ảnh sẽ dựa trên tên của file shader. - -![](blender/02.png) - -4. Mở phần Text Editor và viết shader (hoặc sửa từ bên ngoài). Nó sẽ được cập nhật ngay lập tức. - -![](blender/03.png) diff --git a/04/README.md b/04/README.md index 444dcf0..1d64e95 100644 --- a/04/README.md +++ b/04/README.md @@ -210,24 +210,3 @@ void ofApp::draw(){ 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/). - -### In **Blender** - -[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` (or `SpaceBar` depending on your setup). Type `GlslTexture` - -![](blender/00.png) - -2. Change `width` and `height` size and `Source` file (which can be a path to an external file). - -![](blender/01.png) - -3. Use the Image on your materials. The Image name will be based on the name of the source file. - -![](blender/02.png) - -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) diff --git a/04/blender/00.png b/04/blender/00.png deleted file mode 100644 index ab2e362e20a01fb48e8f771e22ac69ebc168248a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17253 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 diff --git a/04/blender/01.png b/04/blender/01.png deleted file mode 100644 index d2171fdf48251c0580eb23e01db37163ec54727e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9924 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 diff --git a/04/blender/02.png b/04/blender/02.png deleted file mode 100644 index b5a83350f2edd476c5898b2b5ed62be28e5422c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41868 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

NTJMYanUw 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

L+Bs7e+E(~-uhkHvpSvsbpD(J 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 z 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≫;X_ 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 A@c;k- diff --git a/05/README.md b/05/README.md index f0fd98f..826e835 100644 --- a/05/README.md +++ b/05/README.md @@ -125,10 +125,10 @@ Take a look at the following table of equations made by [Kynd](http://www.kynd.i #### For your toolbox -Here are some tools that will make it easier for you to visualize these types of functions. +* [LYGIA](https://lygia.xyz/) is a shader library of reusable functions that can be include easily on your projects. It's very granular, designed for reusability, performance and flexibility. And can be easily be added to any projects and frameworks. It's divided in different sections and it have an entire one for[math operations](https://lygia.xyz/math) + * [GraphToy](http://www.iquilezles.org/apps/graphtoy/): once again [Iñigo Quilez](http://www.iquilezles.org) made a tool to visualize GLSL functions in WebGL. ![Iñigo Quilez - GraphToy (2010)](graphtoy.png) -* [LYGIA Shader Library](https://lygia.xyz/) a shader library of reusable functions that can be include easily on your projects. It's very granular, designed for reusability, performance and flexibility. And can be easily be added to any projects and frameworks. diff --git a/06/README.md b/06/README.md index addb535..75c2f42 100644 --- a/06/README.md +++ b/06/README.md @@ -132,3 +132,8 @@ int newFunction(in vec4 aVec4, // read-only ``` 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. + + +#### For your toolbox + +* [LYGIA's color shader functions ](https://lygia.xyz/color) are set of reusable functions to manipulate colors in GLSL. It includes functions to convert between color spaces, to blend colors, to create gradients, and to apply color transformations. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. diff --git a/07/README.md b/07/README.md index 61d6222..281b760 100644 --- a/07/README.md +++ b/07/README.md @@ -228,6 +228,10 @@ The trick will use the number of edges of a polygon to construct the distance fi Congratulations! You have made it through the rough part! Take a break and let these concepts settle - drawing simple shapes in Processing is easy but not here. In shader-land drawing shapes is twisted, and it can be exhausting to adapt to this new paradigm of coding. -Down at the end of this chapter you will find a link to [PixelSpirit Deck](https://patriciogonzalezvivo.github.io/PixelSpiritDeck/) this deck of cards will help you learn new SDF functions, compose them into your designs and use on your shaders. The deck has a progressive learning curve, so taking one card a day and working on it will push and challenge your skills for months. +#### For your toolbox + +* [LYGIA's draw functions ](https://lygia.xyz/draw) are set of reusable functions to draw 2D shapes and patterns. You can also explore [LYGIA's SDF functions folder](https://lygia.xyz/sdf) to combine more complex shapes through distance fields. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. + +* Down at the end of this chapter you will find a link to [PixelSpirit Deck](https://patriciogonzalezvivo.github.io/PixelSpiritDeck/) this deck of cards will help you learn new SDF functions, compose them into your designs and use on your shaders. The deck has a progressive learning curve, so taking one card a day and working on it will push and challenge your skills for months. Now that you know how to draw shapes I'm sure new ideas will pop into your mind. In the following chapter you will learn how to move, rotate and scale shapes. This will allow you to make compositions! diff --git a/08/README.md b/08/README.md index c67587f..dc1aa8a 100644 --- a/08/README.md +++ b/08/README.md @@ -99,3 +99,7 @@ The following code is an interesting opportunity to use matrix operations in GLS As you can see we are treating colors as vectors by multiplying them with matrices. In that way we “move” the values around. In this chapter we've learned how to use matrix transformations to move, rotate and scale vectors. These transformations will be essential for making compositions out of the shapes we learned about in the previous chapter. In the next chapter we'll apply all we've learned to make beautiful procedural patterns. You will find that coding repetition and variation can be an exciting practice. + +#### For your toolbox + +* [LYGIA's space functions ](https://lygia.xyz/space) are set of reusable functions to manipulate space in GLSL. It's a great resource to learn how to use matrices to manipulate space. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. \ No newline at end of file diff --git a/10/README.md b/10/README.md index e16ccbf..e79c014 100644 --- a/10/README.md +++ b/10/README.md @@ -90,3 +90,7 @@ Take a look at [Ikeda](http://www.ryojiikeda.com/)'s work and try the following Using random aesthetically can be problematic, especially if you want to make natural-looking simulations. Random is simply too chaotic and very few things look ```random()``` in real life. If you look at a rain pattern or a stock chart, which are both quite random, they are nothing like the random pattern we made at the begining of this chapter. The reason? Well, random values have no correlation between them what so ever, but most natural patterns have some memory of the previous state. In the next chapter we will learn about noise, the smooth and *natural looking* way of creating computational chaos. + +#### For your toolbox + +* [LYGIA's generative functions ](https://lygia.xyz/generative) are a set of reusable functions to generate patterns in GLSL. It's a great resource to learn how to use randomness and noise to create generative art. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. \ No newline at end of file diff --git a/11/README.md b/11/README.md index ae410ae..e6c83b7 100644 --- a/11/README.md +++ b/11/README.md @@ -218,3 +218,7 @@ In the following chapters we will see some well known techniques to perfect your

"Talk to the tree, make friends with it." Bob Ross

+ +#### For your toolbox + +* [LYGIA's generative functions ](https://lygia.xyz/generative) are a set of reusable functions to generate patterns in GLSL. It's a great resource to learn how to use randomness and noise to create generative art. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. \ No newline at end of file diff --git a/12/README.md b/12/README.md index ed4034f..4f6c83f 100644 --- a/12/README.md +++ b/12/README.md @@ -188,3 +188,7 @@ Now it's time for you to look closely at things, be inspired by nature and find ![Deyrolle glass film - 1831](DeyrolleFilm.png)
+ +#### For your toolbox + +* [LYGIA's generative functions ](https://lygia.xyz/generative) are a set of reusable functions to generate patterns in GLSL. It's a great resource to learn how to use randomness and noise to create generative art. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. \ No newline at end of file diff --git a/13/README.md b/13/README.md index a23670b..1c1a29f 100644 --- a/13/README.md +++ b/13/README.md @@ -109,3 +109,7 @@ A less extreme example of this technique is the following code where the wrap is
Warping the texture coordinates with noise in this manner can be very useful, a lot of fun, and fiendishly difficult to master. It's a powerful tool, but it takes quite a bit of experience to use it well. A useful tool for this is to displace the coordinates with the derivative (gradient) of the noise. [A famous article by Ken Perlin and Fabrice Neyret called "flow noise"](http://evasion.imag.fr/Publications/2001/PN01/) is based on this idea. Some modern implementations of Perlin noise include a variant that computes both the function and its analytical gradient. If the "true" gradient is not available for a procedural function, you can always compute finite differences to approximate it, although this is less accurate and involves more work. + +#### For your toolbox + +* [LYGIA's generative functions ](https://lygia.xyz/generative) are a set of reusable functions to generate patterns in GLSL. It's a great resource to learn how to use randomness and noise to create generative art. It's very granular library, designed for reusability, performance and flexibility. And it can be easily be added to any projects and frameworks. \ No newline at end of file From a6f2950a2a6ad4de9e087e3110430823062a0af3 Mon Sep 17 00:00:00 2001 From: Yehor <20585619+satelllte@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:52:14 +0300 Subject: [PATCH 17/47] theme: prevent flicker on first load --- footer.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/footer.php b/footer.php index 5ec218e..dcde0fc 100644 --- a/footer.php +++ b/footer.php @@ -3,6 +3,12 @@
+ + + '; From 45b66fbcf8d4162f21204df495a04e00d943f6b5 Mon Sep 17 00:00:00 2001 From: Lavanya Mittal Date: Thu, 14 Nov 2024 10:19:25 -0500 Subject: [PATCH 18/47] fix comment --- 07/shapes.frag | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/07/shapes.frag b/07/shapes.frag index 6d7f5d8..7f409bd 100644 --- a/07/shapes.frag +++ b/07/shapes.frag @@ -24,8 +24,10 @@ void main(){ // Number of sides of your shape int N = 3; - // Angle and radius from the current pixel + // Angle from the current pixel float a = atan(st.x,st.y)+PI; + + // Angular spacing between vertices of shape (in radians) float r = TWO_PI/float(N); // Shaping function that modulate the distance From 65bdf90a0082e42b399d207084059432a17e4dca Mon Sep 17 00:00:00 2001 From: Lavanya Mittal Date: Thu, 14 Nov 2024 10:32:13 -0500 Subject: [PATCH 19/47] remove in radians since its obvious --- 07/shapes.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/07/shapes.frag b/07/shapes.frag index 7f409bd..e68744b 100644 --- a/07/shapes.frag +++ b/07/shapes.frag @@ -27,7 +27,7 @@ void main(){ // Angle from the current pixel float a = atan(st.x,st.y)+PI; - // Angular spacing between vertices of shape (in radians) + // Angular spacing between vertices of shape float r = TWO_PI/float(N); // Shaping function that modulate the distance From 20421841edfc25d20476f9d51f9886f53f03acc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Moror=C3=B3?= Date: Mon, 16 Dec 2024 11:31:24 -0300 Subject: [PATCH 20/47] Fix plural agreement in the portuguese translation --- 00/README-pt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/00/README-pt.md b/00/README-pt.md index d675a43..5f2eecf 100644 --- a/00/README-pt.md +++ b/00/README-pt.md @@ -34,7 +34,7 @@ O que esse livro não cobre: ## O que você precisa para começar? -Não muito! Se você tem um browser modernos que possa rodar WebGL (como Chrome, Firefox ou Safari) e uma conexão à internet, clique no botão para o próximo capítulo no fim desta página para começar. +Não muito! Se você tem um browser moderno que possa rodar WebGL (como Chrome, Firefox ou Safari) e uma conexão à internet, clique no botão para o próximo capítulo no fim desta página para começar. Alternativamente, baseado no que você tem, ou no que você precisa deste livro você pode: From 5873c7bf5b5598ef295583e2640f80c0b96007fa Mon Sep 17 00:00:00 2001 From: Tong Wu Date: Tue, 24 Dec 2024 16:19:38 -0800 Subject: [PATCH 21/47] fix: links to appendix entries --- 00/README-ch.md | 6 +++--- README-ch.md | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/00/README-ch.md b/00/README-ch.md index 31c75f5..2943f9f 100644 --- a/00/README-ch.md +++ b/00/README-ch.md @@ -42,10 +42,10 @@ Fragment shaders(片段着色器)可以让你控制像素在屏幕上的快 此外,基于你有的条件或需求你可以: -* [制作一个离线版的本书](https://thebookofshaders.com/appendix/) +* [制作一个离线版的本书](https://thebookofshaders.com/appendix/00/?lan=ch) -* [用树莓派而不是浏览器来运行书中示例](https://thebookofshaders.com/appendix/) +* [用树莓派而不是浏览器来运行书中示例](https://thebookofshaders.com/appendix/01/?lan=ch) -* [做一个PDF版的书用于打印](https://thebookofshaders.com/appendix/) +* [做一个PDF版的书用于打印](https://thebookofshaders.com/appendix/02/?lan=ch) * 用[github仓库](https://github.com/patriciogonzalezvivo/thebookofshaders)来帮助解决问题和分享代码 diff --git a/README-ch.md b/README-ch.md index 64df50e..dc87018 100644 --- a/README-ch.md +++ b/README-ch.md @@ -60,10 +60,10 @@ * 环境贴图 (spherical and cube) * 折射和反射 -* [附录:](appendix/) 其他阅读本书的方式 - * [如何离线阅读此书?](appendix/?lan=ch) - * [如何在树莓派上运行示例程序?](appendix/?lan=ch) - * [如何打印这本书](appendix/?lan=ch) +* [附录:](appendix/?lan=ch) 其他阅读本书的方式 + * [如何离线阅读此书?](appendix/00/?lan=ch) + * [如何在树莓派上运行示例程序?](appendix/01/?lan=ch) + * [如何打印这本书](appendix/02/?lan=ch) * [example gallery](examples/?lan=ch) From e0e030c61e94512f09ce71ddbfe02b87850e3fd1 Mon Sep 17 00:00:00 2001 From: Tong Wu Date: Tue, 24 Dec 2024 16:20:01 -0800 Subject: [PATCH 22/47] chore: add missing appendix entries in ToC --- README-ch.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README-ch.md b/README-ch.md index dc87018..e2d9c3e 100644 --- a/README-ch.md +++ b/README-ch.md @@ -64,6 +64,8 @@ * [如何离线阅读此书?](appendix/00/?lan=ch) * [如何在树莓派上运行示例程序?](appendix/01/?lan=ch) * [如何打印这本书](appendix/02/?lan=ch) + * [我怎样共创这本书](appendix/03/?lan=ch) + * [给那些从JS语言过来的人的介绍](appendix/04/?lan=ch) by [Nicolas Barradeau](http://www.barradeau.com/) * [example gallery](examples/?lan=ch) From 7f2c67c04e6329190bc6cb16a0b28095d9d5405a Mon Sep 17 00:00:00 2001 From: Tong Wu Date: Tue, 24 Dec 2024 16:21:01 -0800 Subject: [PATCH 23/47] fix: use correct ch translation --- 00/README-ch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/00/README-ch.md b/00/README-ch.md index 2943f9f..b8e28e9 100644 --- a/00/README-ch.md +++ b/00/README-ch.md @@ -44,7 +44,7 @@ Fragment shaders(片段着色器)可以让你控制像素在屏幕上的快 * [制作一个离线版的本书](https://thebookofshaders.com/appendix/00/?lan=ch) -* [用树莓派而不是浏览器来运行书中示例](https://thebookofshaders.com/appendix/01/?lan=ch) +* [用不带浏览器的树莓派来运行书中示例](https://thebookofshaders.com/appendix/01/?lan=ch) * [做一个PDF版的书用于打印](https://thebookofshaders.com/appendix/02/?lan=ch) From a0939cc6bc2d7b840469e126214dbb887ce95aeb Mon Sep 17 00:00:00 2001 From: JasonnnW3000 Date: Wed, 1 Jan 2025 12:00:11 -0500 Subject: [PATCH 24/47] Update LICENSE, fix license year Signed-off-by: JasonnnW3000 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e2f0194..76aa1e8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Patricio Gonzalez Vivo - http://patriciogonzalezvivo.com/ +Copyright (c) 2025 Patricio Gonzalez Vivo - http://patriciogonzalezvivo.com/ All rights reserved. I am the sole copyright owner of this Work. From 15a21effaaaa49833ca9b244ecafb0268edaa69d Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:48:26 +0100 Subject: [PATCH 25/47] fix typos in Polish version of chapter 00 --- 00/README-pl.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/00/README-pl.md b/00/README-pl.md index 485ba7e..0af79e6 100644 --- a/00/README-pl.md +++ b/00/README-pl.md @@ -2,14 +2,14 @@ -Powyższe obrazy zostały stworzone na różny sposób. Pierwszy stworzył Van Gogh, aplikując farbę warstwa po wartwie. Zajęło mu to godziny. Drugi z nich stworzono poprzez połączenie czterech macierzy zawierających piksele koloru niebieskozielonego (cyjan), magenty, żółtego i czarnego. Kluczowa różnicę stanowi fakt, że drugi obraz stworzny został natychmiastowo (przez komputer), a nie seryjnie, krok po kroku (przez malarza). +Powyższe obrazy zostały stworzone na różny sposób. Pierwszy stworzył Van Gogh, aplikując farbę warstwa po warstwie. Zajęło mu to godziny. Drugi z nich stworzono poprzez połączenie czterech macierzy zawierających piksele koloru niebieskozielonego (cyjan), magenty, żółtego i czarnego. Kluczową różnicę stanowi fakt, że drugi obraz stworzony został natychmiastowo (przez komputer), a nie seryjnie, krok po kroku (przez malarza). Ta książka jest o rewolucyjnej technice obliczeniowej, tzw. *fragment shaderach* (zwanych też *pixel shaderami*), które wznoszą cyfrowo generowane obrazy na wyższy poziom. Możesz o nich myśleć jak o ekwiwalencie maszyny drukarskiej Gutenberga dla zastosowań graficznych. ![Gutenberg's press](gutenpress.jpg) -Fragment shadery dają ci pełnię kontroli nad błyskawicznym renderowaniem pikseli na ekranie. Właśnie dlatego są one używane w przeróżnych sytuacjach: od filtrów wideo w telefonach do niesamowitych twójwymiarowych gier wideo. +Fragment shadery dają ci pełnię kontroli nad błyskawicznym renderowaniem pikseli na ekranie. Właśnie dlatego są one używane w przeróżnych sytuacjach: od filtrów wideo w telefonach do niesamowitych trójwymiarowych gier wideo. ![Journey by That Game Company](journey.jpg) @@ -17,15 +17,15 @@ W następujących rozdziałach odkryjesz jak niewiarygodnie szybkie i potężne ## Dla kogo jest ta książka? -Ta książka jest napisana dla osób zainteresowanych *creative coding*'iem, game developerów i inżynierów, którzy posiadają doświadczenie programistyczne, podstawową wiedzę z algebry liniowej i trygonometrii, i którzy chcą podnieść jakość swoich prac graficzny na wyższy poziom. (Jeżeli chcesz nauczyć się programować, polecam zacząć od [Processing](https://processing.org/) i wrócić, gdy opanujesz go do komfortowego poziomu. +Ta książka jest napisana dla osób zainteresowanych *creative coding*iem, game developerów i inżynierów, którzy posiadają doświadczenie programistyczne, podstawową wiedzę z algebry liniowej i trygonometrii, i którzy chcą podnieść jakość swoich prac graficznych na wyższy poziom. (Jeżeli chcesz nauczyć się programować, polecam zacząć od [Processing](https://processing.org/) i wrócić, gdy opanujesz go do komfortowego poziomu.) Ta książka nauczy cię jak używać shadery w celu polepszenia wydajności i wyglądu twoich projektów. Ponieważ shadery GLSL (OpenGL Shading Language) kompilują i uruchamiają się na różnorodnych platformach, będziesz w stanie zaaplikować tutaj zdobytą wiedzę do jakiegokolwiek środowiska wykorzystującego OpenGL, OpenGL ES lub WebGL. Innymi słowy, będziesz w stanie wykorzystać tę wiedzę przy tworzeniu szkiców z [Processing](https://processing.org/), aplikacji z [openFrameworks](http://openframeworks.cc/), interaktywnych instalacji z [Cinder](http://libcinder.org/) czy stron internetowych z [Three.js](http://threejs.org/) i gier iOS/Android. ## Jaki materiał pokrywa ta książka? -Ta książka skupia się na użyciu fragment shaderów GLSL. Wpierw zdefiniujemy czym shadery są; potem dowiemy się jak, z ich pomocą, tworzyć proceduralne kształty, wzory, tekstury i animacje. Nauczysz się podstaw języka shadingowego i jego przydatnych aplikacji w przetwarzaniu obrazów (operacje na obrazach, sploty macierzowe, rozmycia, filtry koloru, "lookup tables" i inne efekty) czy symulacji ("Gra w życie" Conwaya, model reakcji-dyfuzji Graya-Scotta, plusk wody, efekt akwareli, komórki Voronoi, itp.). Pod koniec książki zobaczymy kilka zaawansowanych technik opartych o Ray Marching. +Ta książka skupia się na użyciu fragment shaderów GLSL. Najpierw zdefiniujemy czym shadery są; potem dowiemy się jak, z ich pomocą, tworzyć proceduralne kształty, wzory, tekstury i animacje. Nauczysz się podstaw języka shadingowego i jego przydatnych aplikacji w przetwarzaniu obrazów (operacje na obrazach, sploty macierzowe, rozmycia, filtry koloru, "lookup tables" i inne efekty) czy symulacji ("Gra w życie" Conwaya, model reakcji-dyfuzji Graya-Scotta, plusk wody, efekt akwareli, komórki Voronoi, itp.). Pod koniec książki zobaczymy kilka zaawansowanych technik opartych o Ray Marching. -*W każdym rozdziale znajdziesz interaktywne przykłady do wypróbowania.* Kiedy zmodyfikujesz kod, natychmiastowo zobaczysz zmiany. Zagadnienia mogą być abstrakcyjne i mylące, więc takie interkatywne przykłady stanowią konieczną pomoc w zrozumieniu materiału. Im szybciej złapiesz praktykę, tym prostsza będzie dalsza nauka. +*W każdym rozdziale znajdziesz interaktywne przykłady do wypróbowania.* Kiedy zmodyfikujesz kod, natychmiastowo zobaczysz zmiany. Zagadnienia mogą być abstrakcyjne i mylące, więc takie interaktywne przykłady stanowią konieczną pomoc w zrozumieniu materiału. Im szybciej złapiesz praktykę, tym prostsza będzie dalsza nauka. Materiał, którego ta książka nie pokrywa: @@ -42,9 +42,9 @@ Alternatywnie, w zależności od tego, co masz albo co potrzebujesz od tej ksią - [Stworzyć wersję off-line tej książki](https://thebookofshaders.com/appendix/00/?lan=pl) -- [Uruchomić przykłady na Raspberry PI bez przeglądarki](https://thebookofshaders.com/appendix/01/?lan=pl) +- [Uruchomić przykłady na Raspberry Pi bez przeglądarki](https://thebookofshaders.com/appendix/01/?lan=pl) - [Stworzyć wersję PDF tej książki do wydrukowania](https://thebookofshaders.com/appendix/02/?lan=pl) -- Sprawdź [repozytorium GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) tej książki, by pomóc rożwiązać issues i podzielić się swoim kodem. +- Sprawdź [repozytorium GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) tej książki, by pomóc rozwiązać issues i podzielić się swoim kodem. From 96b62b9dbbb380531968fb18b2941d908e71dae6 Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:52:26 +0100 Subject: [PATCH 26/47] fix typos in Polish version of README --- README-pl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-pl.md b/README-pl.md index c3ffe1a..c204da7 100644 --- a/README-pl.md +++ b/README-pl.md @@ -38,7 +38,7 @@ * Image operations * Kernel convolutions * Filters - * Others effects + * Other effects * Simulation * Pingpong @@ -80,7 +80,7 @@ Patricio studiował i praktykował psychoterapię oraz arteterapię. Otrzymał t ## Podziękowania -Podziękowania dla [Scott Murray](http://alignedleft.com/) za porady i inspriację. +Podziękowania dla [Scott Murray](http://alignedleft.com/) za porady i inspirację. Podziękowania dla [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo), [Nicolas Barradeau](https://twitter.com/nicoptere), [Karim Naaji](http://karim.naaji.fr/) za wsparcie, dobre pomysły i kod. From 3f28f144a1da3cb3b802256c19570986324312de Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:59:20 +0100 Subject: [PATCH 27/47] fix typos in Polish version of chapter 01 --- 01/README-pl.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/01/README-pl.md b/01/README-pl.md index 555a18c..111fd3b 100644 --- a/01/README-pl.md +++ b/01/README-pl.md @@ -28,7 +28,7 @@ Wyobraź sobie procesor twojego komputera jako potok przetwarzania (ang. "pipeli ![CPU](00.jpeg) -Gry video i inne aplikacje graficzne wymagają zdecydowanie więcej mocy obliczeniowej niż większość programów, gdyż muszą wykonywać ogromne ilości operacji piksel po pikselu. Nie dość, że każdy pojedynczy piksel musi być obliczony, to w wypadku gier 3D dochodzą do tego obliczenia geometryczne i obliczenie perspektywy. +Gry wideo i inne aplikacje graficzne wymagają zdecydowanie więcej mocy obliczeniowej niż większość programów, gdyż muszą wykonywać ogromne ilości operacji piksel po pikselu. Nie dość, że każdy pojedynczy piksel musi być obliczony, to w przypadku gier 3D dochodzą do tego obliczenia geometryczne i obliczenie perspektywy. @@ -44,7 +44,7 @@ Z pomocą przychodzi przetwarzanie równoległe. Zamiast kilku dużych, potężn ![GPU](04.jpeg) -Wyobraź sobie mały mikroprocesor jako tablicę rur (spójrz na obrazek powyżej), a dane jako piłeczki ping pongowe. 14.400.000 piłeczek ping pongowych na sekundę może zablokować prawie każdą pojedynczą rurę. Ale tabela 800x600 malutkich rur przyjmująca co sekundę 30 fal po 480.000 piłeczek poradzi sobie z nimi bez problemu. Tak samo działa to na wyższych rozdzielczościach - im więcej równolegle pracującego hardware'u, tym większy potok, z którymi GPU sobie poradzi. +Wyobraź sobie mały mikroprocesor jako tablicę rur (spójrz na obrazek powyżej), a dane jako piłeczki ping pongowe. 14.400.000 piłeczek ping pongowych na sekundę może zablokować prawie każdą pojedynczą rurę. Ale tabela 800x600 malutkich rur przyjmująca co sekundę 30 fal po 480.000 piłeczek poradzi sobie z nimi bez problemu. Tak samo działa to na wyższych rozdzielczościach - im więcej równolegle pracującego hardware'u, tym większy potok, z którym GPU sobie poradzi. @@ -64,7 +64,7 @@ Jak to mówią: "with great power comes great responsibility". Stosuje się to r -Aby wątki mogły działać równolegle, muszą być od siebie niezależne. Mówimy, że wątki są *ślepe* na to, co robi reszta wątków. Ograniczenie to implikuje, że dane muszą "płynąć w ten samą stronę" - nie jest możliwe sprawdzić dane wyjściowe innego wątku, zmodyfikować jego dane wejściowe albo przekazać dane wyjściowe jednego wątku jako dane wejściowe innego. +Aby wątki mogły działać równolegle, muszą być od siebie niezależne. Mówimy, że wątki są *ślepe* na to, co robi reszta wątków. Ograniczenie to implikuje, że dane muszą "płynąć w tę samą stronę" - nie jest możliwe sprawdzić dane wyjściowe innego wątku, zmodyfikować jego dane wejściowe albo przekazać dane wyjściowe jednego wątku jako dane wejściowe innego. @@ -72,6 +72,6 @@ Poza tym GPU odpowiada za to, żeby każdy wątek miał coś do roboty, i żeby -Ale nie martw się! W następnych rozdziałąch nauczymy się, krok po kroku, prostych i zaawansowanych obliczeń shadingowych. Jeżeli czytasz to we współczesnej przeglądarce, to z pewnością docenisz zabawę z interaktywnymi przykładami. Ale nie przedłużajmy! Naciśnij *Next>>* aby przejść dalej. +Ale nie martw się! W następnych rozdziałach nauczymy się, krok po kroku, prostych i zaawansowanych obliczeń shadingowych. Jeżeli czytasz to we współczesnej przeglądarce, to z pewnością docenisz zabawę z interaktywnymi przykładami. Ale nie przedłużajmy! Naciśnij *Next>>* aby przejść dalej. From c4583dc5cac76b73b89ddab1d81cc57e3380d267 Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 21:20:54 +0100 Subject: [PATCH 28/47] fixed translations in Polish version of chapter 00 --- 00/README-pl.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/00/README-pl.md b/00/README-pl.md index 0af79e6..c71a6e4 100644 --- a/00/README-pl.md +++ b/00/README-pl.md @@ -2,7 +2,7 @@ -Powyższe obrazy zostały stworzone na różny sposób. Pierwszy stworzył Van Gogh, aplikując farbę warstwa po warstwie. Zajęło mu to godziny. Drugi z nich stworzono poprzez połączenie czterech macierzy zawierających piksele koloru niebieskozielonego (cyjan), magenty, żółtego i czarnego. Kluczową różnicę stanowi fakt, że drugi obraz stworzony został natychmiastowo (przez komputer), a nie seryjnie, krok po kroku (przez malarza). +Powyższe obrazy zostały stworzone na różne sposoby. Pierwszy z nich stworzył Van Gogh, aplikując farbę warstwa po warstwie. Zajęło mu to godziny. Drugi stworzono poprzez połączenie czterech macierzy pikseli odpowiadających kolorom: cyjan, magenta, żółty i czarny. Kluczową różnicę stanowi fakt, że drugi obraz stworzony został natychmiastowo (przez komputer), a nie seryjnie, krok po kroku (przez malarza). Ta książka jest o rewolucyjnej technice obliczeniowej, tzw. *fragment shaderach* (zwanych też *pixel shaderami*), które wznoszą cyfrowo generowane obrazy na wyższy poziom. Możesz o nich myśleć jak o ekwiwalencie maszyny drukarskiej Gutenberga dla zastosowań graficznych. @@ -31,7 +31,7 @@ Materiał, którego ta książka nie pokrywa: * To *nie jest* książka o OpenGL lub WebGL. OpenGL/WebGL jest większym tematem niż GLSL czy fragment shadery. Jeśli chcesz wiedzieć więcej o OpenGL i WebGL, polecam zajrzeć do [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (zwana również "czerwoną książką") lub [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) -* To *nie jest* książka do nauki matematyki. Choć opisane są w niej algorytmy i techniki, które opierają się zrozumieniu algebry i trygonometrii, to nie będziemy ich szczegółowo tłumaczyć. Z pytaniami dotyczącymi matematyki polecam zajrzeć do następujących książek: +* To *nie jest* książka do nauki matematyki. Choć opisane są w niej algorytmy i techniki, które opierają się na zrozumieniu algebry i trygonometrii, to nie będziemy ich szczegółowo tłumaczyć. Z pytaniami dotyczącymi matematyki polecam zajrzeć do następujących książek: [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) lub [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). ## Co potrzeba, żeby zacząć? @@ -40,11 +40,11 @@ Niewiele! Jeśli masz współczesną przeglądarkę, która obsługuje WebGL (ja Alternatywnie, w zależności od tego, co masz albo co potrzebujesz od tej książki, możesz: -- [Stworzyć wersję off-line tej książki](https://thebookofshaders.com/appendix/00/?lan=pl) +- [Stworzyć wersję offline tej książki](https://thebookofshaders.com/appendix/00/?lan=pl) - [Uruchomić przykłady na Raspberry Pi bez przeglądarki](https://thebookofshaders.com/appendix/01/?lan=pl) - [Stworzyć wersję PDF tej książki do wydrukowania](https://thebookofshaders.com/appendix/02/?lan=pl) -- Sprawdź [repozytorium GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) tej książki, by pomóc rozwiązać issues i podzielić się swoim kodem. +- Sprawdź [repozytorium GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) tej książki, by pomóc w rozwiązywaniu problemów (issues) i podzielić się swoim kodem. From 301bdefb5ec79761a106089aa363d9c0d1833b18 Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 21:22:19 +0100 Subject: [PATCH 29/47] fixed typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d82c896..22416d3 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ This is a gentle step-by-step guide through the abstract and complex universe of * Image operations * Kernel convolutions * Filters - * Others effects + * Other effects * Simulation * Pingpong From 292c20ab6ab200922e733a9e273a6efaaa8a176b Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 21:31:51 +0100 Subject: [PATCH 30/47] fix typos and translations in Polish version of chapter 02 --- 02/README-pl.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/02/README-pl.md b/02/README-pl.md index ae8196a..de1ccaa 100644 --- a/02/README-pl.md +++ b/02/README-pl.md @@ -1,6 +1,6 @@ ## Witaj świecie! -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. +Zazwyczaj przykład "Hello world!" stanowi pierwszy krok przy nauce nowego języka. Jest to prosty jednolinijkowy program, który zwraca pełną entuzjazmu wiadomość powitalną i tym samym zapowiada nadchodzące przygody. @@ -10,7 +10,7 @@ W świecie GPU renderowanie tekstu jest jednak zbyt skomplikowanym zadaniem dla
-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. +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. @@ -24,7 +24,7 @@ Choć kod jest prosty, to możemy wyciągnąć z niego ważne wnioski: 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. Kolejną 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 `#` i ewaluowane są podczas procesu prekompilacji poprzedzającego kompilację. W naszym powyższym przykładzie linijka 2 kompilowana jest tylko wtedy, gdy zmienna `GL_ES` jest zdefiniowana (co występuje na urządzeniach mobilnych i w przeglądarkach). +5. Kolejną 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 `#` i ewaluowane są podczas procesu prekompilacji poprzedzającego kompilację. W naszym powyższym przykładzie linijka 2 kompilowana jest tylko wtedy, gdy zmienna `GL_ES` jest zdefiniowana (co występuje na urządzeniach mobilnych i w przeglądarkach). -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;`). +6. Typy zmiennoprzecinkowe są kluczowe w shaderach, więc ich poziom precyzji (ang. *precision*) ma ogromne znaczenie. 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, zatem, działał: +7. Ostatni i chyba najważniejszy szczegół specyfikacji GLSL: nie ma gwarancji, ż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 graficznych, 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. Przyzwyczaj 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, zatem, działał: ```glsl void main() { @@ -54,7 +54,7 @@ Czas na ćwiczenia! Pamiętaj, że w wypadku błędu kompilacji pokaże się inf * 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: +* Stwórz osobną funkcję, która zwraca dowolny kolor i użyj jej w `main()`. Wskazówka: poniższy kod zwraca kolor czerwony: ```glsl vec4 red(){ @@ -68,4 +68,4 @@ vec4 red(){ vec4 color = vec4(vec3(1.0,0.0,1.0),1.0); ``` -Choć przykład ten nie jest zbyt ekscytujący, ale stanowi ważną podstawę. 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). \ No newline at end of file +Choć przykład ten nie jest zbyt ekscytujący, stanowi ważną podstawę. 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). From 3b6a8509d3c5d01284f728ef4c577297093e516a Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 21:58:35 +0100 Subject: [PATCH 31/47] fix typos and translations in Polish version of chapter 03 --- 03/README-pl.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/03/README-pl.md b/03/README-pl.md index 67e5556..1556adf 100644 --- a/03/README-pl.md +++ b/03/README-pl.md @@ -4,7 +4,7 @@ Do tej pory widzieliśmy jak GPU zarządza wieloma równoległymi wątkami, z kt -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. +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. @@ -18,7 +18,7 @@ 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: +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ą dodawania `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: @@ -29,23 +29,23 @@ 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. +Koniec gadania, czas zobaczyć uniformy w akcji. W poniższym kodzie używamy `u_time` (liczby sekund od uruchomienia shadera) razem z funkcją sinus, aby stworzyć animację przejścia od koloru czerwonego do czarnego.
-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). +Jak widać GLSL skrywa wiele niespodzianek, na przykład w postaci specjalnych, zaimplementowanych w hardwarze, 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). Pobawmy się powyższym kodem: -* Zmniejsz częstotliwość tak bardzo, aby zmiany koloru stały się nie zauważalne. +* Zmniejsz częstotliwość tak bardzo, aby zmiany koloru stały się niezauważ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. +* Wstaw funkcje sinusoidalne o różnych częstotliwościach do pozostałych kanałów (zielonego i niebieskiego), aby uzyskać ciekawe efekty. -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. +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 programowanie GLSL jest często jak wkładanie miniaturowych statków do butelki - jest to trudne, ale też piękne i satysfakcjonujące. @@ -77,13 +77,13 @@ 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)`? +* Co z fragmentami 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. +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. ```glsl -uniform vec3 iResolution; -uniform vec4 iMouse; -uniform float iTime; +uniform vec3 iResolution; // rozdzielczość obszaru widoku (w pikselach) +uniform vec4 iMouse; // współrzędne piksela myszy: xy – bieżąca pozycja, zw – kliknięcie +uniform float iTime; // czas działania shadera (w sekundach) ``` (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) From b2184fc4d567c6e0f21c5c1676a17e91f312c3c7 Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:15:48 +0100 Subject: [PATCH 36/47] fix a typo in glossary/abd --- glossary/abs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/abs/README.md b/glossary/abs/README.md index 90e1068..78eab5f 100644 --- a/glossary/abs/README.md +++ b/glossary/abs/README.md @@ -10,7 +10,7 @@ vec4 abs(vec4 x) ``` ### Parameters -```x``` specify the value of which to return the absolute. +```x``` specifies the value of which to return the absolute. ### Description ```abs()``` returns the absolute value of ```x```. From 7ca3bcde6a5ace7b8a53fd7d2b5595fa783722df Mon Sep 17 00:00:00 2001 From: Kvmilos <98656825+kvmilos@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:16:50 +0100 Subject: [PATCH 37/47] translate glossary/abd to Polish --- glossary/abs/README-pl.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 glossary/abs/README-pl.md diff --git a/glossary/abs/README-pl.md b/glossary/abs/README-pl.md new file mode 100644 index 0000000..34dde30 --- /dev/null +++ b/glossary/abs/README-pl.md @@ -0,0 +1,21 @@ +## Abs +Zwraca wartość bezwzględną z parametru. + +### Deklaracja +```glsl +float abs(float x) +vec2 abs(vec2 x) +vec3 abs(vec3 x) +vec4 abs(vec4 x) +``` + +### Parametry +```x``` określa wartość, z której ma zostać zwrócona wartość bezwzględna. + +### Opis +```abs()``` zwraca wartość bezwzględną z x. + +
+ +### Zobacz także +[sign()](/glossary/?search=sign), [min()](/glossary/?search=min), [max()](/glossary/?search=max), [Rozdział 05: Shaping Functions](../05/) From 8f513976e1799f6a7b3ece6310576886fbbb5ae3 Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Mon, 3 Feb 2025 00:01:25 +0100 Subject: [PATCH 38/47] translate appendix/04 to Polish --- appendix/04/README-pl.md | 448 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 appendix/04/README-pl.md diff --git a/appendix/04/README-pl.md b/appendix/04/README-pl.md new file mode 100644 index 0000000..61c83eb --- /dev/null +++ b/appendix/04/README-pl.md @@ -0,0 +1,448 @@ +## Wprowadzenie dla osób przychodzących z JS +przez [Nicolas Barradeau](http://www.barradeau.com/) + + +Jeśli jesteś programistą JavaScript, prawdopodobnie nieco zaskoczy Cię treść tej książki. +Rzeczywiście, istnieje wiele różnic pomiędzy manipulowaniem wysokopoziomowym kodem JS a zagłębianiem się w świat shaderów. +Jednak w przeciwieństwie do niskopoziomowego języka asemblerowego, GLSL jest czytelny dla człowieka i jestem pewien, że po zrozumieniu jego specyfiki szybko zaczniesz go używać. + +Zakładam, że masz podstawową (choć może płytką) wiedzę o JavaScript, ale także o Canvas API. +Jeśli nie, nie martw się – większość tej sekcji będzie dla Ciebie zrozumiała. + +Nie będę zagłębiać się zbytnio w szczegóły, a niektóre kwestie mogą być _półprawdziwe_; nie oczekuj "wyczerpującego przewodnika", ale raczej + +### WIELKI UŚCISK + +JavaScript świetnie nadaje się do szybkiego prototypowania; wrzucasz garść losowych, nieotypowanych zmiennych i metod, możesz dynamicznie dodawać i usuwać członków klas, odświeżać stronę i sprawdzać, czy wszystko działa, +wprowadzać zmiany, odświeżać stronę, powtarzać – życie jest proste. +Możesz się więc zastanawiać, jaka jest różnica między JavaScriptem a GLSL. +W końcu oba działają w przeglądarce, oba służą do rysowania różnych efektownych rzeczy na ekranie i pod tym względem JS jest łatwiejszy w użyciu. + +Główna różnica polega jednak na tym, że JavaScript jest językiem **interpretowanym**, podczas gdy GLSL jest językiem **kompilowanym**. +**Kompilowany** program jest wykonywany natywnie przez system operacyjny, jest niskopoziomowy i zazwyczaj szybki. +**Interpretowany** program wymaga [wirtualnej maszyny](https://en.wikipedia.org/wiki/Virtual_machine) (VM) do wykonania, jest wysokopoziomowy i zazwyczaj wolniejszy. + + +Gdy przeglądarka (czyli _JavaScriptowa **VM**_) **wykonuje** lub **interpretuje** fragment kodu JS, nie wie, jaka zmienna czym jest i jaka funkcja co robi (z wyjątkiem oczywistych przypadków, takich jak **TypedArrays**). +Dlatego nie może nic zoptymalizować _z góry_, więc potrzebuje trochę czasu, aby przeczytać Twój kod, **wywnioskować** (dedukować na podstawie użycia) typy Twoich zmiennych i metod, +a kiedy to możliwe, przekształci _część_ Twojego kodu w kod asemblerowy, który wykona się znacznie szybciej. + +To powolny, mozolny i niesamowicie skomplikowany proces – jeśli interesują Cię szczegóły, polecam przyjrzeć się działaniu [silnika V8 w Chrome](https://developers.google.com/v8/). +Najgorsze jest to, że każda przeglądarka optymalizuje JS na swój sposób, a cały proces jest _ukryty_ przed użytkownikiem; jesteś bezsilny. + +**Kompilowany** program nie jest interpretowany; system operacyjny go uruchamia, a jeśli program jest poprawny, zostaje wykonany. +To duża zmiana; jeśli zapomnisz o średniku na końcu linii, Twój kod jest niepoprawny i nie skompiluje się: Twój kod w ogóle nie przekształci się w program. + +To surowe, ale tak właśnie działa **shader**: _skompilowany program wykonywany na GPU_. +Nie bój się! **Kompilator**, czyli część programu, która dba o to, aby Twój kod był poprawny, stanie się Twoim najlepszym przyjacielem. +Przykłady z tej książki oraz [edytor towarzyszący](http://editor.thebookofshaders.com/) są bardzo przyjazne użytkownikowi. +Powiedzą Ci, gdzie i dlaczego Twój program nie skompilował się, a następnie będziesz musiał wprowadzić poprawki – i za każdym razem, gdy shader będzie gotowy do kompilacji, zostanie on natychmiast wyświetlony. +To świetny sposób na naukę, ponieważ jest bardzo wizualny i tak naprawdę niczego nie możesz zepsuć. + +Ostatnia uwaga: **shader** składa się z dwóch programów, **vertex shader** i **fragment shader**. +W skrócie, **vertex shader**, pierwszy program, otrzymuje geometrię jako dane wejściowe i przekształca ją w serię **pikseli** (lub *fragmentów*), które następnie przekazuje do +**fragment shader**, drugiego programu, który decyduje, jaki kolor nadać pikselom. +Ta książka koncentruje się głównie na tym drugim – we wszystkich przykładach geometria to prosty czworobok pokrywający cały ekran. + +Więc! Gotowy? + +No to ruszamy! + +### Silne typowanie +![pierwszy wynik wyszukiwania dla 'strong type' w Google Images, 20.05.2016](vector.jpg) + +Dla osób przychodzących z JS lub innego języka bez typów, **typowanie** zmiennych jest obcym konceptem, co sprawia, że **typowanie** stanowi najtrudniejszy krok w kierunku nauki GLSL. +**Typowanie**, jak sama nazwa wskazuje, oznacza, że musisz przypisać **typ** każdej zmiennej (oraz funkcjom, oczywiście). +To zasadniczo oznacza, że słowo **`var`** przestaje istnieć. +Polityka myślenia GLSL wymazała je z powszechnego języka i nie jesteś w stanie go używać, ponieważ... po prostu nie istnieje. + +Zamiast używać magicznego słowa **`var`**, będziesz musiał _jawnie określić typ każdej używanej zmiennej_, dzięki czemu kompilator będzie widział tylko obiekty i prymitywy, które wie, jak efektywnie obsługiwać. +Minusem braku możliwości użycia słowa **`var`** i konieczności _jawnego określania wszystkiego_ jest to, że musisz znać typ wszystkich zmiennych i dobrze je rozumieć. +Spokojnie – jest ich niewiele, a do tego są dość proste (GLSL nie jest frameworkiem Java). + +Może to brzmieć strasznie, ale ogólnie nie różni się to bardzo od tego, co robisz w JavaScript; jeśli zmienna jest typu `boolean`, oczekujesz, że będzie przechowywać `true` lub `false` i nic więcej. +Jeśli zmienna jest zadeklarowana jako `var uid = XXX;`, prawdopodobnie przechowasz w niej wartość całkowitą, a `var y = YYY;` _może_ odnosić się do wartości zmiennoprzecinkowej. +Co więcej, dzięki **silnemu typowaniu** nie będziesz tracił czasu na zastanawianie się, czy `X == Y` (albo czy `typeof X == typeof Y`? ... albo `typeof X !== null && Y...`... w każdym razie) – po prostu będziesz tego wiedział, a jeśli nie, kompilator Cię o tym poinformuje. + +Oto **typy skalarne** (**skalar** określa ilość), których możesz używać w GLSL: `bool` (Boolean), `int` (liczba całkowita), `float` (liczba zmiennoprzecinkowa). +Istnieją też inne typy, ale nie ma co się przejmować – poniższy fragment pokazuje, jak deklarować **zmienne (`vars`)** (tak, użyłem zakazanego słowa) w GLSL: +```glsl +// wartość typu Boolean: +JS: var b = true; GLSL: bool b = true; + +// wartość typu Integer +JS: var i = 1; GLSL: int i = 1; + +// wartość typu Float (liczba) +JS: var f = 3.14159; GLSL: float f = 3.14159; +``` +Nie jest to trudne, prawda? Jak wspomniałem, ułatwia to kodowanie, ponieważ nie tracisz czasu na sprawdzanie typu danej zmiennej. +W razie wątpliwości pamiętaj, że robisz to po to, aby Twój program działał o wiele szybciej niż w JS. + +#### void +Istnieje typ `void`, który w przybliżeniu odpowiada `null`; jest on używany jako typ zwracany przez funkcję, która nic nie zwraca. +Nie możesz przypisać go do zmiennej. + +#### boolean +Jak wiesz, wartości logiczne (Boolean) są najczęściej używane w testach warunkowych, np. `if( myBoolean == true ){}else{}`. +Choć rozgałęzianie warunkowe jest możliwe na CPU, [równoległa natura](http://thebookofshaders/01/) GLSL czyni to mniej sensownym. +Używanie instrukcji warunkowych jest często wręcz zniechęcane – książka przedstawia kilka alternatywnych technik rozwiązania tego problemu. + +#### rzutowanie typów +Jak powiedział [Boromir](https://pl.wikipedia.org/wiki/Boromir): "Nie łączy się po prostu otypowanych prymitywów". W przeciwieństwie do JavaScript, GLSL nie pozwala na wykonywanie operacji pomiędzy zmiennymi o różnych typach. + +This for instance: +```glsl +int i = 2; +float f = 3.14159; + +// próba pomnożenia liczby całkowitej przez wartość zmiennoprzecinkową: +float r = i * f; +``` +nie zadziała, ponieważ próbujesz połączyć **_kota_** z **_żyrafą_**. +Rozwiązaniem jest użycie rzutowania typów; to _sprawi, że kompilator uwierzy_, że *`i`* jest typu `float`, nie zmieniając faktycznie typu *`i`*. +```glsl +// rzutowanie typu zmiennej całkowitej 'i' na float: +float r = float( i ) * f; +``` + +Co jest ściśle równoważne przebraniu **_kota_** w **_żyrafi_ strój** i zadziała zgodnie z oczekiwaniami (`r` będzie wynikiem `i` x `f`). + +Można **rzutować** dowolny z wymienionych typów na inny; zauważ, że rzutowanie `float` na `int` działa jak `Math.floor()`, ponieważ usuwa część dziesiętną. +Rzutowanie `float` lub `int` na `bool` zwróci `true`, jeśli wartość zmiennej nie wynosi zero. + +#### konstruktor +**Typy** zmiennych są również swoimi własnymi **konstruktorami klas**; w rzeczywistości zmienna typu `float` może być traktowana jako _`instancja`_ klasy _`Float`_. + +Następujące deklaracje są równie poprawne: + +```glsl +int i = 1; +int i = int( 1 ); +int i = int( 1.9995 ); +int i = int( true ); +``` +Może się to nie wydawać znaczące dla typów `skalarnych`, ale nie różni się to zbytnio od **rzutowania** – nabierze sensu, gdy przejdziemy do sekcji dotyczącej *przeciążania*. + +Ok, więc te trzy to `typy prymitywne`, rzeczy, bez których nie możesz żyć – ale oczywiście GLSL ma do zaoferowania więcej. + +### Wektory +![pierwszy wynik wyszukiwania dla 'vector villain' w Google Images, 05.20.2016](vector.jpg) + +W JavaScript, podobnie jak w GLSL, potrzebujesz bardziej zaawansowanych sposobów obsługi danych, dlatego przydają się **wektory**. +Przypuszczam, że już napisałeś klasę `Point` w JavaScript, która przechowuje razem wartość `x` i `y`, kod wyglądałby mniej więcej tak: +```glsl +// definicja 'klasy': +var Point = function( x, y ){ + this.x = x || 0; + this.y = y || 0; +} + +// i instancjonowałoby się ją tak: +var p = new Point( 100,100 ); +``` + +Jak właśnie widzieliśmy, to jest TAK niepoprawne na TYLU poziomach! Po pierwsze, użycie słowa kluczowego **`var`**, potem okropne **`this`**, a następnie znowu **nieotypowane** wartości `x` i `y`... +Nie, to nie zadziała w świecie shaderów. + +Zamiast tego GLSL udostępnia wbudowane struktury danych, które służą do przechowywania danych razem, mianowicie: + + * `bvec2`: 2-wymiarowy wektor Boolean, `bvec3`: 3-wymiarowy wektor Boolean, `bvec4`: 4-wymiarowy wektor Boolean + * `ivec2`: 2-wymiarowy wektor Integer, `ivec3`: 3-wymiarowy wektor Integer, `ivec4`: 4-wymiarowy wektor Integer + * `vec2`: 2-wymiarowy wektor Float, `vec3`: 3-wymiarowy wektor Float, `vec4`: 4-wymiarowy wektor Float + +Natychmiast zauważyłeś, że dla każdego typu prymitywnego istnieje odpowiedni **wektor**, spryciarzu. +Z tego, co właśnie widzieliśmy, można wywnioskować, że `bvec2` przechowa dwie wartości typu `bool`, a `vec4` cztery wartości typu `float`. + +Inną rzeczą wprowadzoną przez wektory jest liczba **wymiarów**; nie oznacza to, że do renderowania grafiki 2D używasz 2-wymiarowego wektora, a do 3D – 3-wymiarowego. +Co by wtedy reprezentował 4-wymiarowy wektor? (właściwie nazywa się tesseraktem lub hiperkostką) + +Nie, **wymiary** oznaczają liczbę oraz typ **składowych** lub **zmiennych** przechowywanych w **wektorze**: +```glsl +// stwórzmy 2-wymiarowy wektor Boolean +bvec2 b2 = bvec2 ( true, false ); + +// stwórzmy 3-wymiarowy wektor Integer +ivec3 i3 = ivec3( 0,0,1 ); + +// stwórzmy 4-wymiarowy wektor Float +vec4 v4 = vec4( 0.0, 1.0, 2.0, 1. ); +``` +`b2` przechowuje dwie różne wartości logiczne, `i3` przechowuje trzy różne wartości całkowite, a `v4` cztery różne wartości zmiennoprzecinkowe. + +Ale jak odczytać te wartości? +w przypadku `skalarów` odpowiedź jest oczywista – przy `float f = 1.2`; zmienna `f` przechowuje wartość `1.2`. +W przypadku **wektorów** jest to nieco inne i całkiem piękne. + +#### akcesory +Istnieją różne sposoby dostępu do wartości +```glsl +// stwórzmy 4-wymiarowy wektor Float +vec4 v4 = vec4( 0.0, 1.0, 2.0, 3.0 ); +``` +Aby odczytać te 4 wartości, możesz zrobić następująco: +```glsl +float x = v4.x; // x = 0.0 +float y = v4.y; // y = 1.0 +float z = v4.z; // z = 2.0 +float w = v4.w; // w = 3.0 +``` +bułka z masłem; ale poniższe sposoby są równie poprawne w dostępie do Twoich danych: +```glsl +float x = v4.x = v4.r = v4.s = v4[0]; // x = 0.0 +float y = v4.y = v4.g = v4.t = v4[1]; // y = 1.0 +float z = v4.z = v4.b = v4.p = v4[2]; // z = 2.0 +float w = v4.w = v4.a = v4.q = v4[3]; // w = 3.0 +``` + +I spryciarzu, już zauważyłeś trzy rzeczy: + * `X`, `Y`, `Z` i `W` są używane w programach 3D do reprezentacji wektorów 3D + * `R`, `G`, `B` i `A` służą do kodowania kolorów oraz kanału alfa + * `[0]`, `[1]`, `[2]` i `[3]` oznaczają, że mamy dostęp do wartości w sposób losowy (tablica indeksowana) + +W zależności od tego, czy manipulujesz współrzędnymi 2D czy 3D, kolorem z lub bez kanału alfa, czy też po prostu różnymi zmiennymi, możesz wybrać najbardziej odpowiedni typ i rozmiar **wektora**. +Zazwyczaj współrzędne 2D i wektory (w sensie geometrycznym) przechowywane są jako `vec2`, `vec3` lub `vec4`, kolory jako `vec3` lub `vec4` (jeśli potrzebujesz kanału alfa), ale nie ma ograniczeń co do sposobu użycia wektorów. +Na przykład, jeśli chcesz przechować tylko jedną wartość logiczną w `bvec4`, jest to możliwe, ale to marnotrawstwo pamięci. + +**uwaga**: w shaderze wartości kolorów (`R`, `G`, `B` i `A`) są normalizowane, mieszczą się w przedziale od 0 do 1, a nie od 0 do 0xFF, dlatego lepiej użyć Float `vec4` niż Integer `ivec4` do ich przechowywania. + +Już nieźle, ale to nie wszystko! + +#### swizzle + +Można zwrócić więcej niż jedną wartość jednocześnie; powiedzmy, że potrzebujesz tylko składowych `X` i `Y` z `vec4`, w JavaScript musiałbyś napisać coś takiego: +```glsl +var needles = [0, 1]; // pozycja 'x' i 'y' w naszej strukturze danych +var a = [ 0,1,2,3 ]; // nasza struktura danych 'vec4' +var b = a.filter( function( val, i, array ) { +return needles.indexOf( array.indexOf( val ) ) != -1; +}); +// b = [ 0, 1 ] + +// albo bardziej bezpośrednio: +var needles = [0, 1]; +var a = [ 0,1,2,3 ]; // our 'vec4' data structure +var b = [ a[ needles[ 0 ] ], a[ needles[ 1 ] ] ]; // b = [ 0, 1 ] +``` +Brzydko. W GLSL możesz je uzyskać w ten sposób: +```glsl +// stwrórz 4-wymiarowy wektor Float +vec4 v4 = vec4( 0.0, 1.0, 2.0, 3.0 ); + +// i odczytaj tylko 'x' i 'y' +vec2 xy = v4.xy; // xy = vec2( 0.0, 1.0 ); +``` +Co tu się stało?! Gdy **skonkatenujesz akcesory**, GLSL elegancko zwraca podzbiór wartości, o które prosiłeś, w najbardziej odpowiednim formacie **wektora**. +Rzeczywiście, wektor to struktura danych o **losowym dostępie**, podobna do tablicy w JavaScript. +Tak więc, nie tylko możesz pobrać podzbiór swoich danych, ale także określić **kolejność**, w jakiej mają być zwrócone – może to odwrócić kolejność składowych wektora: +```glsl +// stwórz 4-wymiarowy wektor: R,G,B,A +vec4 color = vec4( 0.2, 0.8, 0.0, 1.0 ); + +// i odczytaj go w kolejności: A,B,G,R +vec4 backwards = color.abgr; // backwards = vec4( 1.0, 0.0, 0.8, 0.2 ); +``` +I oczywiście, możesz zapytać o tę samą składową wielokrotnie: +```glsl +// stwórz 4-wymiarowy wektor: R,G,B,A +vec4 color = vec4( 0.2, 0.8, 0.0, 1.0 ); + +// i odczytaj GAG (Green, Alpha, Green) vec3 z kanałów G i A +vec3 GAG = color.gag; // GAG = vec4( 0.8, 1.0, 0.8 ); +``` + +Jest to niezwykle przydatne, aby łączyć części wektorów, wyodrębniać tylko kanały rgb z koloru RGBA itp. + + +#### przeciążaj wszystko! + +W sekcji o typach wspomniałem o **konstruktorze** i tu mamy kolejną świetną cechę GLSL – **przeciążanie**. +Dla tych, którzy nie wiedzą, **przeciążanie** operatora lub funkcji oznacza mniej więcej: _"zmianę zachowania danego operatora lub funkcji w zależności od operandów/argumentów"_. +Przeciążanie nie jest dozwolone w JavaScript, więc na początku może to wydawać się dziwne, ale jestem pewien, że gdy się do tego przyzwyczaisz, zastanowisz się, dlaczego nie zostało to zaimplementowane w JS (krótka odpowiedź, *typowanie*). + +Najprostszy przykład przeciążania operatorów wygląda następująco: + +```glsl +vec2 a = vec2( 1.0, 1.0 ); +vec2 b = vec2( 1.0, 1.0 ); +// przeciążone dodawanie +vec2 c = a + b; // c = vec2( 2.0, 2.0 ); +``` +CO? Czyli można dodawać rzeczy, które nie są liczbami?! + +Tak, dokładnie. Oczywiście dotyczy to wszystkich operatorów (`+`, `-`, `*` oraz `/`), ale to dopiero początek. +Rozważ poniższy fragment: +```glsl +vec2 a = vec2( 0.0, 0.0 ); +vec2 b = vec2( 1.0, 1.0 ); +// przeciążony konstruktor +vec4 c = vec4( a , b ); // c = vec4( 0.0, 0.0, 1.0, 1.0 ); +``` +Zbudowaliśmy `vec4` z dwóch `vec2`, przy czym nowy `vec4` użył `a.x` i `a.y` jako składowych `X` i `Y` wektora `c`. +Następnie wziął `b.x` i `b.y` i użył ich jako składowych `Z` i `W`. + +Tak właśnie działa przeciążony konstruktor vec4, który akceptuje różne argumenty. +Oznacza to, że wiele wersji tej samej funkcji o różnych sygnaturach może współistnieć w jednym programie, na przykład następujące deklaracje są wszystkie poprawne: +```glsl +vec4 a = vec4(1.0, 1.0, 1.0, 1.0); +vec4 a = vec4(1.0);// x, y, z, w wszystkie są równe 1.0 +vec4 a = vec4( v2, float, v4 );// vec4( v2.x, v2.y, float, v4.x ); +vec4 a = vec4( v3, float );// vec4( v3.x, v3.y, v3.z, float ); +etc. +``` +Jedyne, na co musisz zwrócić uwagę, to dostarczenie wystarczającej liczby argumentów, aby wypełnić Twój **wektor**. + +Ostatnia rzecz, możesz przeciążać wbudowane funkcje w swoim programie, aby przyjmowały argumenty, dla których nie zostały zaprojektowane (choć nie powinno się to zdarzać zbyt często). + +#### inne typy +Wektory są fajne, to sedno Twojego shadera. +Istnieją inne prymitywy, takie jak macierze (Matrices) i próbki tekstur (Texture samplers), które zostaną omówione później w książce. + +Możemy także używać tablic (Arrays). Oczywiście muszą być typowane, a przy tym występują pewne pułapki: + * mają ustalony rozmiar + * nie możesz używać metod push(), pop(), splice() itp., a właściwość ```length``` nie istnieje + * nie możesz od razu zainicjalizować ich wartościami + * musisz przypisywać wartości pojedynczo + +to nie zadziała: +```glsl +int values[3] = [0,0,0]; +``` +ale to zadziała: +```glsl +int values[3]; +values[0] = 0; +values[1] = 0; +values[2] = 0; +``` +To jest w porządku, gdy znasz swoje dane lub masz małe tablice wartości. +Jeśli chcesz bardziej ekspresyjnego sposobu deklaracji zmiennej, +możesz użyć również typu ```struct```. Są one jak _obiekty_ bez metod; +pozwalają przechowywać i uzyskiwać dostęp do wielu zmiennych w jednym obiekcie. +```glsl +struct ColorStruct { + vec3 color0; + vec3 color1; + vec3 color2; +} +``` +następnie możesz ustawiać i odczytywać wartości _kolorów_ w następujący sposób: +```glsl +// zainicjuj struct z jakimiś wartościami +ColorStruct sandy = ColorStruct( vec3(0.92,0.83,0.60), + vec3(1.,0.94,0.69), + vec3(0.95,0.86,0.69) ); + +// odczytaj wartość ze struct +sandy.color0 // vec3(0.92,0.83,0.60) +``` +To lukier składniowy, ale może pomóc w pisaniu bardziej przejrzystego kodu, przynajmniej takiego, do którego jesteś przyzwyczajony. + +#### instrukcje i warunki + +Struktury danych są przydatne, ale może będziesz musiał iterować lub wykonywać testy warunkowe w pewnym momencie. +Na szczęście składnia jest bardzo zbliżona do tej w JavaScript. +Warunek wygląda tak: +```glsl +if( warunek ){ + // prawda +}else{ + // fałsz +} +``` +Pętla for zazwyczaj wygląda tak: +```glsl +const int count = 10; +for( int i = 0; i <= count; i++){ + // zrób coś +} +``` +lub z iteratorem typu float: +```glsl +const float count = 10.; +for( float i = 0.0; i <= count; i+= 1.0 ){ + // zrób coś +} +``` +Zauważ, że `count` musi być zdefiniowane jako stała. +Oznacza to, że poprzedzasz typ kwalifikatorem `const`, o czym opowiem za chwilę. + +Mamy również instrukcje ```break``` i ```continue```: +```glsl +const float count = 10.; +for( float i = 0.0; i <= count; i+= 1.0 ){ + if( i < 5. )continue; + if( i >= 8. )break; +} +``` +Miej na uwadze, że na niektórych urządzeniach instrukcja ```break``` może nie działać zgodnie z oczekiwaniami i pętla nie przerwie iteracji wcześniej. + +Ogólnie rzecz biorąc, powinieneś utrzymywać liczbę iteracji na możliwie najniższym poziomie i unikać pętli oraz instrukcji warunkowych tak często, jak to możliwe. + + +#### kwalifikatory + +Oprócz typów zmiennych, GLSL używa **kwalifikatorów**. +Krótko mówiąc, kwalifikatory pomagają kompilatorowi zrozumieć, jaka jest rola danej zmiennej. +Na przykład, niektóre dane mogą być dostarczane tylko przez CPU do GPU, nazywamy je **atrybutami** i **uniformami**. +**Atrybuty** są zarezerwowane dla vertex shaderów, a **uniformy** mogą być używane zarówno w vertex, jak i fragment shaderach. +Jest też kwalifikator ```varying```, służący do przekazywania zmiennych między vertex a fragment shaderem. + +Nie będę zagłębiać się tutaj w szczegóły, ponieważ skupiamy się głównie na **fragment shaderze**, ale później w książce zobaczysz coś takiego: +```glsl +uniform vec2 u_resolution; +``` +Widzisz, co zrobiliśmy? Dodaliśmy kwalifikator ```uniform``` przed typem zmiennej. +Oznacza to, że rozdzielczość kanwy, nad którą pracujemy, jest przekazywana do shadera z CPU. +Szerokość kanwy zapisana jest w komponencie x, a wysokość w komponencie y 2-wymiarowego wektora. + +Gdy kompilator napotka zmienną poprzedzoną tym kwalifikatorem, upewni się, że nie możesz zmieniać tych wartości w czasie wykonywania programu. + +To samo dotyczy naszej zmiennej ```count```, która była limitem w pętli ```for```: +```glsl +const float count = 10.; +for( ... ) +``` +Kiedy używamy kwalifikatora ```const```, kompilator upewni się, że wartość zmiennej zostanie ustawiona tylko raz, w przeciwnym razie nie jest to stała. + +Istnieją trzy dodatkowe kwalifikatory używane w sygnaturach funkcji: in, out oraz inout. +W JavaScript, gdy przekazujesz prymitywne argumenty do funkcji, ich wartość jest tylko do odczytu, a jeśli zmienisz ich wartość wewnątrz funkcji, +zmiany nie mają wpływu na zmienną poza funkcją. +```glsl +function banana( a ){ + a += 1; +} +var value = 0; +banana( value ); +console.log( value );// > 0 ; zmiany nie są brane pod uwagę poza funkcją +``` + +With arguments qualifiers, you can specify the behaviour of the arguments: + * ```in``` will be read-only ( default ) + * ```out``` write-only: you can't read the value of this argument but you can set it + * ```inout``` read-write: you can both get and set the value of this variable + +Przepisanie funkcji banana do GLSL wyglądałoby tak: +```glsl +void banana( inout float a ){ + a += 1.; +} +float A = 0.; +banana( A ); // teraz A = 1.; +``` +To bardzo różni się od JS i jest również potężne, ale nie musisz jawnie określać kwalifikatorów w sygnaturze (domyślnie są one tylko do odczytu). + +#### przestrzeń i współrzędne + +Ostatnia uwaga: w DOM oraz w 2D Canvas jesteśmy przyzwyczajeni, że oś Y wskazuje w dół. +Ma to sens w kontekście DOM, ponieważ odpowiada sposobowi, w jaki rozwija się strona internetowa – pasek nawigacyjny na górze, zawartość rozciągająca się ku dołowi. +W kanwie WebGL oś Y jest odwrócona: Y wskazuje w górę. + +Oznacza to, że punkt początkowy, czyli (0,0), znajduje się w lewym dolnym rogu kontekstu WebGL, a nie w lewym górnym, jak ma to miejsce w 2D Canvas. +Współrzędne tekstur podlegają tej zasadzie, co na początku może być nieintuicyjne. + +## I to wszystko! +Oczywiście moglibyśmy zagłębić się w różne koncepcje, ale jak wspomniano wcześniej, chodziło o to, aby dać WIELKI UŚCISK nowoprzybyłym. +To sporo materiału do przyswojenia, ale z cierpliwością i praktyką stanie się to coraz bardziej naturalne. + +Mam nadzieję, że część z tego okaże się przydatna. A teraz, co powiesz na rozpoczęcie swojej podróży przez tę książkę? From 5317d2a32b9d0ec8d5e9cbe0e00b64863f7f6eae Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Mon, 3 Feb 2025 00:15:03 +0100 Subject: [PATCH 39/47] fixed typos --- glossary/acos/README.md | 2 +- glossary/asin/README.md | 2 +- glossary/atan/README.md | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/glossary/acos/README.md b/glossary/acos/README.md index 3128024..c1f6fc4 100644 --- a/glossary/acos/README.md +++ b/glossary/acos/README.md @@ -10,7 +10,7 @@ vec4 acos(vec4 x) ``` ### Parameters -```x``` specify the value whose arccosine to return. +```x``` specifies the value whose arccosine to return. ### Description ```acos()``` returns the angle whose trigonometric cosine is ```x```. diff --git a/glossary/asin/README.md b/glossary/asin/README.md index 00f064d..6a65b76 100644 --- a/glossary/asin/README.md +++ b/glossary/asin/README.md @@ -10,7 +10,7 @@ vec4 asin(vec4 x) ``` ### Parameters -```x``` specify the value whose arcsine to return. +```x``` specifies the value whose arcsine to return. ### Description ```asin()``` returns the angle whose trigonometric sine is ```x```. diff --git a/glossary/atan/README.md b/glossary/atan/README.md index 7d53bd0..d580224 100644 --- a/glossary/atan/README.md +++ b/glossary/atan/README.md @@ -15,14 +15,14 @@ vec4 atan(vec4 y_over_x) ``` ### Parameters -```y``` specify the numerator of the fraction whose arctangent to return. +```y``` specifies the numerator of the fraction whose arctangent to return. -```x``` specify the denominator of the fraction whose arctangent to return. +```x``` specifies the denominator of the fraction whose arctangent to return. -```y_over_x``` specify the fraction whose arctangent to return. +```y_over_x``` specifies the fraction whose arctangent to return. ### Description -```atan()``` returns the angle whose trigonometric arctangent is ```y,x``` or ```y_over_x```, depending on which overload is invoked. In the first overload, the signs of ```y``` and ```x``` are used to determine the quadrant that the angle lies in. The values returned by atan in this case are in the range -PI and PI. Results are undefined if ```x``` is zero. +```atan()``` returns the angle whose trigonometric arctangent is ```y,x``` or ```y_over_x```, depending on which overload is invoked. In the first overload, the signs of ```y``` and ```x``` are used to determine the quadrant that the angle lies in. The values returned by ```atan``` in this case are in the range -PI and PI. Results are undefined if ```x``` is zero. For the second overload, ```atan()``` returns the angle whose tangent is ```y_over_x```. Values returned in this case are in the range -PI to PI. From 9421fe12883d9014b33230ed23c26d5a518458ee Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Mon, 3 Feb 2025 00:15:12 +0100 Subject: [PATCH 40/47] added P:olish translations --- examples/README-pl.md | 5 +++++ glossary/acos/README-pl.md | 21 +++++++++++++++++++++ glossary/all/README-pl.md | 29 +++++++++++++++++++++++++++++ glossary/any/README-pl.md | 29 +++++++++++++++++++++++++++++ glossary/asin/README-pl.md | 21 +++++++++++++++++++++ glossary/atan/README-pl.md | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 examples/README-pl.md create mode 100644 glossary/acos/README-pl.md create mode 100644 glossary/all/README-pl.md create mode 100644 glossary/any/README-pl.md create mode 100644 glossary/asin/README-pl.md create mode 100644 glossary/atan/README-pl.md diff --git a/examples/README-pl.md b/examples/README-pl.md new file mode 100644 index 0000000..79484d7 --- /dev/null +++ b/examples/README-pl.md @@ -0,0 +1,5 @@ +# Galeria przykładów + + + +To jest zbiór przykładów wyciągniętych z rozdziałów tej książki, wraz z udostępnionymi shaderami hojnie przekazanymi przez innych czytelników korzystających z [edytora online](http://editor.thebookofshaders.com/). Zachęcamy do eksplorowania i modyfikowania ich krok po kroku. Gdy stworzysz coś, z czego będziesz dumny, kliknij "Export", a następnie skopiuj "URL do kodu...". Prześlij go do [@bookofshaders](https://x.com/bookofshaders) lub [@kyndinfo](https://x.com/kyndinfo). Nie możemy się doczekać, aby to zobaczyć! diff --git a/glossary/acos/README-pl.md b/glossary/acos/README-pl.md new file mode 100644 index 0000000..21dfe0b --- /dev/null +++ b/glossary/acos/README-pl.md @@ -0,0 +1,21 @@ +## Acos +Zwraca arcus cosinus podanego argumentu + +### Deklaracja +```glsl +float acos(float x) +vec2 acos(vec2 x) +vec3 acos(vec3 x) +vec4 acos(vec4 x) +``` + +### Parametry +```x``` wartość, której arcus cosinus ma zostać zwrócony. + +### Opis +```acos()``` zwraca kąt, którego cosinus jest równy ```x```. + +
+ +### Zobacz też +[cos()](/glossary/?search=cos), [sin()](/glossary/?search=sin), [asin()](/glossary/?search=asin), [tan()](/glossary/?search=tan), [atan()](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/) \ No newline at end of file diff --git a/glossary/all/README-pl.md b/glossary/all/README-pl.md new file mode 100644 index 0000000..e66d4d6 --- /dev/null +++ b/glossary/all/README-pl.md @@ -0,0 +1,29 @@ +## All +Sprawdza, czy wszystkie elementy wektora logicznego są prawdziwe + +### Deklaracja +```glsl +bool all(bvec2 x) +bool all(bvec3 x) +bool all(bvec4 x) +``` + +### Parametry +```x``` określa wektor, który ma zostać sprawdzony pod kątem prawdy. + +### Opis +```all()``` zwraca ```true```, jeśli wszystkie elementy ```x``` są ```true``` i ```false``` w przeciwnym razie. Jest to funkcjonalnie równoważne: + +```glsl +bool all(bvec x){ // bvec może być bvec2, bvec3 lub bvec4 + bool result = true; + int i; + for (i = 0; i < x.length(); ++i) + { + result &= x[i]; + } + return result; +} +``` +### Zobacz też +[any()](/glossary/?search=any), [not()](/glossary/?search=not) \ No newline at end of file diff --git a/glossary/any/README-pl.md b/glossary/any/README-pl.md new file mode 100644 index 0000000..4a49ded --- /dev/null +++ b/glossary/any/README-pl.md @@ -0,0 +1,29 @@ +## Any +Sprawdza, czy choć jeden element wektora logicznego jest prawdziwy + +### Deklaracja +```glsl +bool all(bvec2 x) +bool all(bvec3 x) +bool all(bvec4 x) +``` + +### Parametry +```x``` określa wektor, który ma zostać sprawdzony pod kątem prawdy. + +### Opis +```all()``` zwraca ```true```, jeśli którykolwiek element ```x``` jest ```true``` i ```false``` w przeciwnym razie. Jest to funkcjonalnie równoważne: + +```glsl +bool any(bvec x) { // bvec może być bvec2, bvec3 lub bvec4 + bool result = false; + int i; + for (i = 0; i < x.length(); ++i) { + result |= x[i]; + } + return result; +} +``` + +### Zobacz też +[any()](/glossary/?search=any), [not()](/glossary/?search=not) \ No newline at end of file diff --git a/glossary/asin/README-pl.md b/glossary/asin/README-pl.md new file mode 100644 index 0000000..952b075 --- /dev/null +++ b/glossary/asin/README-pl.md @@ -0,0 +1,21 @@ +## Asin +Zwraca arcsin parametru + +### Deklaracja +```glsl +float asin(float x) +vec2 asin(vec2 x) +vec3 asin(vec3 x) +vec4 asin(vec4 x) +``` + +### Parametry +```x``` określa wartość, której arcsin ma zostać zwrócony. + +### Opis +```asin()``` zwraca kąt, którego sinus trygonometryczny to ```x```. + +
+ +### Zobacz też +[cos](/glossary/?search=cos), [sin](/glossary/?search=sin), [acos](/glossary/?search=acos), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/) \ No newline at end of file diff --git a/glossary/atan/README-pl.md b/glossary/atan/README-pl.md new file mode 100644 index 0000000..e568c04 --- /dev/null +++ b/glossary/atan/README-pl.md @@ -0,0 +1,32 @@ +## Atan +Zwraca arcus tangens parametrów + +### Deklaracja +```glsl +float atan(float y, float x) +vec2 atan(vec2 y, vec2 x) +vec3 atan(vec3 y, vec3 x) +vec4 atan(vec4 y, vec4 x) + +float atan(float y_over_x) +vec2 atan(vec2 y_over_x) +vec3 atan(vec3 y_over_x) +vec4 atan(vec4 y_over_x) +``` + +### Parametry +```y``` określa licznik ułamka, którego arcus tangens ma zostać zwrócony. + +```x``` określa mianownik ułamka, którego arcus tangens ma zostać zwrócony. + +```y_over_x``` określa ułamek, którego arcus tangens ma zostać zwrócony. + +### Opis +```atan()``` zwraca kąt, którego trygonometryczny arcus tangens jest równy ```y,x``` lub ```y_over_x```, w zależności od tego, który przeciążenie jest wywoływane. W pierwszym przeciążeniu znaki ```y``` i ```x``` są używane do określenia ćwiartki, w której znajduje się kąt. Wartości zwracane przez ```atan``` w tym przypadku mieszczą się w zakresie -PI i PI. Wyniki są niezdefiniowane, jeśli ```x``` wynosi zero. + +Dla drugiego przeciążenia, ```atan()``` zwraca kąt, którego tangens wynosi ```y_over_x```. Wartości zwracane w tym przypadku mieszczą się w zakresie -PI do PI. + +### Zobacz też +[cos](/glossary/?search=cos), [acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [atan](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/), [Rozdział 06: Kolory](/06/) +[]: # (end) +[]: # (end) \ No newline at end of file From 492438da4236c8f4ac56724cdde6f17fb32dcb6b Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Thu, 6 Feb 2025 00:44:27 +0100 Subject: [PATCH 41/47] added translations to Polish --- glossary/abs/README-pl.md | 4 ++-- glossary/acos/README-pl.md | 4 ++-- glossary/all/README-pl.md | 4 ++-- glossary/any/README-pl.md | 4 ++-- glossary/asin/README-pl.md | 4 ++-- glossary/atan/README-pl.md | 4 ++-- glossary/attribute/README-pl.md | 15 +++++++++++++++ glossary/bool/README-pl.md | 15 +++++++++++++++ glossary/bvec2/README-pl.md | 21 +++++++++++++++++++++ glossary/bvec3/README-pl.md | 25 +++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 glossary/attribute/README-pl.md create mode 100644 glossary/bool/README-pl.md create mode 100644 glossary/bvec2/README-pl.md create mode 100644 glossary/bvec3/README-pl.md diff --git a/glossary/abs/README-pl.md b/glossary/abs/README-pl.md index 34dde30..ffcd279 100644 --- a/glossary/abs/README-pl.md +++ b/glossary/abs/README-pl.md @@ -1,4 +1,4 @@ -## Abs +## abs Zwraca wartość bezwzględną z parametru. ### Deklaracja @@ -18,4 +18,4 @@ vec4 abs(vec4 x)
### Zobacz także -[sign()](/glossary/?search=sign), [min()](/glossary/?search=min), [max()](/glossary/?search=max), [Rozdział 05: Shaping Functions](../05/) +[sign()](/glossary/?lan=pl&search=sign), [min()](/glossary/?lan=pl&search=min), [max()](/glossary/?lan=pl&search=max), [Rozdział 05: Shaping Functions](../05/?lan=pl) diff --git a/glossary/acos/README-pl.md b/glossary/acos/README-pl.md index 21dfe0b..61b513b 100644 --- a/glossary/acos/README-pl.md +++ b/glossary/acos/README-pl.md @@ -1,4 +1,4 @@ -## Acos +## acos Zwraca arcus cosinus podanego argumentu ### Deklaracja @@ -18,4 +18,4 @@ vec4 acos(vec4 x)
### Zobacz też -[cos()](/glossary/?search=cos), [sin()](/glossary/?search=sin), [asin()](/glossary/?search=asin), [tan()](/glossary/?search=tan), [atan()](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/) \ No newline at end of file +[cos()](/glossary/?lan=pl&search=cos), [sin()](/glossary/?lan=pl&search=sin), [asin()](/glossary/?lan=pl&search=asin), [tan()](/glossary/?lan=pl&search=tan), [atan()](/glossary/?lan=pl&search=atan), [Rozdział 05: Shaping Functions](/05/?lan=pl) \ No newline at end of file diff --git a/glossary/all/README-pl.md b/glossary/all/README-pl.md index e66d4d6..34b57c3 100644 --- a/glossary/all/README-pl.md +++ b/glossary/all/README-pl.md @@ -1,4 +1,4 @@ -## All +## all Sprawdza, czy wszystkie elementy wektora logicznego są prawdziwe ### Deklaracja @@ -26,4 +26,4 @@ bool all(bvec x){ // bvec może być bvec2, bvec3 lub bvec4 } ``` ### Zobacz też -[any()](/glossary/?search=any), [not()](/glossary/?search=not) \ No newline at end of file +[any()](/glossary/?lan=pl&search=any), [not()](/glossary/?lan=pl&search=not) \ No newline at end of file diff --git a/glossary/any/README-pl.md b/glossary/any/README-pl.md index 4a49ded..5fce170 100644 --- a/glossary/any/README-pl.md +++ b/glossary/any/README-pl.md @@ -1,4 +1,4 @@ -## Any +## any Sprawdza, czy choć jeden element wektora logicznego jest prawdziwy ### Deklaracja @@ -26,4 +26,4 @@ bool any(bvec x) { // bvec może być bvec2, bvec3 lub bvec4 ``` ### Zobacz też -[any()](/glossary/?search=any), [not()](/glossary/?search=not) \ No newline at end of file +[any()](/glossary/?lan=pl&search=any), [not()](/glossary/?lan=pl&search=not) \ No newline at end of file diff --git a/glossary/asin/README-pl.md b/glossary/asin/README-pl.md index 952b075..991595c 100644 --- a/glossary/asin/README-pl.md +++ b/glossary/asin/README-pl.md @@ -1,4 +1,4 @@ -## Asin +## asin Zwraca arcsin parametru ### Deklaracja @@ -18,4 +18,4 @@ vec4 asin(vec4 x)
### Zobacz też -[cos](/glossary/?search=cos), [sin](/glossary/?search=sin), [acos](/glossary/?search=acos), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/) \ No newline at end of file +[cos](/glossary/?lan=pl&search=cos), [sin](/glossary/?lan=pl&search=sin), [acos](/glossary/?lan=pl&search=acos), [tan](/glossary/?lan=pl&search=tan), [atan](/glossary/?lan=pl&search=atan), [Rozdział 05: Shaping Functions](/05/?lan=pl) \ No newline at end of file diff --git a/glossary/atan/README-pl.md b/glossary/atan/README-pl.md index e568c04..4a35950 100644 --- a/glossary/atan/README-pl.md +++ b/glossary/atan/README-pl.md @@ -1,4 +1,4 @@ -## Atan +## atan Zwraca arcus tangens parametrów ### Deklaracja @@ -27,6 +27,6 @@ vec4 atan(vec4 y_over_x) Dla drugiego przeciążenia, ```atan()``` zwraca kąt, którego tangens wynosi ```y_over_x```. Wartości zwracane w tym przypadku mieszczą się w zakresie -PI do PI. ### Zobacz też -[cos](/glossary/?search=cos), [acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [atan](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/), [Rozdział 06: Kolory](/06/) +[cos](/glossary/?lan=pl&search=cos), [acos](/glossary/?lan=pl&search=acos), [sin](/glossary/?lan=pl&search=sin), [asin](/glossary/?lan=pl&search=asin), [atan](/glossary/?lan=pl&search=atan), [Rozdział 05: Shaping Functions](/05/), [Rozdział 06: Kolory](/06/) []: # (end) []: # (end) \ No newline at end of file diff --git a/glossary/attribute/README-pl.md b/glossary/attribute/README-pl.md new file mode 100644 index 0000000..e38e0ba --- /dev/null +++ b/glossary/attribute/README-pl.md @@ -0,0 +1,15 @@ +## attribute +Dane atrybutów wierzchołka. + +### Przykład +```glsl +attribute vec4 v_color; +``` + +### Opis +`attribute` to zmienne tylko do odczytu, zawierające dane udostępniane z środowiska WebGL/OpenGL do vertex shadera. + +Ponieważ vertex shader jest uruchamiany raz dla każdego wierzchołka, atrybuty określają dane specyficzne dla poszczególnych wierzchołków, takie jak: pozycja w przestrzeni, kolor, kierunek wektora normalnego czy współrzędne tekstury. + +### Zobacz też +[const](/glossary/?lan=pl&search=const), [uniform](/glossary/?lan=pl&search=uniform), [varying](/glossary/?lan=pl&search=varying), [Rozdział 03: Uniformy](/03/?lan=pl) diff --git a/glossary/bool/README-pl.md b/glossary/bool/README-pl.md new file mode 100644 index 0000000..4b27972 --- /dev/null +++ b/glossary/bool/README-pl.md @@ -0,0 +1,15 @@ +## bool +Typ zmiennej logicznej + +### Deklaracja +```glsl +bool aBool = true; +bool bBool = bool(aInt); +bool cBool = bool(aFloat); +``` + +### Opis +`bool` może przyjmować dwie wartości: `true` lub `false`. + +### Zobacz też +[void](/glossary/?lan=pl&search=void), [bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [struct](/glossary/?lan=pl&search=struct) diff --git a/glossary/bvec2/README-pl.md b/glossary/bvec2/README-pl.md new file mode 100644 index 0000000..f4b9581 --- /dev/null +++ b/glossary/bvec2/README-pl.md @@ -0,0 +1,21 @@ +## bvec2 +2-wymiarowy wektor `bool`owski + +### Deklaracja +```glsl +bvec2 aBvec2 = bvec2(true, true); +bvec2 bBvec2 = bvec2(true); + +bvec2 cBvec2 = bvec2(aBvec3); +bvec2 dBvec2 = bvec2(aBvec3.x, aBvec3.y); +``` + +### Opis +`bvec2` to wektor `bool`owski z dwoma komponentami. Może być inicjalizowany na kilka sposobów: + +- Poprzez podanie wartości skalarnej dla każdego komponentu. +- Poprzez podanie jednej wartości skalarnej – zostanie ona przypisana do wszystkich komponentów. +- Poprzez podanie wektora o wyższym wymiarze – odpowiednie wartości zostaną użyte do inicjalizacji komponentów. + +### Zobacz też +[bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [ivec2](/glossary/?lan=pl&search=ivec2), [ivec3](/glossary/?lan=pl&search=ivec3), [ivec4](/glossary/?lan=pl&search=ivec4), [vec2](/glossary/?lan=pl&search=vec2), [vec3](/glossary/?lan=pl&search=vec3), [vec4](/glossary/?lan=pl&search=vec4), [mat2](/glossary/?lan=pl&search=mat2), [mat3](/glossary/?lan=pl&search=mat3), [mat4](/glossary/?lan=pl&search=mat4) diff --git a/glossary/bvec3/README-pl.md b/glossary/bvec3/README-pl.md new file mode 100644 index 0000000..c812f2d --- /dev/null +++ b/glossary/bvec3/README-pl.md @@ -0,0 +1,25 @@ +## bvec3 +3-wymiarowy wektor `bool`owski + +### Deklaracja +```glsl +vec3 aBvec3 = bvec3(true, true, true); +vec3 bBvec3 = bvec3(true); + +vec3 cBvec3 = bvec3(aBvec4); +vec3 dBvec3 = bvec3(aBvec4.x, aBvec4.y, aBvec4.z); + +vec3 eBvec3 = bvec3(aBvec2, aBool); +vec3 fBvec3 = bvec3(aBvec2.x, aBvec2.y, aBool); +``` + +### Opis +`bvec3` to wektor `bool`owski z trzema komponentami. Może być inicjalizowany na kilka sposobów: + +- Poprzez podanie wartości skalarnej dla każdego komponentu. +- Poprzez podanie jednej wartości skalarnej – zostanie ona przypisana do wszystkich komponentów. +- Poprzez podanie wektora o wyższym wymiarze – odpowiednie wartości zostaną użyte do inicjalizacji komponentów. +- Poprzez podanie kombinacji wektorów i/lub skalarów – odpowiednie wartości zostaną użyte do inicjalizacji wektora. Argumenty konstruktora muszą zawierać co najmniej tyle komponentów, ile ma inicjalizowany wektor. + +### Zobacz też +[bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [ivec2](/glossary/?lan=pl&search=ivec2), [ivec3](/glossary/?lan=pl&search=ivec3), [ivec4](/glossary/?lan=pl&search=ivec4), [vec2](/glossary/?lan=pl&search=vec2), [vec3](/glossary/?lan=pl&search=vec3), [vec4](/glossary/?lan=pl&search=vec4), [mat2](/glossary/?lan=pl&search=mat2), [mat3](/glossary/?lan=pl&search=mat3), [mat4](/glossary/?lan=pl&search=mat4) From edb0e29f8a63646667f6ceb485e989c1fd2610f1 Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Sun, 9 Feb 2025 14:57:23 +0100 Subject: [PATCH 42/47] unified the singular/plural forms --- glossary/ceil/README.md | 2 +- glossary/clamp/README.md | 6 +++--- glossary/cos/README-ua.md | 21 --------------------- glossary/cos/README-vi.md | 21 --------------------- glossary/cos/README.md | 21 --------------------- glossary/degrees/README.md | 2 +- glossary/equal/README.md | 4 ++-- glossary/exp/README.md | 2 +- glossary/exp2/README.md | 2 +- glossary/floor/README.md | 2 +- glossary/fract/README.md | 2 +- glossary/inversesqrt/README.md | 2 +- glossary/log/README.md | 2 +- glossary/log2/README.md | 2 +- glossary/max/README.md | 4 ++-- glossary/min/README.md | 4 ++-- glossary/mix/README.md | 6 +++--- glossary/mod/README.md | 4 ++-- glossary/pow/README.md | 4 ++-- glossary/radians/README.md | 2 +- glossary/sign/README.md | 2 +- glossary/sqrt/README.md | 2 +- glossary/step/README.md | 2 +- glossary/struct/README.md | 2 +- glossary/tan/README.md | 2 +- 25 files changed, 31 insertions(+), 94 deletions(-) delete mode 100644 glossary/cos/README-ua.md delete mode 100644 glossary/cos/README-vi.md delete mode 100644 glossary/cos/README.md diff --git a/glossary/ceil/README.md b/glossary/ceil/README.md index affed94..614015b 100644 --- a/glossary/ceil/README.md +++ b/glossary/ceil/README.md @@ -10,7 +10,7 @@ vec4 ceil(vec4 x) ``` ### Parameters -```x``` specify the value to evaluate. +```x``` specifies the value to evaluate. ### Description ```ceil()``` returns a value equal to the nearest integer that is greater than or equal to ```x```. diff --git a/glossary/clamp/README.md b/glossary/clamp/README.md index 32013ae..7c815be 100644 --- a/glossary/clamp/README.md +++ b/glossary/clamp/README.md @@ -14,11 +14,11 @@ vec4 clamp(vec4 x, float minVal, float maxVal) ``` ### Parameters -```x``` specify the value to constrain. +```x``` specifies the value to constrain. -```minVal``` specify the lower end of the range into which to constrain x. +```minVal``` specifies the lower end of the range into which to constrain x. -```maxVal``` specify the upper end of the range into which to constrain x. +```maxVal``` specifies the upper end of the range into which to constrain x. ### Description ```clamp()``` returns the value of ```x``` constrained to the range ```minVal``` to ```maxVal```. The returned value is computed as ```min(max(x, minVal), maxVal)```. diff --git a/glossary/cos/README-ua.md b/glossary/cos/README-ua.md deleted file mode 100644 index a79f3c9..0000000 --- a/glossary/cos/README-ua.md +++ /dev/null @@ -1,21 +0,0 @@ -## cos -Повертає косинус параметра - -### Оголошення -```glsl -float cos(float angle) -vec2 cos(vec2 angle) -vec3 cos(vec3 angle) -vec4 cos(vec4 angle) -``` - -### Параметри -**```angle```** — величина в радіанах, косинус якої потрібно повернути. - -### Опис -**```cos()```** повертає тригонометричний косинус кута. - -
- -### Дивіться також -[acos](/glossary/?lan=ua&search=acos), [sin](/glossary/?lan=ua&search=sin), [asin](/glossary/?lan=ua&search=asin), [tan](/glossary/?lan=ua&search=tan), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/cos/README-vi.md b/glossary/cos/README-vi.md deleted file mode 100644 index e9d49bd..0000000 --- a/glossary/cos/README-vi.md +++ /dev/null @@ -1,21 +0,0 @@ -## Cos -Tính hàm cosine của 1 góc lượng giác - -### Các phiên bản -```glsl -float cos(float angle) -vec2 cos(vec2 angle) -vec3 cos(vec3 angle) -vec4 cos(vec4 angle) -``` - -### Các tham số -```angle``` góc lượng giác (đơn vị radian) cần tính cosine - -### Mô tả -```cos()``` trả về giá trị cosine tương ứng với góc ```angle``` - -
- -### Tham khảo thêm -[acos](/glossary/?lan=vi&search=acos), [sin](/glossary/?lan=vi&search=sin), [asin](/glossary/?lan=vi&search=asin), [tan](/glossary/?lan=vi&search=tan), [atan](/glossary/?lan=vi&search=atan), [Các hàm số cơ bản (Hàm hình dạng - Shape function)](/05/?lan=vi) diff --git a/glossary/cos/README.md b/glossary/cos/README.md deleted file mode 100644 index a17764c..0000000 --- a/glossary/cos/README.md +++ /dev/null @@ -1,21 +0,0 @@ -## Cos -Return the cosine of the parameter - -### Declaration -```glsl -float cos(float angle) -vec2 cos(vec2 angle) -vec3 cos(vec3 angle) -vec4 cos(vec4 angle) -``` - -### Parameters -```angle``` specify the quantity, in radians, of which to return the cosine. - -### Description -```cos()``` returns the trigonometric cosine of angle. - -
- -### See Also -[acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/degrees/README.md b/glossary/degrees/README.md index a782b2b..2fe5a0b 100644 --- a/glossary/degrees/README.md +++ b/glossary/degrees/README.md @@ -10,7 +10,7 @@ vec4 degrees(vec4 radians) ``` ### Parameters -```radians``` specify the quantity, in radians, to be converted to degrees. +```radians``` specifies the quantity, in radians, to be converted to degrees. ### Description ```degrees()``` converts a quantity, specified in radians into degrees. That is, the return value is ```(180.0*radians)/PI``` diff --git a/glossary/equal/README.md b/glossary/equal/README.md index d3bf59f..a9bdf93 100644 --- a/glossary/equal/README.md +++ b/glossary/equal/README.md @@ -13,9 +13,9 @@ bvec4 equal(ivec4 x, ivec4 y) ``` ### Parameters -```x``` Specifies the first vector to be used in the comparison operation. +```x``` specifies the first vector to be used in the comparison operation. -```y``` Specifies the second vector to be used in the comparison operation. +```y``` specifies the second vector to be used in the comparison operation. ### Description ```equal()``` returns a boolean vector in which each element ```i``` is computed as ```x[i] == y[i]```. diff --git a/glossary/exp/README.md b/glossary/exp/README.md index 2f6d42d..d148482 100644 --- a/glossary/exp/README.md +++ b/glossary/exp/README.md @@ -10,7 +10,7 @@ vec4 exp(vec4 x) ``` ### Parameters -```x``` specify the value to exponentiate. +```x``` specifies the value to exponentiate. ### Description ```exp()``` returns the natural exponentiation of ```x```. diff --git a/glossary/exp2/README.md b/glossary/exp2/README.md index 1c508dc..abd2845 100644 --- a/glossary/exp2/README.md +++ b/glossary/exp2/README.md @@ -10,7 +10,7 @@ vec4 exp2(vec4 x) ``` ### Parameters -```x``` specify the value of the power to which 2 will be raised. +```x``` specifies the value of the power to which 2 will be raised. ### Description ```exp2()``` returns 2 raised to the power of ```x```. diff --git a/glossary/floor/README.md b/glossary/floor/README.md index 8b496d0..af7322b 100644 --- a/glossary/floor/README.md +++ b/glossary/floor/README.md @@ -10,7 +10,7 @@ vec4 floor(vec4 x) ``` ### Parameters -```x``` specify the value to evaluate. +```x``` specifies the value to evaluate. ### Description ```floor()``` returns a value equal to the nearest integer that is less than or equal to ```x```. diff --git a/glossary/fract/README.md b/glossary/fract/README.md index 68fd266..47c7345 100644 --- a/glossary/fract/README.md +++ b/glossary/fract/README.md @@ -10,7 +10,7 @@ vec4 fract(vec4 x) ``` ### Parameters -```x``` specify the value to evaluate. +```x``` specifies the value to evaluate. ### Description ```fract()``` returns the fractional part of ```x```. This is calculated as ```x - floor(x)```. diff --git a/glossary/inversesqrt/README.md b/glossary/inversesqrt/README.md index 676278a..c9c76f6 100644 --- a/glossary/inversesqrt/README.md +++ b/glossary/inversesqrt/README.md @@ -10,7 +10,7 @@ vec4 inversesqrt(vec4 x) ``` ### Parameters -```x``` specify the value of which to take the inverse of the square root. +```x``` specifies the value of which to take the inverse of the square root. ### Description ```inversesqrt()``` returns the inverse of the square root of ```x```. diff --git a/glossary/log/README.md b/glossary/log/README.md index 6be29e2..9e5b15b 100644 --- a/glossary/log/README.md +++ b/glossary/log/README.md @@ -10,7 +10,7 @@ vec4 log(vec4 x) ``` ### Parameters -```x``` specify the value of which to take the natural logarithm. +```x``` specifies the value of which to take the natural logarithm. ### Description ```log()``` returns the natural logarithm of ```x```. diff --git a/glossary/log2/README.md b/glossary/log2/README.md index 72856b9..4402c7f 100644 --- a/glossary/log2/README.md +++ b/glossary/log2/README.md @@ -10,7 +10,7 @@ vec4 log2(vec4 x) ``` ### Parameters -```x``` specify the value of which to take the base 2 logarithm. +```x``` specifies the value of which to take the base 2 logarithm. ### Description ```log2()``` returns the base 2 logarithm of ```x```. diff --git a/glossary/max/README.md b/glossary/max/README.md index 56f4da3..920092e 100644 --- a/glossary/max/README.md +++ b/glossary/max/README.md @@ -14,9 +14,9 @@ vec4 max(vec4 x, float y) ``` ### Parameters -```x``` specify the first value to compare. +```x``` specifies the first value to compare. -```y``` specify the second value to compare. +```y``` specifies the second value to compare. ### Description ```max()``` returns the maximum of the two parameters. It returns ```y``` if ```y``` is greater than ```x```, otherwise it returns ```x```. diff --git a/glossary/min/README.md b/glossary/min/README.md index ddc22cf..00205e8 100644 --- a/glossary/min/README.md +++ b/glossary/min/README.md @@ -14,9 +14,9 @@ vec4 min(vec4 x, float y) ``` ### Parameters -```x``` specify the first value to compare. +```x``` specifies the first value to compare. -```y``` specify the second value to compare. +```y``` specifies the second value to compare. ### Description ```min()``` returns the minimum of the two parameters. It returns ```y``` if ```y``` is less than ```x```, otherwise it returns ```x```. diff --git a/glossary/mix/README.md b/glossary/mix/README.md index 85ed5a0..227e7cc 100644 --- a/glossary/mix/README.md +++ b/glossary/mix/README.md @@ -14,11 +14,11 @@ vec4 mix(vec4 x, vec4 y, float a) ``` ### Parameters -```x``` Specify the start of the range in which to interpolate. +```x``` specifies the start of the range in which to interpolate. -```y``` Specify the end of the range in which to interpolate. +```y``` specifies the end of the range in which to interpolate. -```a``` Specify the value to use to interpolate between x and y. +```a``` specifies the value to use to interpolate between x and y. ### Description ```mix()``` performs a linear interpolation between ```x``` and ```y``` using ```a``` to weight between them. The return value is computed as ```x×(1−a)+y×a```. diff --git a/glossary/mod/README.md b/glossary/mod/README.md index 69fdf5a..a11ad8f 100644 --- a/glossary/mod/README.md +++ b/glossary/mod/README.md @@ -14,8 +14,8 @@ vec4 mod(vec4 x, float y) ``` ### Parameters -```x``` specify the value to evaluate. -```y``` specify the value to obtain the modulo of. +```x``` specifies the value to evaluate. +```y``` specifies the value to obtain the modulo of. ### Description ```mod()``` returns the value of ```x``` modulo ```y```. This is computed as ```x - y * floor(x/y)```. diff --git a/glossary/pow/README.md b/glossary/pow/README.md index b7fc9fb..28dda6b 100644 --- a/glossary/pow/README.md +++ b/glossary/pow/README.md @@ -10,9 +10,9 @@ vec4 pow(vec4 x, vec4 y) ``` ### Parameters -```x``` specify the value to raise to the power ```y```. +```x``` specifies the value to raise to the power ```y```. -```y``` specify the power to which to raise ```x```. +```y``` specifies the power to which to raise ```x```. ### Description ```pow()``` returns the value of ```x``` raised to the ```y``` power. diff --git a/glossary/radians/README.md b/glossary/radians/README.md index bf29e72..6a3ffec 100644 --- a/glossary/radians/README.md +++ b/glossary/radians/README.md @@ -10,7 +10,7 @@ vec4 radians(vec4 degrees) ``` ### Parameters -```degrees``` specify the quantity, in degrees, to be converted to radians. +```degrees``` specifies the quantity, in degrees, to be converted to radians. ### Description ```radians()``` converts a quantity, specified in degrees into radians. That is, the return value is ```(PI * degrees)/180```. diff --git a/glossary/sign/README.md b/glossary/sign/README.md index 656f2c4..66b5677 100644 --- a/glossary/sign/README.md +++ b/glossary/sign/README.md @@ -10,7 +10,7 @@ vec4 sign(vec4 x) ``` ### Parameters -```x``` specify the value from which to extract the sign. +```x``` specifies the value from which to extract the sign. ### Description ```sign()``` returns -1.0 if x is less than 0.0, 0.0 if x is equal to 0.0, and +1.0 if x is greater than 0.0. diff --git a/glossary/sqrt/README.md b/glossary/sqrt/README.md index 8895ba3..adf70a8 100644 --- a/glossary/sqrt/README.md +++ b/glossary/sqrt/README.md @@ -10,7 +10,7 @@ vec4 sqrt(vec4 x) ``` ### Parameters -```x``` specify the value of which to take the square root. +```x``` specifies the value of which to take the square root. ### Description ```sqrt()``` returns the square root of ```x```. diff --git a/glossary/step/README.md b/glossary/step/README.md index baf78f5..9af2734 100644 --- a/glossary/step/README.md +++ b/glossary/step/README.md @@ -16,7 +16,7 @@ vec4 step(float edge, vec4 x) ### Parameters ```edge``` specifies the location of the edge of the step function. -```x``` specify the value to be used to generate the step function. +```x``` specifies the value to be used to generate the step function. ### Description ```step()``` generates a step function by comparing ```x``` to ```edge```. diff --git a/glossary/struct/README.md b/glossary/struct/README.md index 6338481..40decd1 100644 --- a/glossary/struct/README.md +++ b/glossary/struct/README.md @@ -17,4 +17,4 @@ newMaterial = matStruct(vec4(0.1, 0.1, 0.1, 1.0), ``` ### Description -```struct``` declare a custom data structures based on standard types. A constructor for the structure with the same name is created automatically. The declaration of a variable (in this case "newMaterial") is optional. +```struct``` declares a custom data structure based on standard types. A constructor for the structure with the same name is created automatically. The declaration of a variable (in this case "newMaterial") is optional. diff --git a/glossary/tan/README.md b/glossary/tan/README.md index 0430a8c..c830c6b 100644 --- a/glossary/tan/README.md +++ b/glossary/tan/README.md @@ -10,7 +10,7 @@ vec4 tan(vec4 angle) ``` ### Parameters -```angle``` specify the quantity, in radians, of which to return the tangent. +```angle``` specifies the quantity, in radians, of which to return the tangent. ### Description ```tan()``` returns the trigonometric tangent of angle. From 16b87c539c64c3497650f287fcb7c29bff976225 Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Sun, 9 Feb 2025 14:58:10 +0100 Subject: [PATCH 43/47] readded files that i deleted by mistake --- glossary/cos/README-ua.md | 21 +++++++++++++++++++++ glossary/cos/README-vi.md | 21 +++++++++++++++++++++ glossary/cos/README.md | 21 +++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 glossary/cos/README-ua.md create mode 100644 glossary/cos/README-vi.md create mode 100644 glossary/cos/README.md diff --git a/glossary/cos/README-ua.md b/glossary/cos/README-ua.md new file mode 100644 index 0000000..a79f3c9 --- /dev/null +++ b/glossary/cos/README-ua.md @@ -0,0 +1,21 @@ +## cos +Повертає косинус параметра + +### Оголошення +```glsl +float cos(float angle) +vec2 cos(vec2 angle) +vec3 cos(vec3 angle) +vec4 cos(vec4 angle) +``` + +### Параметри +**```angle```** — величина в радіанах, косинус якої потрібно повернути. + +### Опис +**```cos()```** повертає тригонометричний косинус кута. + +
+ +### Дивіться також +[acos](/glossary/?lan=ua&search=acos), [sin](/glossary/?lan=ua&search=sin), [asin](/glossary/?lan=ua&search=asin), [tan](/glossary/?lan=ua&search=tan), [atan](/glossary/?lan=ua&search=atan), [Розділ 05: Формотворчі функції](/05/?lan=ua) diff --git a/glossary/cos/README-vi.md b/glossary/cos/README-vi.md new file mode 100644 index 0000000..e9d49bd --- /dev/null +++ b/glossary/cos/README-vi.md @@ -0,0 +1,21 @@ +## Cos +Tính hàm cosine của 1 góc lượng giác + +### Các phiên bản +```glsl +float cos(float angle) +vec2 cos(vec2 angle) +vec3 cos(vec3 angle) +vec4 cos(vec4 angle) +``` + +### Các tham số +```angle``` góc lượng giác (đơn vị radian) cần tính cosine + +### Mô tả +```cos()``` trả về giá trị cosine tương ứng với góc ```angle``` + +
+ +### Tham khảo thêm +[acos](/glossary/?lan=vi&search=acos), [sin](/glossary/?lan=vi&search=sin), [asin](/glossary/?lan=vi&search=asin), [tan](/glossary/?lan=vi&search=tan), [atan](/glossary/?lan=vi&search=atan), [Các hàm số cơ bản (Hàm hình dạng - Shape function)](/05/?lan=vi) diff --git a/glossary/cos/README.md b/glossary/cos/README.md new file mode 100644 index 0000000..a17764c --- /dev/null +++ b/glossary/cos/README.md @@ -0,0 +1,21 @@ +## Cos +Return the cosine of the parameter + +### Declaration +```glsl +float cos(float angle) +vec2 cos(vec2 angle) +vec3 cos(vec3 angle) +vec4 cos(vec4 angle) +``` + +### Parameters +```angle``` specify the quantity, in radians, of which to return the cosine. + +### Description +```cos()``` returns the trigonometric cosine of angle. + +
+ +### See Also +[acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) From af523fcc5c3258443c7629bdc69611dcee271433 Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Sun, 9 Feb 2025 14:58:27 +0100 Subject: [PATCH 44/47] fixed a few translations to Polish --- glossary/bvec2/README-pl.md | 8 ++++---- glossary/bvec3/README-pl.md | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/glossary/bvec2/README-pl.md b/glossary/bvec2/README-pl.md index f4b9581..75e2c00 100644 --- a/glossary/bvec2/README-pl.md +++ b/glossary/bvec2/README-pl.md @@ -11,11 +11,11 @@ bvec2 dBvec2 = bvec2(aBvec3.x, aBvec3.y); ``` ### Opis -`bvec2` to wektor `bool`owski z dwoma komponentami. Może być inicjalizowany na kilka sposobów: +`bvec2` to wektor `bool`owski z dwoma komponentami. Można go zainicjalizować: -- Poprzez podanie wartości skalarnej dla każdego komponentu. -- Poprzez podanie jednej wartości skalarnej – zostanie ona przypisana do wszystkich komponentów. -- Poprzez podanie wektora o wyższym wymiarze – odpowiednie wartości zostaną użyte do inicjalizacji komponentów. +- Podając wartość skalarną dla każdego komponentu. +- Podając jedną wartośś skalarną. Zostanie ona przypisana do wszystkich komponentów. +- Podając wektor o wyższym wymiarze. Odpowiednie wartości zostaną użyte do inicjalizacji komponentów. ### Zobacz też [bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [ivec2](/glossary/?lan=pl&search=ivec2), [ivec3](/glossary/?lan=pl&search=ivec3), [ivec4](/glossary/?lan=pl&search=ivec4), [vec2](/glossary/?lan=pl&search=vec2), [vec3](/glossary/?lan=pl&search=vec3), [vec4](/glossary/?lan=pl&search=vec4), [mat2](/glossary/?lan=pl&search=mat2), [mat3](/glossary/?lan=pl&search=mat3), [mat4](/glossary/?lan=pl&search=mat4) diff --git a/glossary/bvec3/README-pl.md b/glossary/bvec3/README-pl.md index c812f2d..c5770ca 100644 --- a/glossary/bvec3/README-pl.md +++ b/glossary/bvec3/README-pl.md @@ -14,12 +14,12 @@ vec3 fBvec3 = bvec3(aBvec2.x, aBvec2.y, aBool); ``` ### Opis -`bvec3` to wektor `bool`owski z trzema komponentami. Może być inicjalizowany na kilka sposobów: +`bvec3` to wektor `bool`owski z trzema komponentami. Można go zainicjalizować: -- Poprzez podanie wartości skalarnej dla każdego komponentu. -- Poprzez podanie jednej wartości skalarnej – zostanie ona przypisana do wszystkich komponentów. -- Poprzez podanie wektora o wyższym wymiarze – odpowiednie wartości zostaną użyte do inicjalizacji komponentów. -- Poprzez podanie kombinacji wektorów i/lub skalarów – odpowiednie wartości zostaną użyte do inicjalizacji wektora. Argumenty konstruktora muszą zawierać co najmniej tyle komponentów, ile ma inicjalizowany wektor. +- Podając wartość skalarną dla każdego komponentu. +- Podając jedną wartość skalarną – zostanie ona przypisana do wszystkich komponentów. +- Podając wektor o wyższym wymiarze – odpowiednie wartości zostaną użyte do inicjalizacji komponentów. +- Podając kombinację wektorów i/lub skalarów – odpowiednie wartości zostaną użyte do inicjalizacji wektora. Argumenty konstruktora muszą zawierać co najmniej tyle komponentów, ile ma inicjalizowany wektor. ### Zobacz też [bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [ivec2](/glossary/?lan=pl&search=ivec2), [ivec3](/glossary/?lan=pl&search=ivec3), [ivec4](/glossary/?lan=pl&search=ivec4), [vec2](/glossary/?lan=pl&search=vec2), [vec3](/glossary/?lan=pl&search=vec3), [vec4](/glossary/?lan=pl&search=vec4), [mat2](/glossary/?lan=pl&search=mat2), [mat3](/glossary/?lan=pl&search=mat3), [mat4](/glossary/?lan=pl&search=mat4) From 348d7a589fb056d9cb9b37bee225a5503640af7c Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Sun, 9 Feb 2025 17:43:07 +0100 Subject: [PATCH 45/47] Add Polish translations --- glossary/bvec4/README-pl.md | 21 +++++++++++++++++++++ glossary/ceil/README-pl.md | 21 +++++++++++++++++++++ glossary/clamp/README-pl.md | 29 +++++++++++++++++++++++++++++ glossary/const/README-pl.md | 13 +++++++++++++ glossary/cos/README-pl.md | 21 +++++++++++++++++++++ glossary/cross/README-pl.md | 18 ++++++++++++++++++ glossary/dFdx/README-pl.md | 16 ++++++++++++++++ glossary/dFdy/README-pl.md | 16 ++++++++++++++++ glossary/degrees/README-pl.md | 19 +++++++++++++++++++ glossary/distance/README-pl.md | 23 +++++++++++++++++++++++ glossary/dot/README-pl.md | 24 ++++++++++++++++++++++++ glossary/sin/README-pl.md | 2 +- 12 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 glossary/bvec4/README-pl.md create mode 100644 glossary/ceil/README-pl.md create mode 100644 glossary/clamp/README-pl.md create mode 100644 glossary/const/README-pl.md create mode 100644 glossary/cos/README-pl.md create mode 100644 glossary/cross/README-pl.md create mode 100644 glossary/dFdx/README-pl.md create mode 100644 glossary/dFdy/README-pl.md create mode 100644 glossary/degrees/README-pl.md create mode 100644 glossary/distance/README-pl.md create mode 100644 glossary/dot/README-pl.md diff --git a/glossary/bvec4/README-pl.md b/glossary/bvec4/README-pl.md new file mode 100644 index 0000000..778de1d --- /dev/null +++ b/glossary/bvec4/README-pl.md @@ -0,0 +1,21 @@ +## bvec4 +4-wymiarowy wektor `bool`owski + +### Deklaracja +```glsl +vec4 aBvec4 = bvec4(true, true, true, true); +vec4 bBvec4 = bvec4(true); + +vec4 cBvec4 = bvec4(aBvec2, aBool, aBvec3); +vec4 dBvec4 = bvec4(aBvec2.x, aBvec2.y, aBool, aBvec3.x); +``` + +### Opis +`bvec4` to wektor `bool`owski mający cztery składowe. Można go zainicjalizować: + +- Podając osobną wartość skalarną dla każdej składowej. +- Podając jedną wartość skalarną. Wartość ta zostanie użyta dla wszystkich składowych. +- Podając kombinację wektorów i skalarów. Odpowiednie wartości zostaną użyte do inicjalizacji składowych. Argumenty konstruktora muszą mieć przynajmniej tyle składowych, ile wynosi rozmiar inicjalizowanego wektora. + +### Zobacz też +[bool](/glossary/?lan=pl&search=bool), [int](/glossary/?lan=pl&search=int), [float](/glossary/?lan=pl&search=float), [bvec2](/glossary/?lan=pl&search=bvec2), [bvec3](/glossary/?lan=pl&search=bvec3), [bvec4](/glossary/?lan=pl&search=bvec4), [ivec2](/glossary/?lan=pl&search=ivec2), [ivec3](/glossary/?lan=pl&search=ivec3), [ivec4](/glossary/?lan=pl&search=ivec4), [vec2](/glossary/?lan=pl&search=vec2), [vec3](/glossary/?lan=pl&search=vec3), [vec4](/glossary/?lan=pl&search=vec4), [mat2](/glossary/?lan=pl&search=mat2), [mat3](/glossary/?lan=pl&search=mat3), [mat4](/glossary/?lan=pl&search=mat4) \ No newline at end of file diff --git a/glossary/ceil/README-pl.md b/glossary/ceil/README-pl.md new file mode 100644 index 0000000..5d33b4b --- /dev/null +++ b/glossary/ceil/README-pl.md @@ -0,0 +1,21 @@ +## ceil +Znajdź najbliższą liczbę całkowitą, która jest większa lub równa podanemu parametrowi + +### Deklaracja +```glsl +float ceil(float x) +vec2 ceil(vec2 x) +vec3 ceil(vec3 x) +vec4 ceil(vec4 x) +``` + +### Parametry +```x``` określa wartość do ewaluacji + +### Opis +```ceil()``` zwraca wartość równą najbliższej liczbie całkowitej, która jest większa bądź równa ```x```. + +
+ +### Zobacz też +[floor](/glossary/?lan=pl&search=floor), [fract](/glossary/?lan=pl&search=fract), [mod](/glossary/?lan=pl&search=mod), [Rozdział 05: Shaping Functions](/05/?lan=pl) diff --git a/glossary/clamp/README-pl.md b/glossary/clamp/README-pl.md new file mode 100644 index 0000000..bab15cb --- /dev/null +++ b/glossary/clamp/README-pl.md @@ -0,0 +1,29 @@ +## clamp +Ogranicza wartość, aby mieściła się między dwoma skrajnymi wartościami + +### Deklaracja +```glsl +float clamp(float x, float minVal, float maxVal) +vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal) +vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal) +vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal) + +vec2 clamp(vec2 x, float minVal, float maxVal) +vec3 clamp(vec3 x, float minVal, float maxVal) +vec4 clamp(vec4 x, float minVal, float maxVal) +``` + +### Parametry +```x``` określa wartość, którą należy ograniczyć. + +```minVal``` określa dolną granicę zakresu, w którym będzie ograniczana wartość x. + +```maxVal``` określa górną granicę zakresu, w którym będzie ograniczana wartość x. + +### Opis +```clamp()``` zwraca wartość ```x``` ograniczoną do zakresu od ```minVal``` do ```maxVal```. Zwrócona wartość obliczana jest jako ```min(max(x, minVal), maxVal)```. + +
+ +### Zobacz też +[min](/glossary/?lan=pl&search=min), [abs](/glossary/?lan=pl&search=abs), [max](/glossary/?lan=pl&search=max) \ No newline at end of file diff --git a/glossary/const/README-pl.md b/glossary/const/README-pl.md new file mode 100644 index 0000000..e04b904 --- /dev/null +++ b/glossary/const/README-pl.md @@ -0,0 +1,13 @@ +## const +Kwalifikator stały + +### Przykład +```glsl +const float PI = 3.14159265359; +``` + +### Opis +Kwalifikator ```const``` może być zastosowany do deklaracji dowolnej zmiennej, aby określić, że jej wartość nie ulegnie zmianie. + +### Zobacz też +[attribute](/glossary/?lan=pl&search=attribute), [uniform](/glossary/?lan=pl&search=uniform), [varying](/glossary/?lan=pl&search=varying) \ No newline at end of file diff --git a/glossary/cos/README-pl.md b/glossary/cos/README-pl.md new file mode 100644 index 0000000..b51eeda --- /dev/null +++ b/glossary/cos/README-pl.md @@ -0,0 +1,21 @@ +## cos +Zwraca cosinus podanego parametru + +### Deklaracja +```glsl +float cos(float angle) +vec2 cos(vec2 angle) +vec3 cos(vec3 angle) +vec4 cos(vec4 angle) +``` + +### Parametry +```angle``` określa wartość (w radianach), dla której ma zostać zwrócony cosinus. + +### Opis +```cos()``` zwraca trygonometryczny cosinus podanego kąta. + +
+ +### Zobacz też +[acos](/glossary/?lan=pl&search=acos), [sin](/glossary/?lan=pl&search=sin), [asin](/glossary/?lan=pl&search=asin), [tan](/glossary/?lan=pl&search=tan), [atan](/glossary/?lan=pl&search=atan), [Rozdział 05: Shaping Functions](/05/?lan=pl) \ No newline at end of file diff --git a/glossary/cross/README-pl.md b/glossary/cross/README-pl.md new file mode 100644 index 0000000..8167d30 --- /dev/null +++ b/glossary/cross/README-pl.md @@ -0,0 +1,18 @@ +## cross +Oblicza iloczyn wektorowy dwóch wektorów + +### Deklaracja +```glsl +vec3 cross(vec3 x, vec3 y) +``` + +### Parametry +```x``` określa pierwszy z dwóch wektorów + +```y``` określa drugi z dwóch wektorów + +### Opis +```cross()``` zwraca iloczyn wektorowy dwóch wektorów, ```x``` i ```y```. Parametry wejściowe mogą być wyłącznie 3-składowymi wektorami zmiennoprzecinkowymi. Iloczyn wektorowy jest równoważny iloczynowi długości tych wektorów pomnożonemu przez sinus (mniejszego) kąta między ```x``` i ```y```. + +### Zobacz też +[dot](/glossary/?lan=pl&search=dot) \ No newline at end of file diff --git a/glossary/dFdx/README-pl.md b/glossary/dFdx/README-pl.md new file mode 100644 index 0000000..b6ba3f8 --- /dev/null +++ b/glossary/dFdx/README-pl.md @@ -0,0 +1,16 @@ +## dFdx +Zwraca pochodną cząstkową podanego wyrażenia względem x + +### Deklaracja +```glsl +genType dFdx(float x); +``` + +### Parametry +```p``` określa wyrażenie, dla którego chcemy obliczyć pochodną cząstkową. + +### Opis +Dostępna wyłącznie w fragment shaderze , ```dFdx``` zwraca pochodną cząstkową wyrażenia ```p``` względem ```x```. Pochodne obliczane są poprzez lokalne różnicowanie. Wyrażenia oznaczające pochodne wyższego rzędu, takie jak ```dFdx(dFdx(n))```, zwracają niezdefiniowane wyniki, podobnie jak mieszane pochodne, np. ```dFdx(dFdy(n))```. Przyjmuje się, że wyrażenie ```p``` jest ciągłe, więc wyrażenia oceniane w warunkowym przepływie sterowania (non-uniform control flow) mogą być niezdefiniowane. + +### Zobacz też +[dFdy](/glossary/?lan=pl&search=dFdy) \ No newline at end of file diff --git a/glossary/dFdy/README-pl.md b/glossary/dFdy/README-pl.md new file mode 100644 index 0000000..94ed5fa --- /dev/null +++ b/glossary/dFdy/README-pl.md @@ -0,0 +1,16 @@ +## dFdy +Zwraca pochodną cząstkową podanego wyrażenia względem y + +### Deklaracja +```glsl +genType dFdy(float y); +``` + +### Parametry +```p``` określa wyrażenie, dla którego chcemy obliczyć pochodną cząstkową. + +### Opis +Dostępna wyłącznie w fragment shaderze, ```dFdy``` zwraca pochodną cząstkową wyrażenia ```p``` względem ```y```. Pochodne obliczane są poprzez lokalne różnicowanie. Wyrażenia oznaczające pochodne wyższego rzędu, takie jak ```dFdy(dFdy(n))```, zwracają niezdefiniowane wyniki, podobnie jak mieszane pochodne, np. ```dFdy(dFdx(n))```. Przyjmuje się, że wyrażenie ```p``` jest ciągłe, więc wyrażenia oceniane w warunkowym przepływie sterowania (non-uniform control flow) mogą być niezdefiniowane. + +### Zobacz też +[dFdx](/glossary/?lan=pl&search=dfdx) \ No newline at end of file diff --git a/glossary/degrees/README-pl.md b/glossary/degrees/README-pl.md new file mode 100644 index 0000000..e32a936 --- /dev/null +++ b/glossary/degrees/README-pl.md @@ -0,0 +1,19 @@ +## degrees +Konwertuje wielkość w radianach na stopnie + +### Deklaracja +```glsl +float degrees(float radians) +vec2 degrees(vec2 radians) +vec3 degrees(vec3 radians) +vec4 degrees(vec4 radians) +``` + +### Parametry +```radians``` określa wielkość (w radianach), która ma zostać zamieniona na stopnie. + +### Opis +```degrees()``` konwertuje wielkość wyrażoną w radianach na stopnie. Oznacza to, że wartość zwracana to ```(180.0*radians)/PI```. + +### Zobacz też +[radians](/glossary/?lan=pl&search=radians) \ No newline at end of file diff --git a/glossary/distance/README-pl.md b/glossary/distance/README-pl.md new file mode 100644 index 0000000..e61c52d --- /dev/null +++ b/glossary/distance/README-pl.md @@ -0,0 +1,23 @@ +## distance +Oblicza odległość między dwoma punktami + +### Deklaracja +```glsl +float distance(float p0, float p1) +float distance(vec2 p0, vec2 p1) +float distance(vec3 p0, vec3 p1) +float distance(vec4 p0, vec4 p1) +``` + +### Parametry +```p0``` określa pierwszy z dwóch punktów + +```p1``` określa drugi z dwóch punktów + +### Opis +```distance()``` zwraca odległość pomiędzy dwoma punktami ```p0``` i ```p1```. + +
+ +### Zobacz też +[length](/glossary/?lan=pl&search=length), [normalize](/glossary/?lan=pl&search=normalize), [Rozdział 07: Kształty](/07/?lan=pl) \ No newline at end of file diff --git a/glossary/dot/README-pl.md b/glossary/dot/README-pl.md new file mode 100644 index 0000000..976ed28 --- /dev/null +++ b/glossary/dot/README-pl.md @@ -0,0 +1,24 @@ +## dot +Oblicz iloczyn skalarny (dot product) dwóch wektorów + +### Deklaracja +```glsl +float dot(float x, float y) +float dot(vec2 x, vec2 y) +float dot(vec3 x, vec3 y) +float dot(vec4 x, vec4 y) +``` + +### Parametry +```x``` określa pierwszy z dwóch wektorów + +```y``` określa drugi z dwóch wektorów + +### Opis +```dot()``` zwraca iloczyn skalarny dwóch wektorów, ```x``` i ```y```, tzn. ```x[0]⋅y[0] + x[1]⋅y[1] + ...``` +Jeśli ```x``` i ```y``` są identyczne, wówczas pierwiastek kwadratowy z iloczynu skalarnego jest równoważny długości wektora. Parametry wejściowe mogą być skalarnymi wartościami zmiennoprzecinkowymi lub wektorami zmiennoprzecinkowymi. W przypadku skalarów obliczenia sprowadzają się do pomnożenia ```x``` przez ```y```. + +
+ +### Zobacz też +[cross](/glossary/?lan=pl&search=cross), [Rozdział 07: Kształty](/07/?lan=pl) \ No newline at end of file diff --git a/glossary/sin/README-pl.md b/glossary/sin/README-pl.md index 8fa8e77..fbb2ce7 100644 --- a/glossary/sin/README-pl.md +++ b/glossary/sin/README-pl.md @@ -18,4 +18,4 @@ vec4 sin(vec4 angle)
### Zobacz także -[acos](/glossary/?search=acos), [cos](/glossary/?search=cos), [asin](/glossary/?search=asin), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Rozdział 05: Shaping Functions](/05/) +[acos](/glossary/?lan=pl&search=acos), [cos](/glossary/?lan=pl&search=cos), [asin](/glossary/?lan=pl&search=asin), [tan](/glossary/?lan=pl&search=tan), [atan](/glossary/?lan=pl&search=atan), [Rozdział 05: Shaping Functions](/05/?lan=pl) From 4890cbeb72599c45a33df557e1bf02d59ddf0043 Mon Sep 17 00:00:00 2001 From: Kvmilos Date: Sun, 9 Feb 2025 17:45:53 +0100 Subject: [PATCH 46/47] unified grammar in Polish translations --- glossary/abs/README-pl.md | 2 +- glossary/ceil/README-pl.md | 2 +- glossary/dot/README-pl.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/glossary/abs/README-pl.md b/glossary/abs/README-pl.md index ffcd279..2577a9a 100644 --- a/glossary/abs/README-pl.md +++ b/glossary/abs/README-pl.md @@ -17,5 +17,5 @@ vec4 abs(vec4 x)
-### Zobacz także +### Zobacz też [sign()](/glossary/?lan=pl&search=sign), [min()](/glossary/?lan=pl&search=min), [max()](/glossary/?lan=pl&search=max), [Rozdział 05: Shaping Functions](../05/?lan=pl) diff --git a/glossary/ceil/README-pl.md b/glossary/ceil/README-pl.md index 5d33b4b..b0cce7e 100644 --- a/glossary/ceil/README-pl.md +++ b/glossary/ceil/README-pl.md @@ -1,5 +1,5 @@ ## ceil -Znajdź najbliższą liczbę całkowitą, która jest większa lub równa podanemu parametrowi +Znajduje najbliższą liczbę całkowitą, która jest większa lub równa podanemu parametrowi ### Deklaracja ```glsl diff --git a/glossary/dot/README-pl.md b/glossary/dot/README-pl.md index 976ed28..913bbae 100644 --- a/glossary/dot/README-pl.md +++ b/glossary/dot/README-pl.md @@ -1,5 +1,5 @@ ## dot -Oblicz iloczyn skalarny (dot product) dwóch wektorów +Oblicza iloczyn skalarny (dot product) dwóch wektorów ### Deklaracja ```glsl From a22f0df73cef96874d2bb12bad1d4f05ef0300a4 Mon Sep 17 00:00:00 2001 From: Luke Floden Date: Tue, 4 Mar 2025 11:16:03 -0500 Subject: [PATCH 47/47] fix (typo): Add space between "for" and "[math operations](https://lygia.xyz/math)" --- 05/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05/README.md b/05/README.md index 826e835..06eb6c1 100644 --- a/05/README.md +++ b/05/README.md @@ -125,7 +125,7 @@ Take a look at the following table of equations made by [Kynd](http://www.kynd.i #### For your toolbox -* [LYGIA](https://lygia.xyz/) is a shader library of reusable functions that can be include easily on your projects. It's very granular, designed for reusability, performance and flexibility. And can be easily be added to any projects and frameworks. It's divided in different sections and it have an entire one for[math operations](https://lygia.xyz/math) +* [LYGIA](https://lygia.xyz/) is a shader library of reusable functions that can be include easily on your projects. It's very granular, designed for reusability, performance and flexibility. And can be easily be added to any projects and frameworks. It's divided in different sections and it have an entire one for [math operations](https://lygia.xyz/math) * [GraphToy](http://www.iquilezles.org/apps/graphtoy/): once again [Iñigo Quilez](http://www.iquilezles.org) made a tool to visualize GLSL functions in WebGL.