diff --git a/00/README-ch.md b/00/README-ch.md index 693c88d..31c75f5 100644 --- a/00/README-ch.md +++ b/00/README-ch.md @@ -48,4 +48,4 @@ Fragment shaders(片段着色器)可以让你控制像素在屏幕上的快 * [做一个PDF版的书用于打印](https://thebookofshaders.com/appendix/) -* 用[github仓库](https://github.com/patriciogonzalezvivo/thebookofshaders)来帮助解决问题和分享代码 \ No newline at end of file +* 用[github仓库](https://github.com/patriciogonzalezvivo/thebookofshaders)来帮助解决问题和分享代码 diff --git a/00/README-de.md b/00/README-de.md index 9160d8e..2553603 100644 --- a/00/README-de.md +++ b/00/README-de.md @@ -2,9 +2,9 @@ -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 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. -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 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. ![Gutenbergs Druckerpresse](gutenpress.jpg) @@ -18,7 +18,7 @@ Die folgenden Kapitel wollen Dir zeigen, wie unglaublich schnell und leistungsf 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.) -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. +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. 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. @@ -47,4 +47,3 @@ Alternativ kannst Du auch: - [Eine PDF-Datei mit diesem Buch erzeugen, um es auszudrucken](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. - diff --git a/00/README-fr.md b/00/README-fr.md index 7c12278..a0f0759 100644 --- a/00/README-fr.md +++ b/00/README-fr.md @@ -42,7 +42,7 @@ ce que ce livre n'est pas: * ce *n'est pas* livre sur l'openGL ou le webGL. OpenGL/webGL dépasse de loin le GLSL ou les shaders. si vous voulez en savoir plus, les liens suivants vous aideront [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) (alias "the red book") ou [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) * ce *n'est pas* un livre de maths. Même si le livre contient un certain nombre de notions et d'algorithmes nécessitant des connaissances en algèbre et en trigonométrie, nous ne rentrerons pas dans le détail. Pour toute question relative aux maths, vous pouvez choisir un de ces livres et le garder près de vous : [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) ou [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). - + ## bien démarrer @@ -57,4 +57,3 @@ Cela étant et selon ce que vous voulez faire de ce livre, vous pouvez : - [créer un PDF du livre pour l'imprimer](https://thebookofshaders.com/appendix/) - vous servir du [repo online](https://github.com/patriciogonzalezvivo/thebookofshaders) pour contribuer ou nous aider à débugger. - diff --git a/00/README-it.md b/00/README-it.md index 9ddab8d..a4199e5 100644 --- a/00/README-it.md +++ b/00/README-it.md @@ -47,4 +47,3 @@ In alternativa, in base a ciò di cui avete bisogno, è possibile: - [Fare un PDF del libro da stampare](https://thebookofshaders.com/appendix/) - Utilizzare la [repository on-line](https://github.com/patriciogonzalezvivo/thebookofshaders) per aiutare a risolvere i problemi e per condividere il codice. - diff --git a/00/README-kr.md b/00/README-kr.md index 2ffbe7d..c21f584 100644 --- a/00/README-kr.md +++ b/00/README-kr.md @@ -45,4 +45,3 @@ Fragment shader는 매우 빠른 속도로 스크린에 렌더되는 픽셀들 - [이책의 PDF버젼 만들기](https://thebookofshaders.com/appendix/) - 또는 [온라인 리포](https://github.com/patriciogonzalezvivo/thebookofshaders) 이슈들을 답하거나, 올려주세요. - diff --git a/00/README.md b/00/README.md index 2115a68..1ddc000 100644 --- a/00/README.md +++ b/00/README.md @@ -2,7 +2,7 @@ -The images above were made in different ways. The first one was made by Van Gogh's hand applying layer over layer of paint. It took him hours. The second was produced in seconds by the combination of four matrices of pixels: one for cyan, one for magenta, one for yellow and one for black. The key difference is that the second image is produced in a non-serial way (that means not step-by-step, but all at the same time). +The images above were made in different ways. The first one was made by Van Gogh's hand applying layer over layer of paint. It took him hours. The second was produced in seconds by the combination of four matrices of pixels: one for cyan, one for magenta, one for yellow and one for black. The key difference is that the second image is produced in a non-serial way (that means not step-by-step, but all at the same time). This book is about the revolutionary computational technique, *fragment shaders*, that is taking digitally generated images to the next level. You can think of it as the equivalent of Gutenberg's press for graphics. @@ -45,4 +45,3 @@ Alternatively, based on what you have or what you need from this book you can: - [Make a PDF of the book to print](https://thebookofshaders.com/appendix/) - Use the [on-line repository](https://github.com/patriciogonzalezvivo/thebookofshaders) to help resolve issues and share code. - diff --git a/00/cmyk-halftone.frag b/00/cmyk-halftone.frag index 40d8452..ad83b96 100644 --- a/00/cmyk-halftone.frag +++ b/00/cmyk-halftone.frag @@ -14,7 +14,7 @@ precision mediump float; #define SST 0.888 #define SSQ 0.288 -uniform sampler2D u_tex0; +uniform sampler2D u_tex0; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; @@ -72,7 +72,7 @@ void main() { mat2 mm = rotm(R+D2R(75.0)); mat2 my = rotm(R); mat2 mk = rotm(R+D2R(45.0)); - + float k = halftone(fc,mk).a; vec4 c = cmyki2rgb(ss(vec4( halftone(fc,mc).r, @@ -86,6 +86,6 @@ void main() { st = vec2(st.x,st.y*0.5)*2.0; gl_FragColor = texture2D(u_tex0,st); } - - -} \ No newline at end of file + + +} diff --git a/00/halftone.frag b/00/halftone.frag index 251598e..6f46466 100644 --- a/00/halftone.frag +++ b/00/halftone.frag @@ -2,7 +2,7 @@ precision mediump float; #endif -uniform sampler2D u_tex0; +uniform sampler2D u_tex0; uniform vec2 u_resolution; uniform vec2 u_mouse; @@ -30,7 +30,7 @@ void main () { if (st.x > 0.5) { // Halftone dot matrix shader // @author Tomek Augustyn 2010 - + // Ported from my old PixelBender experiment // https://github.com/og2t/HiSlope/blob/master/src/hislope/pbk/fx/halftone/Halftone.pbk float ratio = u_resolution.y / u_resolution.x; @@ -39,25 +39,25 @@ void main () { vec2 srcCoord = vec2(st.x-0.5, st.y*0.5)*2.0; vec2 rotationCenter = vec2(0.5); vec2 shift = dstCoord - rotationCenter; - + float dotSize = 5.0; float angle = 45.0; - + float rasterPattern = added(shift, sind(angle), cosd(angle), rotationCenter, PI / dotSize * 680.0); vec4 srcPixel = texture2D(u_tex0, srcCoord); - + float avg = 0.2125 * srcPixel.r + 0.7154 * srcPixel.g + 0.0721 * srcPixel.b; float gray = (rasterPattern * threshold + avg - threshold) / (1.0 - threshold); - // uncomment to see how the raster pattern looks + // uncomment to see how the raster pattern looks // gray = rasterPattern; - + gl_FragColor = vec4(gray, gray, gray, 1.0); } else { st = vec2(st.x,st.y*0.5)*2.0; gl_FragColor = texture2D(u_tex0, st); } - - + + } diff --git a/00/index.php b/00/index.php index a6df888..0f2dc41 100644 --- a/00/index.php +++ b/00/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/01/README-ch.md b/01/README-ch.md index d04e8ab..26e2e9e 100644 --- a/01/README-ch.md +++ b/01/README-ch.md @@ -29,7 +29,7 @@ Shaders 也是一系列的指令,但是这些指令会对屏幕上的每个像 ![GPU](04.jpeg) -设想一堆小型微处理器排成一个平面的画面,假设每个像素的数据是乒乓球。14400000个乒乓球可以在一秒内阻塞几乎任何管道。但是一面800x600的管道墙,每秒接收30波480000个像素的信息就可以流畅完成。这在更高的分辨率下也是成立的 —— 并行的处理器越多,可以处理的数据流就越大。 +设想一堆小型微处理器排成一个平面的画面,假设每个像素的数据是乒乓球。14400000个乒乓球可以在一秒内阻塞几乎任何管道。但是一面800x600的管道墙,每秒接收30波480000个像素的信息就可以流畅完成。这在更高的分辨率下也是成立的 —— 并行的处理器越多,可以处理的数据流就越大。 另一个 GPU 的魔法是特殊数学函数可通过硬件加速。非常复杂的数学操作可以直接被微芯片解决,而无须通过软件。这就表示可以有更快的三角和矩阵运算 —— 和电流一样快。 @@ -45,4 +45,4 @@ GLSL 代表 openGL Shading Language,openGL 着色语言,这是你在接下 并且 GPU 会让所有并行的微处理器(管道们)一直处在忙碌状态;只要它们一有空闲就会接到新的信息。一个线程不可能知道它前一刻在做什么。它可能是在画操作系统界面上的一个按钮,然后渲染了游戏中的一部分天空,然后显示了一封 email 中的一些文字。每个线程不仅是“盲视”的,而且还是“无记忆”的。同时,它要求编写一个通用的规则,依据像素的不同位置依次输出不同的结果。这种抽象性,和盲视、无记忆的限制使得 shaders 在程序员新手中不是很受欢迎。 -但是不要担心!在接下来的章节中,我们会一步一步地,由浅入深地学习着色语言。如果你是在用一个靠谱的浏览器阅读这个教程,你会喜欢边读边玩书中的示例的。好了,不要再浪费时间了,赶快去玩起来吧! 点击 **Next >>** 开启 shader 之旅! \ No newline at end of file +但是不要担心!在接下来的章节中,我们会一步一步地,由浅入深地学习着色语言。如果你是在用一个靠谱的浏览器阅读这个教程,你会喜欢边读边玩书中的示例的。好了,不要再浪费时间了,赶快去玩起来吧! 点击 **Next >>** 开启 shader 之旅! diff --git a/01/README-de.md b/01/README-de.md index 1dd2920..27ddc0f 100644 --- a/01/README-de.md +++ b/01/README-de.md @@ -1,7 +1,7 @@ # 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 Grafiken beschrieben. Nun, wie kommen wir darauf? Und vor allem: Was genau soll das sein, ein „Shader“? ![Von Brief-für-Brief zu Seite-für-Seite. Rechts: William Blades (1891), links Rolt-Wheeler (1920).](print.png) @@ -13,9 +13,9 @@ Auch Shader verkörpern eine Abfolge von Operationen, doch hier werden diese Ope ## Warum arbeiten Shader schnell? -Diese Frage beantwortet sich, wenn wir uns das Prinzip der *parallelen Verarbeitung* anschauen. +Diese Frage beantwortet sich, wenn wir uns das Prinzip der *parallelen Verarbeitung* anschauen. -Stelle Dir den Prozessor in Deinem Computer als eine große Pipeline vor und jede zu bearbeitende Aufgabe als etwas, das durch die Pipeline fließt - wie an einem Fließband innerhalb einer Fabrik. Einige Aufgaben sind größer als andere, weshalb ihre Abarbeitung mehr Zeit und mehr Energie in Anspruch nimmt. Wir sagen dann, diese Aufgaben benötigen mehr „Prozessorleistung“. Der Aufbau des Computers zwingt die verschiedenen Aufgaben dazu, eine nach der anderen durch die Pipeline zu strömen. Die nächste Aufgabe ist an der Reihe, sobald die vorangehende Aufgabe erfolgreich abgearbeitet wurde. Moderne Prozessoren verfügen in der Regel über mehrere Kerne (typischerweise zwei, vier oder acht), von denen jeder wie eine Pipeline arbeitet, so dass mehrere Ströme von Aufgaben (engl. „Threads“) gleichzeitig abgearbeitet werden können. +Stelle Dir den Prozessor in Deinem Computer als eine große Pipeline vor und jede zu bearbeitende Aufgabe als etwas, das durch die Pipeline fließt - wie an einem Fließband innerhalb einer Fabrik. Einige Aufgaben sind größer als andere, weshalb ihre Abarbeitung mehr Zeit und mehr Energie in Anspruch nimmt. Wir sagen dann, diese Aufgaben benötigen mehr „Prozessorleistung“. Der Aufbau des Computers zwingt die verschiedenen Aufgaben dazu, eine nach der anderen durch die Pipeline zu strömen. Die nächste Aufgabe ist an der Reihe, sobald die vorangehende Aufgabe erfolgreich abgearbeitet wurde. Moderne Prozessoren verfügen in der Regel über mehrere Kerne (typischerweise zwei, vier oder acht), von denen jeder wie eine Pipeline arbeitet, so dass mehrere Ströme von Aufgaben (engl. „Threads“) gleichzeitig abgearbeitet werden können. ![CPU](00.jpeg) @@ -31,17 +31,17 @@ Hier kommt die gleichzeitige - parallele - Berechnung möglichst vieler Bildpun Stelle Dir eine solche GPU wie ein Feld aus lauter Pipelines vor - eine neben der anderen. Jeder Bildpunkt entspricht einem Tischtennisball, der durch eine solche Pipeline hindurchmuss. 14.400.000 Bälle pro Sekunde sind wahrscheinlich zu viel für jede einzelne noch so dicke Pipeline. Hat man aber ein Feld aus 800 x 600 kleinen Pipelines, muss jede nur 30 Bälle pro Sekunde verarbeiten, damit man eine flüssige Darstellung auf dem Bildschirm erhält. Und das ist durchaus machbar. Gleiches gilt für höhere Auflösungen und größere Bildwiederholraten: Je mehr Pipelines parallel arbeiten, desto mehr Bildpunkte können sie pro Zeiteinheit bewältigen. -Die enorme Leistung einer solchen GPU rührt aber auch aus einer anderen Quelle: Viele für die Grafikberechnung unverzichtbare mathematische Operationen lassen sich direkt in der Hardware, in jeder einzelnen Pipeline, parallel ausführen. Es wird also keine zusätzliche Software benötigt, um diese Berechnungen in mehreren Schritten aus einfachen Grundoperationen zusammenzusetzen. Das gilt beispielsweise für die wichtigen trigonometrischen Funktionen und für Matrizenoperationen. Das bringt die Darstellung zusätzlich auf Trab. +Die enorme Leistung einer solchen GPU rührt aber auch aus einer anderen Quelle: Viele für die Grafikberechnung unverzichtbare mathematische Operationen lassen sich direkt in der Hardware, in jeder einzelnen Pipeline, parallel ausführen. Es wird also keine zusätzliche Software benötigt, um diese Berechnungen in mehreren Schritten aus einfachen Grundoperationen zusammenzusetzen. Das gilt beispielsweise für die wichtigen trigonometrischen Funktionen und für Matrizenoperationen. Das bringt die Darstellung zusätzlich auf Trab. -## Was ist GLSL? +## Was ist GLSL? -GLSL ist die Abkürzung für „OpenGL Shading Language“, einem weit verbreiteten Standard für Shader-Programme, mit dem sich die folgenden Kapitel beschäftigen. Es gibt auch andere Arten von Shadern, je nach Grafikhardware und Betriebssystem. Wir orientieren uns hier an der wichtigen OpenGL-Spezifikation, die von der [Khronos Gruppe](https://www.khronos.org/opengl/) erarbeitet wurde. Wenn man die Geschichte von OpenGL kennt, kann man einige der teilweise etwas merkwürdigen Konstrukte und Konventionen besser verstehen. Allen Interessierten empfehle ich deshalb einen Blick auf [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html). +GLSL ist die Abkürzung für „OpenGL Shading Language“, einem weit verbreiteten Standard für Shader-Programme, mit dem sich die folgenden Kapitel beschäftigen. Es gibt auch andere Arten von Shadern, je nach Grafikhardware und Betriebssystem. Wir orientieren uns hier an der wichtigen OpenGL-Spezifikation, die von der [Khronos Gruppe](https://www.khronos.org/opengl/) erarbeitet wurde. Wenn man die Geschichte von OpenGL kennt, kann man einige der teilweise etwas merkwürdigen Konstrukte und Konventionen besser verstehen. Allen Interessierten empfehle ich deshalb einen Blick auf [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html). ## Warum sind Shader so anspruchsvoll? Mein reicher Onkel Willi aus Amerika sagte früher immer zu mir: „Denk dran, Junge, unglaublich viel Power bedeutet immer auch unglaublich viel Verantwortung“. Dies gilt in gewisser Weise auch für das Feld des „Parallel Computings“. Die enorme Leistungsfähigkeit moderner GPUs erzeugt ihre eigenen Regeln und Abhängigkeiten. Und die wollen beachtet werden, damit wir nicht über das Ziel hinausschießen. -Damit jede Pipeline innerhalb der GPU parallel an ihrer Aufgabe arbeiten kann, muss sie unabhängig von den anderen Pipelines sein. Sie ist quasi blind dafür, was die anderen gerade tun. Dies bringt u.a. die Einschränkung mit sich, dass alle Daten nur in eine Richtung fließen können. Es ist praktisch unmöglich, auf die Ergebnisse einer anderen Pipeline einzugehen, deren Ergebnis abzurufen und damit eine dritte Pipeline zu füttern. +Damit jede Pipeline innerhalb der GPU parallel an ihrer Aufgabe arbeiten kann, muss sie unabhängig von den anderen Pipelines sein. Sie ist quasi blind dafür, was die anderen gerade tun. Dies bringt u.a. die Einschränkung mit sich, dass alle Daten nur in eine Richtung fließen können. Es ist praktisch unmöglich, auf die Ergebnisse einer anderen Pipeline einzugehen, deren Ergebnis abzurufen und damit eine dritte Pipeline zu füttern. Außerdem hält die GPU ihre zahlreichen Mikroprozessoren (Pipelines) ständig beschäftigt. Sobald eine Pipeline mit der Berechnung der Farbe für einen Bildpunkt fertig ist, wird sie auch schon mit dem nächsten Bildpunkt „gefüttert“. Aus Sicht des Shader-Programms gibt es quasi kein Vorher und Nachher, sondern immer nur den aktuell zu berechnenden Bildpunkt. Das Shader-Programm in jeder Pipeline ist also nicht nur blind für alle anderen, sondern auch ohne Erinnerung für das Gewesene. Das ist ein Teil der Herausforderung, die die Entwicklung von Shadern bei Programmieranfängern nicht unbedingt beliebt macht. diff --git a/01/README-it.md b/01/README-it.md index a1d9c14..be7838b 100644 --- a/01/README-it.md +++ b/01/README-it.md @@ -45,4 +45,4 @@ Affinché ogni tubo, o thread, venga eseguito in parallelo, è necessario che si Anche la GPU mantiene costantemente occupati i micro-processore paralleli (i tubi); non appena sono liberi ricevono nuove informazioni da elaborare. E' quindi impossibile per un thread sapere che cosa stava facendo nel momento precedente. Potrebbe disegnare un bottone dell'UI del sistema operativo, subito dopo rendere una porzione di cielo in un videogioco e poi visualizzare il testo di una e-mail. Ogni thread non è solo **cieco ** ma anche **senza memoria**. Oltre all'astrazione necessaria per programmare una funzione generica che cambia il risultato pixel per pixel, a seconda della sua posizione, i vincoli ciechi e senza memoria non rendono gli shaders molto popolari tra i programmatori debuttanti. -Non preoccuparti! Nei capitoli seguenti, impareremo passo-passo a partire dai semplici shaders fino a quelli avanzati. Se stai leggendo questo libro con un navigatore moderno, potrai giocare con gli esempi interattivi. Quindi non aspettare altro tempo e clicca su *Next >>* per iniziare il divertimento! \ No newline at end of file +Non preoccuparti! Nei capitoli seguenti, impareremo passo-passo a partire dai semplici shaders fino a quelli avanzati. Se stai leggendo questo libro con un navigatore moderno, potrai giocare con gli esempi interattivi. Quindi non aspettare altro tempo e clicca su *Next >>* per iniziare il divertimento! diff --git a/01/README-kr.md b/01/README-kr.md index 7107391..d609d3c 100644 --- a/01/README-kr.md +++ b/01/README-kr.md @@ -33,16 +33,16 @@ CPU가 하나의 큰 공장같은 파이프라고 가정하자. 파이프로 들 GPU의 또다른 슈퍼파워중 하나는, 하드웨어지원으로 가속된 수학 함수 연산이다. 즉, 소프트웨어상에서가 아닌, 마이크로칩상에서 바로 연산이 진행된다는 이야기다. 이말은 더 많은 삼각함수연산, 매트릭스연산이 가능하다는 말이다 - 전기가 얼마나 빠르게 흐르냐에 따라. -## GLSL은 무엇인가? +## 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) +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) ## 왜 쉐이더를 사람들이 어렵다고 할까? -2차 세계대전에서 쌀공급으로 유명한 미국의 벤삼촌이 이르길, "큰 힘에는 큰 책임이 따른다"고 했다. 병렬연산또한 이 법칙을 따른다; GPU의 강력한 컴퓨테이션 능력은 이것을 쓰기위해 따라야할 제약과 제한이 있다. +2차 세계대전에서 쌀공급으로 유명한 미국의 벤삼촌이 이르길, "큰 힘에는 큰 책임이 따른다"고 했다. 병렬연산또한 이 법칙을 따른다; GPU의 강력한 컴퓨테이션 능력은 이것을 쓰기위해 따라야할 제약과 제한이 있다. 파이프상에서 병렬처리를 하기위해서는, 각 쓰레드마다, 서로에 대해 철저히 개별적이여야 한다. 쓰레드는 다른 쓰레드에 대해 "실명" 되어 있다고 미국에서는 표현하는데, 서로의 데이터에 대해 엑세스가 없다는 말이다. 그래서 각각의 프로세스들은 서로 데이터를 주고 받고 처리하는것이 불가능하다. 쓰레드끼리 소통하게 하는것은 데이터를 더럽힐수 있다. 또한, GPU는 모든 병렬 마이크로 프로세서들 (파이프들) 을 항시 바쁘게 하고 있다; 이 파이프들은 해당작업이 끝나는 대로 다른 작업을 받아 수행하도록 설계되어 있다. 또한, 각 쓰레드는 이미 수행한 작업에 대한 어떠한 정보도 가질수 없다. 보통 이런 작업들은 운영체제의 UI요소를 그리고 있는것이거나, 게임의 배경화면을 그리거나, 브라우져의 이메일 텍스트를 그리는 것들이다. 각 쓰레드는 서로에게 **실명**되있다고 표현할뿐아니라, **기억이없음** 이라고도 표현하는데, 이것은 이미 수행한 작업에 대한 어떠한 정보도 가지고 있지 않다는 말이다. 바로 이런 점들이 일반적인 프로그래밍 요소와 크게 다른부분이라고 할수 있어서 프로그래밍을 막 접한 이들에게는 어려운 컨셉일수도 있는것이다. -하지만 걱정하지 마시라! 앞으로의 챕터들에서 우리는 간단한 것부터 복잡한 쉐이딩 연산들에 대해 하나씩 짚고 넘어갈 것이다. 만약 당신이 이 책을 근대 브라우져에서 읽오 있다면, 인터엑티브한 예제들로 인해 공부에 도움을 받을것이다. 더이상 지겨운 서론은 짚어 치우고, *Next >>*를 누르고 코드로 넘어가보자! \ No newline at end of file +하지만 걱정하지 마시라! 앞으로의 챕터들에서 우리는 간단한 것부터 복잡한 쉐이딩 연산들에 대해 하나씩 짚고 넘어갈 것이다. 만약 당신이 이 책을 근대 브라우져에서 읽오 있다면, 인터엑티브한 예제들로 인해 공부에 도움을 받을것이다. 더이상 지겨운 서론은 짚어 치우고, *Next >>*를 누르고 코드로 넘어가보자! diff --git a/01/README.md b/01/README.md index aa4e71a..a3f0073 100644 --- a/01/README.md +++ b/01/README.md @@ -1,7 +1,7 @@ # Getting started ## What is a fragment shader? -In the previous chapter we described shaders as the equivalent of the Gutenberg press for graphics. Why? And more importantly: what's a shader? +In the previous chapter we described shaders as the equivalent of the Gutenberg press for graphics. Why? And more importantly: what's a shader? ![From Letter-by-Letter, Right: William Blades (1891). To Page-by-page, Left: Rolt-Wheeler (1920).](print.png) @@ -33,13 +33,13 @@ Picture the tiny microprocessors as a table of pipes, and the data of each pixel Another “super power” of the GPU is special math functions accelerated via hardware, so complicated math operations are resolved directly by the microchips instead of by software. That means extra fast trigonometrical and matrix operations - as fast as electricity can go. -## What is GLSL? +## 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? -As Uncle Ben said “with great power comes great responsibility,” and parallel computation follows this rule; the powerful architectural design of the GPU comes with its own constraints and restrictions. +As Uncle Ben said “with great power comes great responsibility,” and parallel computation follows this rule; the powerful architectural design of the GPU comes with its own constraints and restrictions. In order to run in parallel every pipe, or thread, has to be independent from every other thread. We say the threads are *blind* to what the rest of the threads are doing. This restriction implies that all data must flow in the same direction. So it’s impossible to check the result of another thread, modify the input data, or pass the outcome of a thread into another thread. Allowing thread-to-thread communications puts the integrity of the data at risk. diff --git a/01/index.php b/01/index.php index 1022e00..b7b9033 100644 --- a/01/index.php +++ b/01/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/01/notes.md b/01/notes.md index 8b8353e..dd4fb91 100644 --- a/01/notes.md +++ b/01/notes.md @@ -5,4 +5,4 @@ ### Nicolas B * clearly answer the "what is a fragment shader?" question in some sort of recap paragraph. -* beef up explanations around the compilation step (a brief overview will do). \ No newline at end of file +* beef up explanations around the compilation step (a brief overview will do). diff --git a/02/README-ch.md b/02/README-ch.md index 0db60c4..fe869ab 100644 --- a/02/README-ch.md +++ b/02/README-ch.md @@ -5,7 +5,7 @@ 然而在 GPU 的世界里,第一步就渲染一行文字太难了,所以我们改为选择一个鲜艳的欢迎色,来吧躁起来!
- + 如果你是在线阅读这本书的话,上面的代码都是可以交互的。你可以点击或者改动代码中任何一部分,尽情探索。多亏 GPU 的架构,shader 会**飞速**地编译和更新,这使得你的改动都会立刻出现在你眼前。试试改动第6行的值,看会发生什么。 尽管这几行简单的代码看起来不像有很多内容,我们还是可以据此推测出一些知识点: diff --git a/02/README-de.md b/02/README-de.md index 89d6ff2..58ab981 100644 --- a/02/README-de.md +++ b/02/README-de.md @@ -5,7 +5,7 @@ Beim Erlernen einer neuen Programmiersprache beginnt man häufig mit dem berühm In der Welt der Shader-Programmierung ist die Textausgabe eine zu komplizierte Angelegenheit, um gleich damit zu beginnen. Stattdessen wollen wir eine leuchtende Farbe als Willkommensgruß auf den Bildschirm zaubern.
- + Falls Du dieses Buch in einem Internet-Browser liest, ist der obige Programmcode interaktiv. Du kannst in das Listing hineinklicken und jeden Teil des Programmcodes ändern. Deine Änderungen werden sofort innerhalb der Zeichenfläche sichtbar, weil der Shader-Code automatisch kompiliert und ausgeführt wird. Versuche es doch einfach einmal, indem Du die Zahlenwerte in der *Programmzeile 6* änderst. Obwohl diese wenigen, einfachen Programmzeilen noch nicht nach viel aussehen, können wir daraus bereits einige Erkenntnisse gewinnen: @@ -16,7 +16,7 @@ Obwohl diese wenigen, einfachen Programmzeilen noch nicht nach viel aussehen, k 3. Die stark von C beeinflusste Programmiersprache für Shader verfügt über eingebaute *Variablen* (so wie ```gl_FragColor```), *Funktionen* und *Datentypen*. Im obigen Beispiel sehen wir bereits den Datentyp ```vec4```, der einen vierdimensionalen Vektor aus Fließkommazahlen repräsentiert. Im weiteren Verlauf des Buches werden wir noch die Typen ```vec3``` und ```vec2``` kennen lernen, ebenso die wichtigen Typen ```float```, ```int``` und ```bool```. -4. Wenn wir uns den ```vec4``` Datentyp im obigen Beispiel genau anschauen, können wir bereits erahnen, dass die vier Zahlenwerte für die Farbkanäle Rot, Grün, Blau und Alpha (ein Maß für die Deckkraft) stehen. Außerdem erkennen wir, dass diese Werte offensichtlich normalisiert sind, sich also zwischen ```0.0``` und ```1.0``` bewegen. Später werden wir noch sehen, dass es uns diese Normalisierung vereinfacht, die Inhalte von Variablen auf Farbwerte *abzubilden*. +4. Wenn wir uns den ```vec4``` Datentyp im obigen Beispiel genau anschauen, können wir bereits erahnen, dass die vier Zahlenwerte für die Farbkanäle Rot, Grün, Blau und Alpha (ein Maß für die Deckkraft) stehen. Außerdem erkennen wir, dass diese Werte offensichtlich normalisiert sind, sich also zwischen ```0.0``` und ```1.0``` bewegen. Später werden wir noch sehen, dass es uns diese Normalisierung vereinfacht, die Inhalte von Variablen auf Farbwerte *abzubilden*. 5. Eine weiteres aus C bekanntes Element sind die Präprozessor-Makros, die auch in unserem obigen Beispiel auftauchen. Mit ihrer Hilfe lassen sich Konstanten definieren (```#define```) und konditionale Festlegungen treffen (mit ```#ifdef``` und ```#endif```). Alle diese Makrobefehle beginnen mit einer Raute (```#```). Ihre Auswertung erfolgt als erster Schritt noch vor der eigentlichen Kompilierung des Shaders. Das Ergebnis dieser Auswertung bestimmt jeweils, welche Zeilen und Ausdrücke tatsächlich in den Programmcode einfließen, der anschließend kompiliert wird. In unserem obigen Beispiel wird die *Programmzeile 2* beispielsweise nur dann übernommen, wenn das Symbol ```GL_ES``` definiert ist. Dies ist in der Regel nur in Umgebungen auf mobilen Geräten der Fall, d.h. wenn das obige Programm beispielsweise auf einem Smartphone kompiliert wird, ist die Zeile 2 darin vorhanden und wirkt sich entsprechend aus. Beim Kompilieren auf einem Laptop oder PC taucht die Zeile 2 aber gar nicht auf, weil dort auch das Symbol ```GL_ES``` nicht definiert ist. @@ -50,4 +50,4 @@ vec4 red(){ vec4 color = vec4(vec3(1.0,0.0,1.0),1.0); ``` -Obwohl dieses „Hello world!“-Programm noch nicht so wahnsinnig aufregend daherkommt, ist es doch das simpelste Beispiel aus der Welt der Shader. Wir beeinflussen damit die Farbe aller Bildpunkte innerhalb unserer Zeichenfläche. In den nun folgenden Kapiteln werden wir die Farbe der einzelnen Bildpunkte aufgrund von zwei unterschiedlichen Arten von Eingabewerten steuern: Ihrer Position (d.h. die Lage des zu bearbeitenden Pixels innerhalb der Zeichenfläche) und der Zeit (d.h. der Zeitspanne, die seit dem Laden einer Seite vergangen ist). +Obwohl dieses „Hello world!“-Programm noch nicht so wahnsinnig aufregend daherkommt, ist es doch das simpelste Beispiel aus der Welt der Shader. Wir beeinflussen damit die Farbe aller Bildpunkte innerhalb unserer Zeichenfläche. In den nun folgenden Kapiteln werden wir die Farbe der einzelnen Bildpunkte aufgrund von zwei unterschiedlichen Arten von Eingabewerten steuern: Ihrer Position (d.h. die Lage des zu bearbeitenden Pixels innerhalb der Zeichenfläche) und der Zeit (d.h. der Zeitspanne, die seit dem Laden einer Seite vergangen ist). diff --git a/02/README-it.md b/02/README-it.md index ab6340d..2cb09f5 100644 --- a/02/README-it.md +++ b/02/README-it.md @@ -5,7 +5,7 @@ Di solito l'esempio "Ciao Mondo!" è il primo passo per imparare un nuovo lingua Nel mondo GPU rendere un testo è un esercizio troppo complicato per un primo passo, perciò sceglieremo un colore brillante di benvenuto per mostrare il nostro entusiasmo!
- + Se stai leggendo questo libro in un navigatore, noterai che il precedente blocco di codice è interattivo. Ciò significa che è possibile fare click e modificare qualsiasi parte del codice per capire come funziona. Le modifiche verranno aggiornate immediatamente grazie all'architettura GPU che compila e sostituisce gli shaders *al volo*. Prova per esempio a cambiare i valori della linea 6. Anche se queste semplici righe di codice non sembrano essere molto importanti, possiamo trarre molte informazioni: diff --git a/02/README-kr.md b/02/README-kr.md index af6584d..19c531f 100644 --- a/02/README-kr.md +++ b/02/README-kr.md @@ -5,12 +5,12 @@ GPU-세상에서는 이런 문자열을 출력하는것은 첫번째 발걸음으로 다소 복잡한 경향이 있다. 하여, 우리는 밝은 색하나를 출력하는 것으로 대신해 발걸음을 떼어본다!
- + 이첵을 브라우져에서 읽고 있다면, 위에 구간이 상호작용이 가능하다는것을 알수 있다. 클릭하거나, 코드를 수정하여 결과를 바로 볼수 있다는 것이다. 이런 변화 인풋은 바로 GPU파이프라인으로 주입되어 컴파일되고, *실시간으로* 결과를 바꿔준다. 6번째 줄의 코드를 수정하여 이를 체험해보시라. 매우 간단한 코드지만, 상당히 중요한 내용을 우리는 엿볼수 있는데: -1. 쉐이더 언어는 color값을 리턴하는 ```main``` 함수이고, 이는 C와 형태가 유사하다. +1. 쉐이더 언어는 color값을 리턴하는 ```main``` 함수이고, 이는 C와 형태가 유사하다. 2. 마지막으로 리턴되는 픽셀 색 값은, ```gl_FragColor```라는 전역변수에 대입된다. @@ -50,4 +50,4 @@ vec4 red(){ vec4 color = vec4(vec3(1.0,0.0,1.0),1.0); ``` -이 예제 자체가 그리 흥미롭지는 않지만 매우 중요한 기본 예제중 하나이다 - 캔바스의 모든 색을 같은색으로 바꿔보는 작업. 다음에 오는 챕터에서는 픽셀 색들을 2개의 인풋을 사용하여 바꿔보는 예제를 해볼것이다. (스크린위에 픽셀들의 위치를 이용한) 그리고 시간을 이용해 이들을 바꾸는 작업도 해볼것이다. (페이지가 로드완료된 후로 몇초가 지났는지를 이용한) \ No newline at end of file +이 예제 자체가 그리 흥미롭지는 않지만 매우 중요한 기본 예제중 하나이다 - 캔바스의 모든 색을 같은색으로 바꿔보는 작업. 다음에 오는 챕터에서는 픽셀 색들을 2개의 인풋을 사용하여 바꿔보는 예제를 해볼것이다. (스크린위에 픽셀들의 위치를 이용한) 그리고 시간을 이용해 이들을 바꾸는 작업도 해볼것이다. (페이지가 로드완료된 후로 몇초가 지났는지를 이용한) diff --git a/02/README.md b/02/README.md index 2aa745e..3c1e05b 100644 --- a/02/README.md +++ b/02/README.md @@ -1,11 +1,11 @@ ## Hello World -Usually the "Hello world!" example is the first step to learning a new language. It's a simple one-line program that outputs an enthusiastic welcoming message and declares opportunities ahead. +Usually the "Hello world!" example is the first step to learning a new language. It's a simple one-line program that outputs an enthusiastic welcoming message and declares opportunities ahead. In GPU-land rendering text is an overcomplicated task for a first step, instead we'll choose a bright welcoming color to shout our enthusiasm!
- + If you are reading this book in a browser the previous block of code is interactive. That means you can click and change any part of the code you want to explore. Changes will be updated immediately thanks to the GPU architecture that compiles and replaces shaders *on the fly*. Give it a try by changing the values on line 6. Although these simple lines of code don't look like a lot, we can infer substantial knowledge from them: @@ -16,7 +16,7 @@ Although these simple lines of code don't look like a lot, we can infer substant 3. This C-flavored language has built in *variables* (like ```gl_FragColor```), *functions* and *types*. In this case we've just been introduced to ```vec4``` that stands for a four dimensional vector of floating point precision. Later we will see more types like ```vec3``` and ```vec2``` together with the popular: ```float```, ```int``` and ```bool```. -4. If we look closely to the ```vec4``` type we can infer that the four arguments respond to the RED, GREEN, BLUE and ALPHA channels. Also we can see that these values are *normalized*, which means they go from ```0.0``` to ```1.0```. Later, we will learn how normalizing values makes it easier to *map* values between variables. +4. If we look closely to the ```vec4``` type we can infer that the four arguments respond to the RED, GREEN, BLUE and ALPHA channels. Also we can see that these values are *normalized*, which means they go from ```0.0``` to ```1.0```. Later, we will learn how normalizing values makes it easier to *map* values between variables. 5. Another important *C feature* we can see in this example is the presence of preprocessor macros. Macros are part of a pre-compilation step. With them it is possible to ```#define``` global variables and do some basic conditional operation ( with ```#ifdef``` and ```#endif```). All the macro comands begin with a hashtag (```#```). Pre-compilation happens right before compiling and copies all the calls to ```#defines``` and check ```#ifdef``` (is defined) and ```#ifndef``` (is not defined) conditionals. In our "hello world!" example above, we only insert the line 2 if ```GL_ES``` is defined, which mostly happens when the code is compiled on mobile devices and browsers. @@ -50,4 +50,4 @@ vec4 red(){ vec4 color = vec4(vec3(1.0,0.0,1.0),1.0); ``` -Although this example isn't very exciting, it is the most basic example - we are changing all the pixels inside the canvas to the same exact color. In the following chapter we will see how to change the pixel colors by using two types of input: space (the place of the pixel on the screen) and time (the number of seconds since the page was loaded). +Although this example isn't very exciting, it is the most basic example - we are changing all the pixels inside the canvas to the same exact color. In the following chapter we will see how to change the pixel colors by using two types of input: space (the place of the pixel on the screen) and time (the number of seconds since the page was loaded). diff --git a/02/SUMMARY.md b/02/SUMMARY.md index 4fd29f1..5b81322 100644 --- a/02/SUMMARY.md +++ b/02/SUMMARY.md @@ -1 +1 @@ -Usually the "Hello world!" example is the first step to learning a new language. In GPU-land rendering text is an overcomplicated task for a first step, instead we'll choose a bright welcoming color to shout our enthusiasm! \ No newline at end of file +Usually the "Hello world!" example is the first step to learning a new language. In GPU-land rendering text is an overcomplicated task for a first step, instead we'll choose a bright welcoming color to shout our enthusiasm! diff --git a/02/hello_world.frag b/02/hello_world.frag index 4748df1..a402fdd 100644 --- a/02/hello_world.frag +++ b/02/hello_world.frag @@ -5,7 +5,3 @@ precision mediump float; void main() { gl_FragColor = vec4(1.0,0.0,1.0,1.0); } - - - - diff --git a/02/notes.md b/02/notes.md index 797bba7..e5b54a1 100644 --- a/02/notes.md +++ b/02/notes.md @@ -11,4 +11,4 @@ (float) 1 == 1.0 ``` -* I figured out that vec4() is a vector with 4 values, but perhaps you could make that explicit somewhere. \ No newline at end of file +* I figured out that vec4() is a vector with 4 values, but perhaps you could make that explicit somewhere. diff --git a/03/README-ch.md b/03/README-ch.md index 0d0f311..10d8f6e 100644 --- a/03/README-ch.md +++ b/03/README-ch.md @@ -11,7 +11,7 @@ precision mediump float; uniform vec2 u_resolution; // 画布尺寸(宽,高) uniform vec2 u_mouse; // 鼠标位置(在屏幕上哪个像素) -uniform float u_time; // 时间(加载后的秒数) +uniform float u_time; // 时间(加载后的秒数) ``` 你可以把 uniforms 想象成连通 GPU 和 CPU 的许多小的桥梁。虽然这些 uniforms 的名字千奇百怪,但是在这一系列的例子中我一直有用到:```u_time``` (时间), ```u_resolution``` (画布尺寸)和 ```u_mouse``` (鼠标位置)。按业界传统应在 uniform 值的名字前加 ```u_``` ,这样一看即知是 uniform。尽管如此你也还会见到各种各样的名字。比如[ShaderToy.com](https://www.shadertoy.com/)就用了如下的名字: @@ -58,4 +58,4 @@ GLSL 还有更多惊喜。GPU 的硬件加速支持我们使用角度,三角 * 你可以用 ```u_time``` 和 ```u_mouse``` 来改变颜色的图案吗?不妨琢磨一些有趣的途径。 -经过这些小练习后,你可能会好奇还能用强大的 shader 做什么。接下来的章节你会知道如何把你的 shader 和 three.js,Processing,和 openFrameworks 结合起来。 \ No newline at end of file +经过这些小练习后,你可能会好奇还能用强大的 shader 做什么。接下来的章节你会知道如何把你的 shader 和 three.js,Processing,和 openFrameworks 结合起来。 diff --git a/03/README-de.md b/03/README-de.md index 07223ae..f62636c 100644 --- a/03/README-de.md +++ b/03/README-de.md @@ -1,6 +1,6 @@ ## Uniforms -Wir haben bereits gesehen, wie die GPU eine große Anzahl von parallelen Aufgaben (engl. *Threads*) verwaltet. Jeder Thread übernimmt die Berechnung des Farbwerts für einen Pixel, also für einen kleinen Teil der gesamten Grafik. Obwohl er dabei blind für die anderen Threads ist, muss es einen Weg geben, wie die CPU bestimmte Daten an alle Threads übermitteln kann. Aufgrund der Architektur einer Grafikkarte müssen diese Daten für alle ausgeführten Threads einheitlich (engl. *uniform*) und nur lesbar (engl. *read-only*) sein. Jeder Thread erhält also die gleichen Daten, die er nicht verändern kann. +Wir haben bereits gesehen, wie die GPU eine große Anzahl von parallelen Aufgaben (engl. *Threads*) verwaltet. Jeder Thread übernimmt die Berechnung des Farbwerts für einen Pixel, also für einen kleinen Teil der gesamten Grafik. Obwohl er dabei blind für die anderen Threads ist, muss es einen Weg geben, wie die CPU bestimmte Daten an alle Threads übermitteln kann. Aufgrund der Architektur einer Grafikkarte müssen diese Daten für alle ausgeführten Threads einheitlich (engl. *uniform*) und nur lesbar (engl. *read-only*) sein. Jeder Thread erhält also die gleichen Daten, die er nicht verändern kann. Man bezeichnet diese Daten deshalb als ```uniform```. Es gibt sie in den wichtigsten Datentypen, die GLSL unterstützt: ```float```, ```vec2```, ```vec3```, ```vec4```, ```mat2```, ```mat3```, ```mat4```, ```sampler2D``` und ```samplerCube```. Uniforms werden gemeinsam mit ihrem jeweiligen Datentyp am Anfang eines Shader-Programms definiert, sofern man darauf Bezug nehmen möchte. Dies geschieht in der Regel gleich nachdem man die gewünschte Genauigkeit für alle Fließkommaoperationen in dem Programm festgelegt hat. @@ -48,13 +48,13 @@ In der Welt der Shader-Programmierung haben wir nicht so viele Möglichkeiten zu ![](08.png) -Jetzt ist es an der Zeit für eine kleine Herausforderung in Bezug auf das Verständnis des obigen Programmcodes. +Jetzt ist es an der Zeit für eine kleine Herausforderung in Bezug auf das Verständnis des obigen Programmcodes. * Kannst du ausmachen, wo sich die Koordinate ```(0.0,0.0)``` innerhalb unserer Zeichenfläche befindet? * Und wo liegen wohl die Koordinaten ```(1.0,0.0)```, ```(0.0,1.0)```, ```(0.5,0.5)``` und ```(1.0,1.0)```? Die Farben der jeweiligen Bildpunkte verraten es Dir! -* Gelingt es Dir, die aktuelle Mausposition aus dem Uniform ```u_mouse``` einzubeziehen? Denke daran, dass sich die Angaben in diesem Uniform auf Pixel beziehen und zunächst nicht normalisiert sind. Kannst Du den Programmcode so gestalten, dass die erzeugten Farben auf die Mausbewegung reagieren? +* Gelingt es Dir, die aktuelle Mausposition aus dem Uniform ```u_mouse``` einzubeziehen? Denke daran, dass sich die Angaben in diesem Uniform auf Pixel beziehen und zunächst nicht normalisiert sind. Kannst Du den Programmcode so gestalten, dass die erzeugten Farben auf die Mausbewegung reagieren? * Fällt Dir ein Weg ein, wie man die Farbgestaltung auf interessante Weise durch die Einbeziehung von ```u_time``` und ```u_mouse``` dynamisieren kann? diff --git a/03/README-it.md b/03/README-it.md index dabd918..3b681f0 100644 --- a/03/README-it.md +++ b/03/README-it.md @@ -11,7 +11,7 @@ precision mediump float; uniform vec2 u_resolution; // dimensione del Canvas (larghezza, altezza) uniform vec2 u_mouse; // posizione del mouse (x,y) in pixels -uniform float u_time; // tempo in secondi da quando lo shader è iniziato +uniform float u_time; // tempo in secondi da quando lo shader è iniziato ``` È possibile immaginare gli uniforms come piccoli ponti tra la CPU e la GPU. I nomi variano da applicazione ad applicazione, ma in questa serie di esempi userò: ```u_time``` (tempo in secondi da quando lo shader è iniziato), ```u_resolution``` (la dimensione della finestra in cui lo shader è in corso d'elaborazione) e ```u_mouse``` (la posizione in pixel del mouse all'interno della finestra). Seguirò la convenzione di mettere ```u_``` prima del nome degli uniforms per essere espliciti sulla natura di questa variabile, ma incontrerete varie nomenclature per gli uniforms. Per esempio [ShaderToy.com](https://www.shadertoy.com/) utilizza gli stessi uniforms, ma con i seguenti nomi: @@ -58,4 +58,4 @@ Ora è il momento di mettere in pratica gli insegnamenti che abbiamo imparato. * Sapreste trovare un modo interessante per cambiare questo pattern grafico utilizzando ```u_time``` e le coordinate ```u_mouse```? -Dopo aver fatto questi esercizi, ci si potrebbe chiedere dove si potrebbero provare i nuovi super poteri che gli shader ci hanno dato. Nel prossimo capitolo vedremo come creare i vostri shader in Three.js, Processing e openFrameworks. \ No newline at end of file +Dopo aver fatto questi esercizi, ci si potrebbe chiedere dove si potrebbero provare i nuovi super poteri che gli shader ci hanno dato. Nel prossimo capitolo vedremo come creare i vostri shader in Three.js, Processing e openFrameworks. diff --git a/03/README-kr.md b/03/README-kr.md index e2960a4..6df87c6 100644 --- a/03/README-kr.md +++ b/03/README-kr.md @@ -1,6 +1,6 @@ ## Uniforms -우리는 여태것 GPU가 병렬처리에 왜 유리한지, 또 GPU의 각 Thread가 한 이미지의 각 부분을 어떻게 다루는지 또한 살펴보았다. 병렬처리 Thread들이 서로에 대해 데이터를 공유할수 없더라도, CPU에서 인풋을 받을수 있다. 그리고 이 인풋들은 모든 Thread들에 있어서 일정(*uniform*)하고 *read only*이다. 즉, 읽을순 있어도 변경할수 없다는 뜻이다. +우리는 여태것 GPU가 병렬처리에 왜 유리한지, 또 GPU의 각 Thread가 한 이미지의 각 부분을 어떻게 다루는지 또한 살펴보았다. 병렬처리 Thread들이 서로에 대해 데이터를 공유할수 없더라도, CPU에서 인풋을 받을수 있다. 그리고 이 인풋들은 모든 Thread들에 있어서 일정(*uniform*)하고 *read only*이다. 즉, 읽을순 있어도 변경할수 없다는 뜻이다. 이런 인풋들을 ```uniform```이라고 하고, ```float```, ```vec2```, ```vec3```, ```vec4```, ```mat2```, ```mat3```, ```mat4```, ```sampler2D```, ```samplerCube``` 등의 데이터 타입을 지원한다. 유니폼 값들은 보통 floating pont precision설정이 끝난후 선언된다. @@ -11,7 +11,7 @@ precision mediump float; uniform vec2 u_resolution; // Canvas size (width,height) uniform vec2 u_mouse; // mouse position in screen pixels -uniform float u_time; // Time in seconds since load +uniform float u_time; // Time in seconds since load ``` 유니폼은 CPU와 GPU사이에 다리라고 봐도 좋을것이다. 유니폼 값들의 이름은 구현마다 다 다르지만 여기서는: ```u_time``` (쉐이더 연산이 시작된후부터의 초), ```u_resolution``` (쉐이더가 그려지고 있는 빌보드의 사이즈) and ```u_mouse``` (그려지는 빌보드내에서 마우스의 현재 픽셀 위치값) 등으로 나타내겠다. ```u_``` 를 변수앞에 붙혀서, 유니폼이라고 명시한다는 점도 유의하기 바란다. 더 많은 예제는 [ShaderToy.com](https://www.shadertoy.com/) 에서 찾아볼수 있지만, 변수이름이 약간 다르니 살펴보기 바란다: @@ -39,7 +39,7 @@ GLSL의 재미를 약간 맛볼수 있었다. GPU는 전에도 설명했듯이, ## gl_FragCoord -비슷한 원리로, GLSL은 내장 아웃풋 값들을 가진다. ```vec4 gl_FragColor```, 또한 내장 인풋 값도 있다, *screen fragment*상에서 *pixel*의 위치를 가지고 있는 ```vec4 gl_FragCoord```. ```vec4 gl_FragCoord```로 각 쓰레드가 빌보드의 어느 부분을 작업하고 있는지 알수 있다. 그래서 이값은 ```uniform```값과는 조금다르다. 각 쓰레드마다 값이 다른 *varying*타입이기 때문이다. +비슷한 원리로, GLSL은 내장 아웃풋 값들을 가진다. ```vec4 gl_FragColor```, 또한 내장 인풋 값도 있다, *screen fragment*상에서 *pixel*의 위치를 가지고 있는 ```vec4 gl_FragCoord```. ```vec4 gl_FragCoord```로 각 쓰레드가 빌보드의 어느 부분을 작업하고 있는지 알수 있다. 그래서 이값은 ```uniform```값과는 조금다르다. 각 쓰레드마다 값이 다른 *varying*타입이기 때문이다. In the same way GLSL gives us a default output, ```vec4 gl_FragColor```, it also gives us a default input, ```vec4 gl_FragCoord```, which holds the screen coordinates of the *pixel* or *screen fragment* that the active thread is working on. With ```vec4 gl_FragCoord```, we know where a thread is working inside the billboard. In this case we don't call it ```uniform``` because it will be different from thread to thread, instead ```gl_FragCoord``` is called a *varying*.
@@ -60,4 +60,4 @@ In the same way GLSL gives us a default output, ```vec4 gl_FragColor```, it also * ```u_time```과, ```u_mouse```를 이용해, 색의 패턴을 재밌게 바꾸는 시도도 해보자. -몇번 해보다 보면, 이런 쉐이딩 기술을 어디에 적용할지 의문이 갈것이다. 다음챕터에서, 쉐이딩 기술을 이용하는 라이브러리들에 대해 알아볼것이다. three.js, Processing, openFrameworks와 같은 툴을 이용하여. \ No newline at end of file +몇번 해보다 보면, 이런 쉐이딩 기술을 어디에 적용할지 의문이 갈것이다. 다음챕터에서, 쉐이딩 기술을 이용하는 라이브러리들에 대해 알아볼것이다. three.js, Processing, openFrameworks와 같은 툴을 이용하여. diff --git a/03/README.md b/03/README.md index 301879c..cd22a28 100644 --- a/03/README.md +++ b/03/README.md @@ -1,6 +1,6 @@ ## Uniforms -So far we have seen how the GPU manages large numbers of parallel threads, each one responsible for assigning the color to a fraction of the total image. Although each parallel thread is blind to the others, we need to be able to send some inputs from the CPU to all the threads. Because of the architecture of the graphics card those inputs are going to be equal (*uniform*) to all the threads and necessarily set as *read only*. In other words, each thread receives the same data which it can read but cannot change. +So far we have seen how the GPU manages large numbers of parallel threads, each one responsible for assigning the color to a fraction of the total image. Although each parallel thread is blind to the others, we need to be able to send some inputs from the CPU to all the threads. Because of the architecture of the graphics card those inputs are going to be equal (*uniform*) to all the threads and necessarily set as *read only*. In other words, each thread receives the same data which it can read but cannot change. These inputs are called ```uniform``` and come in most of the supported types: ```float```, ```vec2```, ```vec3```, ```vec4```, ```mat2```, ```mat3```, ```mat4```, ```sampler2D``` and ```samplerCube```. Uniforms are defined with the corresponding type at the top of the shader right after assigning the default floating point precision. @@ -11,7 +11,7 @@ precision mediump float; uniform vec2 u_resolution; // Canvas size (width,height) uniform vec2 u_mouse; // mouse position in screen pixels -uniform float u_time; // Time in seconds since load +uniform float u_time; // Time in seconds since load ``` You can picture the uniforms like little bridges between the CPU and the GPU. The names will vary from implementation to implementation but in this series of examples I’m always passing: ```u_time``` (time in seconds since the shader started), ```u_resolution``` (billboard size where the shader is being drawn) and ```u_mouse``` (mouse position inside the billboard in pixels). I’m following the convention of putting ```u_``` before the uniform name to be explicit about the nature of this variable but you will find all kinds of names for uniforms. For example [ShaderToy.com](https://www.shadertoy.com/) uses the same uniforms but with the following names: @@ -42,7 +42,7 @@ In the same way GLSL gives us a default output, ```vec4 gl_FragColor```, it also
-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 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. @@ -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? diff --git a/03/index.php b/03/index.php index 7b41dc5..79fb6fc 100644 --- a/03/index.php +++ b/03/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/03/notes.md b/03/notes.md index 88a6d4e..e29cd9a 100644 --- a/03/notes.md +++ b/03/notes.md @@ -41,11 +41,11 @@ void main() { // gl_FragCoord.xy = vec2(0.0,0.0); // / / // vec2(500.0,500.0); - + vec2 st = gl_FragCoord.xy/u_resolution; - + // ST -> vec2(0.0,0.0) to vec2(1.0,1.0) - + // RED GREEN BLUE ALPHA gl_FragColor = vec4(st.x, st.y, 0.0, 1.0); } @@ -64,4 +64,3 @@ which holds the screen coordinates of the *pixel* or *screen fragment* that the * I've stressed the fact that gl_FragCoord is implicitly declared so that people don't panic when they don't find it in the new code sample :) also those are reserved names, so I stressed the fact that you can't use them as var names in your custom code. - diff --git a/03/time.frag b/03/time.frag index a6a5fe4..60c2625 100644 --- a/03/time.frag +++ b/03/time.frag @@ -7,5 +7,3 @@ uniform float u_time; void main() { gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0); } - - diff --git a/04/README-ch.md b/04/README-ch.md index cc8ccde..30fa14f 100644 --- a/04/README-ch.md +++ b/04/README-ch.md @@ -42,7 +42,7 @@ function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -66,7 +66,7 @@ renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); @@ -102,7 +102,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -139,12 +139,12 @@ void main() { ### **openFrameworks** 每个人都有自己的舒适区,我的则是[openFrameworks community](http://openframeworks.cc/)。这个 C++ 框架打包了 OpenGL 和其他开源 C++ 库。在很多方面它和 Processing 非常像,但是明显和 C++ 编译器打交道一定比较麻烦。和 Processing 很像地,openFrameworks 会在你的 data 文件夹里寻找 shader 文件,所以不要忘记把你的后缀 ```.frag``` 的文件拷进去,加载的时候记得改名。 - + ```cpp void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); diff --git a/04/README-de.md b/04/README-de.md index c5ed935..d2e8c58 100644 --- a/04/README-de.md +++ b/04/README-de.md @@ -2,7 +2,7 @@ Beim Schreiben dieses Buches und im Rahmen meiner künstlerischen Tätigkeit habe ich eine Sammlung von Tools entwickelt, mit deren Hilfe man Shader programmieren, anzeigen, teilen und kuratieren kann. Dieses Tools laufen auf Linux Desktops, Rechnern mit MacOS, dem [Raspberry Pi](https://www.raspberrypi.org/) und auf Internet-Browsern. Sie sorgen dafür, dass Du Deine Shader dort nutzen kannst, ohne etwas an deren Programmcode verändern zu müssen. -**Anzeige**: Alle Live-Beispiele in diesem Buch werden mit [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) angezeigt. Dieses Tool macht es unglaublich einfach, Shader ohne weitere Umstände im Internet-Browser auszuführen. +**Anzeige**: Alle Live-Beispiele in diesem Buch werden mit [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) angezeigt. Dieses Tool macht es unglaublich einfach, Shader ohne weitere Umstände im Internet-Browser auszuführen. ```html @@ -37,7 +37,7 @@ Wenn Du lieber offline statt online mit [SublimeText](https://www.sublimetext.co Falls Du bereits Erfahrung mit der Programmierung in einer Umgebung wie [Processing](https://processing.org/), [three.js](http://threejs.org/) oder [OpenFrameworks](http://openframeworks.cc/) gesammelt hast, möchtest Du Deine Shader vielleicht in dieser Umgebung ausführen lassen. Die folgenden Codebeispiele zeigen Dir, wie man Shader unter Verwendung der gleichen Uniforms, die wir in diesem Buch verwenden, in diesen Umgebungen ausführen kann. (In der [GitHub-Ablage dieses Kapitels](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) findest Du den gesamten Sourcecode für die Einbindung von Shadern unter den drei genannten Umgebungen.) ### Ausführung unter **three.js** - + Der brillante und äußerst bescheidene Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) hat zusammen mit [Gleichgesinnten](https://github.com/mrdoob/three.js/graphs/contributors) eines der wahrscheinlich populärsten Frameworks für WebGL mit dem Namen [three.js](http://threejs.org/) entwickelt. Du findest dort viele Beispiele, Tutorials und Bücher, die Dir zeigen, wie Du diese JavaScript-Bibliothek zur Erstellung cooler 3D-Grafiken nutzen kannst. Hier folgt ein Beispiel für den HTML- und JS-Code, den Du für Deine ersten Experimente mit Shadern unter *three.js* benötigst. Bitte beachte das Script unter dem HTML-Tag ```id="fragmentShader"```. Dort kannst Du Deine Shader aus dem vorliegenden Buch einfügen. @@ -70,7 +70,7 @@ Hier folgt ein Beispiel für den HTML- und JS-Code, den Du für Deine ersten Exp function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -95,12 +95,12 @@ Hier folgt ein Beispiel für den HTML- und JS-Code, den Du für Deine ersten Exp renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); window.addEventListener( 'resize', onWindowResize, false ); - + document.onmousemove = function(e){ uniforms.u_mouse.value.x = e.pageX uniforms.u_mouse.value.y = e.pageY @@ -136,7 +136,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -173,12 +173,12 @@ Mehr Informationen über den Einsatz von Shadern in Processing findest Du auch i ### In **openFrameworks** Jeder hat einen Platz, an dem er oder sie sich besonders wohl fühlt. Bei mir ist das die [openFrameworks Gemeinschaft](http://openframeworks.cc/). Diese C++-Umgebung ermöglicht die bequeme Einbindung von OpenGL und weiteren Open Source C++-Bibliotheken. In vielerlei Hinsicht ähnelt sie der Arbeit mit Processing, nur dass man es hier mit C++ und C++-Compilern zu tun hat. Genau wie Processing sucht *openFrameworks* nach Deinen Shader-Dateien im ```DATA```-Unterverzeichnis. Deshalb vergiss nicht, Deine ```.frag```-Dateien dorthin zu kopieren und den Dateinamen entsprechend anzupassen, wenn Du diese Dateien ausführen willst. - + ```cpp void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); diff --git a/04/README-fr.md b/04/README-fr.md index 52afb56..4ccb347 100644 --- a/04/README-fr.md +++ b/04/README-fr.md @@ -91,7 +91,7 @@ Notez bien la balise de script appelée ```id="fragmentShader"```, c'est là qu' function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -116,12 +116,12 @@ Notez bien la balise de script appelée ```id="fragmentShader"```, c'est là qu' renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); window.addEventListener( 'resize', onWindowResize, false ); - + document.onmousemove = function(e){ uniforms.u_mouse.value.x = e.pageX uniforms.u_mouse.value.y = e.pageY @@ -162,7 +162,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -203,12 +203,12 @@ Chacun a sa zone de confort, pour moi, ça reste [la communité openFrameworks]( Ce framework C++ intègre OpenGL et d'autres librairies C++ open source. C'est très proche de Processing à ceci près que c'est un langage compilé et qu'il vaut donc mieux être habitué aux compilateurs C++. Comme Processing, openFrameworks va chercher le fichier du shader dans la dossier data, donc n'oubliez pas de créer un fichier ```.frag```, d'y coller le contenu du shader et de spécifier le nom de ce fichier dans votre programme OF. - + ```cpp void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); diff --git a/04/README-it.md b/04/README-it.md index 6c79a1e..928a80d 100644 --- a/04/README-it.md +++ b/04/README-it.md @@ -70,7 +70,7 @@ Di seguito è riportato un esempio di codice HTML e JS per iniziare con gli shad function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -95,12 +95,12 @@ Di seguito è riportato un esempio di codice HTML e JS per iniziare con gli shad renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); window.addEventListener( 'resize', onWindowResize, false ); - + document.onmousemove = function(e){ uniforms.u_mouse.value.x = e.pageX uniforms.u_mouse.value.y = e.pageY @@ -136,7 +136,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -173,12 +173,12 @@ Per ulteriori informazioni sugli shader in Processing controllate questo [tutori ### In **openFrameworks** Ognuno ha un luogo in cui sentirsi a proprio agio e, nel mio caso, è ancora la [comunità di openFrameworks](http://openframeworks.cc/). Questo framework C++ integra OpenGL e altre librerie C++ open source. Per molti aspetti è molto simile a Processing, ma con le ovvie complicazioni dovute ai compilatori C++. Allo stesso modo di Processing, openFrameworks cercherà i tuoi file shader nella cartella dati, quindi non dimenticate di copiare i file ```.frag``` che si desiderano utilizzare e modificate il nome quando li si carica. - + ```cpp void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); @@ -187,4 +187,4 @@ void ofApp::draw(){ } ``` -Per ulteriori informazioni sugli shader in openFrameworks consultate questo [ottimo tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) fatto da [Joshua Noble](http://thefactoryfactory.com/). \ No newline at end of file +Per ulteriori informazioni sugli shader in openFrameworks consultate questo [ottimo tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) fatto da [Joshua Noble](http://thefactoryfactory.com/). diff --git a/04/README-kr.md b/04/README-kr.md index 18fb064..5e2c453 100644 --- a/04/README-kr.md +++ b/04/README-kr.md @@ -7,7 +7,7 @@ **Note 2**: 만약 WebGL에서 쉐이더를 구동하고, 다른 프레임워크를 따로 쓰고 싶지 않다면, [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas)를 이용해서 할수 있다. 이 웹 툴은 이 책에 최적화 되어 있고, 실제로 저자가 프로젝트마다 사용하는 툴이기도 하다. ### **Three.js** 에서 - + Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) 가 다른 참여자[참여자](https://github.com/mrdoob/three.js/graphs/contributors)들과 개발한 WebGL을 이용한 프레임 워크인 [Three.js](http://threejs.org/). 많은 예제와, 튜토리얼, 책들이 존재하고, 이를 이용해 여러 3D graphics데모를 만들어 볼수 있다. 아래는 HTML과 JS를 이용해 three.js를 구동하는 예제이다. ```id="fragmentShader"```부분을 보면, 쉐이더가 어디에서 적용되는지 볼수 있다. @@ -40,7 +40,7 @@ Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) 가 다른 참여자 function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -64,7 +64,7 @@ Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) 가 다른 참여자 renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); @@ -100,7 +100,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -141,7 +141,7 @@ void main() { void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); diff --git a/04/README.md b/04/README.md index 5205748..a0ccde5 100644 --- a/04/README.md +++ b/04/README.md @@ -2,7 +2,7 @@ As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. This tools works consistently across Linux Desktops, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) and browsers without the need of changing your code. -**Display**: all live examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredible easy. +**Display**: all live examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredible easy. ```html @@ -37,8 +37,8 @@ If you prefer to work offline using [SublimeText](https://www.sublimetext.com/) In case you already have experience programming in a framework like: [Processing](https://processing.org/), [Three.js](http://threejs.org/) or [OpenFrameworks](http://openframeworks.cc/), you're probably excited to try shaders on this platforms you feel comfortable with. The following are examples of how to set shaders in some popular frameworks with the same uniforms that we are going to use throughout this book. (In the [GitHub repository for this chapter](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), you'll find the full source code for these three frameworks.) ### In **Three.js** - -The brilliant and very humble Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) has been developing along with other [contributors](https://github.com/mrdoob/three.js/graphs/contributors) probably one of the most famous frameworks for WebGL, called [Three.js](http://threejs.org/). You will find a lot of examples, tutorials and books that teach you how to use this JavaScript library to make cool 3D graphics. + +The brilliant and very humble Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) has been developing along with other [contributors](https://github.com/mrdoob/three.js/graphs/contributors) probably one of the most famous frameworks for WebGL, called [Three.js](http://threejs.org/). You will find a lot of examples, tutorials and books that teach you how to use this JavaScript library to make cool 3D graphics. Below is an example of the HTML and JS you need to get started with shaders in three.js. Pay attention to the ```id="fragmentShader"``` script, here is where you can copy the shaders you find in this book. @@ -70,7 +70,7 @@ Below is an example of the HTML and JS you need to get started with shaders in t function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -95,12 +95,12 @@ Below is an example of the HTML and JS you need to get started with shaders in t renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); window.addEventListener( 'resize', onWindowResize, false ); - + document.onmousemove = function(e){ uniforms.u_mouse.value.x = e.pageX uniforms.u_mouse.value.y = e.pageY @@ -136,7 +136,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + shader = loadShader("shader.frag"); } @@ -173,12 +173,12 @@ For more information about shaders in Processing check out this [tutorial](https ### In **openFrameworks** Everybody has a place where they feel comfortable, in my case, that’s still the [openFrameworks community](http://openframeworks.cc/). This C++ framework wraps around OpenGL and other open source C++ libraries. In many ways it's very similar to Processing, but with the obvious complications of dealing with C++ compilers. In the same way as Processing, openFrameworks will search for your shader files in the data folder, so don’t forget to copy the ```.frag``` files you want to use and change the name when you load them. - + ```cpp void ofApp::draw(){ ofShader shader; shader.load("","shader.frag"); - + shader.begin(); shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); diff --git a/04/index.php b/04/index.php index 4eb3d3e..9c27b1b 100644 --- a/04/index.php +++ b/04/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/04/openFrameworks/bin/data/shader.frag b/04/openFrameworks/bin/data/shader.frag index f2abc59..f90dad8 100644 --- a/04/openFrameworks/bin/data/shader.frag +++ b/04/openFrameworks/bin/data/shader.frag @@ -12,4 +12,4 @@ uniform float u_time; void main() { vec2 st = gl_FragCoord.st/u_resolution; gl_FragColor = vec4(st.x,st.y,0.0,1.0); -} \ No newline at end of file +} diff --git a/04/openFrameworks/src/ofApp.cpp b/04/openFrameworks/src/ofApp.cpp index 79244e6..47755ab 100644 --- a/04/openFrameworks/src/ofApp.cpp +++ b/04/openFrameworks/src/ofApp.cpp @@ -4,7 +4,7 @@ //-------------------------------------------------------------- void ofApp::setup(){ - + // Load and compile the shader // shader.load("","shader.frag"); @@ -12,30 +12,30 @@ void ofApp::setup(){ //-------------------------------------------------------------- void ofApp::update(){ - + } //-------------------------------------------------------------- void ofApp::draw(){ - + // Replace the pipeline with our shader shader.begin(); - + // Send uniforms shader.setUniform1f("u_time", ofGetElapsedTimef()); shader.setUniform2f("u_mouse", mouseX, mouseY); shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); - + // make a billboard ofRect(0,0,ofGetWidth(), ofGetHeight()); - + // Default shader pipeline shader.end(); } //-------------------------------------------------------------- void ofApp::keyPressed(int key){ - + // Reload everytime you press a key // shader.load("","shader.frag"); @@ -77,6 +77,6 @@ void ofApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- -void ofApp::dragEvent(ofDragInfo dragInfo){ +void ofApp::dragEvent(ofDragInfo dragInfo){ } diff --git a/04/openFrameworks/src/ofApp.h b/04/openFrameworks/src/ofApp.h index 906784a..e7c50f0 100644 --- a/04/openFrameworks/src/ofApp.h +++ b/04/openFrameworks/src/ofApp.h @@ -19,6 +19,6 @@ public: void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); - + ofShader shader; }; diff --git a/04/processing/data/shader.frag b/04/processing/data/shader.frag index 9fa9bcb..0c2e773 100644 --- a/04/processing/data/shader.frag +++ b/04/processing/data/shader.frag @@ -14,4 +14,4 @@ uniform float u_time; void main() { vec2 st = gl_FragCoord.st/u_resolution; gl_FragColor = vec4(st.x,st.y,0.0,1.0); -} \ No newline at end of file +} diff --git a/04/processing/processing.pde b/04/processing/processing.pde index d7b836a..eedb762 100644 --- a/04/processing/processing.pde +++ b/04/processing/processing.pde @@ -5,7 +5,7 @@ PShader shader; void setup() { size(640, 360, P2D); noStroke(); - + // Load and compile shader shader = loadShader("shader.frag"); } @@ -15,10 +15,10 @@ 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); - + // Replace the default pipeline programs with our shader shader(shader); - + // Draw a billboard rect(0,0,width,height); } diff --git a/04/three_js/index.html b/04/three_js/index.html index 0ebccc2..03ee6b6 100644 --- a/04/three_js/index.html +++ b/04/three_js/index.html @@ -38,7 +38,7 @@ function init() { container = document.getElementById( 'container' ); - + camera = new THREE.Camera(); camera.position.z = 1; @@ -63,7 +63,7 @@ renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); - + container.appendChild( renderer.domElement ); onWindowResize(); @@ -88,4 +88,4 @@ renderer.render( scene, camera ); } - \ No newline at end of file + diff --git a/05/README-ch.md b/05/README-ch.md index d1466eb..237b840 100644 --- a/05/README-ch.md +++ b/05/README-ch.md @@ -22,7 +22,7 @@ [```pow()```](../glossary/?search=pow) (求x的y次幂)是 GLSL 的一个原生函数,GLSL 有很多原生函数。大多数原生函数都是硬件加速的,也就是说如果你正确使用这些函数,你的代码就会跑得更快。 换掉第 19 行的幂函数,试试看[```exp()```](../glossary/?search=exp)(以自然常数e为底的指数函数),[```log()```](../glossary/?search=log)(对数函数) 和 [```sqrt()```](../glossary/?search=sqrt)(平方根函数)。当你用 Pi 来玩的时候有些方程会变得更有趣。在第 5 行我定义了一个宏,使得每当程序调用 ```PI``` 的时候就用 ```3.14159265359``` 来替换它。 - + ### Step 和 Smoothstep GLSL 还有一些独特的原生插值函数可以被硬件加速。 diff --git a/05/README-de.md b/05/README-de.md index 1df45f2..ffd61f2 100644 --- a/05/README-de.md +++ b/05/README-de.md @@ -21,30 +21,30 @@ Die hier genutzte Eins-zu-Eins-Abbildung zwischen *x* und *y* (in diesem Fall al Interessant, nicht wahr? Versuche einfach einmal, in der *Zeile 22* andere Exponenten wie beispielsweise ```20.0```, ```2.0```, ```1.0```, ```0.0```, ```0.2``` und ```0.02``` einzusetzen. Das Verständnis zwischen dem Exponenten und den daraus resultierenden Werten wird Dir sicher weiterhelfen. Schließlich ist es der geschickte Einsatz dieser und anderer mathematischer Funktionen, die Dir bei der Shader-Programmierung unglaubliche Möglichkeiten eröffnen. -[```pow()```](../glossary/?search=pow) ist eine eingebaute mathematische Funktion von GLSL. Daneben gibt es noch viele weitere. Die meisten davon können sehr schnell in der Hardware der Grafikkarte ausgeführt werden. Ihr geschickter Einsatz beschleunigt deshalb die Ausführung Deiner Shader. +[```pow()```](../glossary/?search=pow) ist eine eingebaute mathematische Funktion von GLSL. Daneben gibt es noch viele weitere. Die meisten davon können sehr schnell in der Hardware der Grafikkarte ausgeführt werden. Ihr geschickter Einsatz beschleunigt deshalb die Ausführung Deiner Shader. Ersetze die Funktion *pow* in der *Zeile 22* durch eine andere Funktion und beobachte das Resultat. Probiere zum Beispiel die folgenden Funktionen aus: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) und [```sqrt()```](../glossary/?search=sqrt). Einige dieser Funktionen erzeugen interessantere Ergebnisse, wenn man sie in Verbindung mit einem Vielfachen oder einem Bruchteil der Kreiszahl *pi* nutzt. In der *Programmzeile 8* findest Du deshalb ein Makro, dass das Symbol ```PI``` innerhalb des Programmcodes durch den zugehörigen Wert ```3.14159265359``` ersetzt. - + ### Step und Smoothstep -GLSL bringt auch einige einzigartige Interpolationsfunktionen mit, die durch die Hardware beschleunigt werden. +GLSL bringt auch einige einzigartige Interpolationsfunktionen mit, die durch die Hardware beschleunigt werden. -Die Interpolationsfunktion [```step()```](../glossary/?search=step) nimmt zwei Argumente entgegen: Das erste verkörpert den Schwellenwert, während das zweite Argument den Wert darstellt, der mit diesem Schwellenwert verglichen werden soll. Liegt dieser Wert unterhalb des Schwellenwerts, liefert die Funktion ```0.0``` zurück, bei jedem Wert größer oder gleich dem Schwellenwert hingegen ```1.0```. +Die Interpolationsfunktion [```step()```](../glossary/?search=step) nimmt zwei Argumente entgegen: Das erste verkörpert den Schwellenwert, während das zweite Argument den Wert darstellt, der mit diesem Schwellenwert verglichen werden soll. Liegt dieser Wert unterhalb des Schwellenwerts, liefert die Funktion ```0.0``` zurück, bei jedem Wert größer oder gleich dem Schwellenwert hingegen ```1.0```. -Ändere im folgenden Programmcode doch einfach einmal den Schwellenwert in *Zeile 20* und beobachte, was dann passiert. +Ändere im folgenden Programmcode doch einfach einmal den Schwellenwert in *Zeile 20* und beobachte, was dann passiert.
-Die zweite eingebaute Interpolationsfunktion trägt den Namen [```smoothstep()```](../glossary/?search=smoothstep). Sie interpoliert einen Wert, sofern sich dieser innerhalb eines angegebenen Wertbereichs befindet. Die ersten zwei Argumente stellen dabei die untere und die obere Schwelle dieses Wertebereichs dar, während das dritte Argument den zu interpolierenden Wert verkörpert. +Die zweite eingebaute Interpolationsfunktion trägt den Namen [```smoothstep()```](../glossary/?search=smoothstep). Sie interpoliert einen Wert, sofern sich dieser innerhalb eines angegebenen Wertbereichs befindet. Die ersten zwei Argumente stellen dabei die untere und die obere Schwelle dieses Wertebereichs dar, während das dritte Argument den zu interpolierenden Wert verkörpert. -Die Funktion liefert ```0.0``` zurück, wenn der zu interpolierende Wert unterhalb des genannten Schwellenwerts liegt, also kleiner als das erste Argument ist. Analog dazu liefert sie ```1.0``` zurück, wenn der zu interpolierende Wert größer als der obere Schwellenwert +Die Funktion liefert ```0.0``` zurück, wenn der zu interpolierende Wert unterhalb des genannten Schwellenwerts liegt, also kleiner als das erste Argument ist. Analog dazu liefert sie ```1.0``` zurück, wenn der zu interpolierende Wert größer als der obere Schwellenwert ist. Befindet sich der zu interpolierende Wert jedoch innerhalb der gegebenen Spanne, wird ein Wert zwischen ```0.0``` und ```1.0``` zurückgeliefert, je nachdem wie nahe sich der Wert am oberen oder unteren Ende der Spanne befindet. Genau in der Mitte lautet das Ergebnis ```0.5```. Wie das folgende Programm zeigt, ist das Ergebnis jedoch nicht vollständig linear, sondern am oberen und unteren Ende des Wertebereichs etwas „abgerundet“. Dadurch wird in den Randbereichen bewusst ein etwas weicherer Übergang erzielt, falls sich weitere interpolierte Werte anschließen.
-Im obigen Beispiel nutzen wir die ```smoothstep()```-Funktion innerhalb der ```plot()```-Funktion, um die grüne Linie zu erzeugen, die die Ergebnisse aus der Y-Berechnung in *Zeile 20* darstellt. Siehst Du, wie diese grüne Linie nach oben und unten jeweils ein wenig ausfedert und sanft in den Hintergrund übergeht? Das erreichen wir, indem wir in *Zeile 12 und 13* zwei Aufrufe von [```smoothstep()```](../glossary/?search=smoothstep) miteinander verbinden. Schau Dir die folgende Berechnung an und setze sie in die *Zeile 20* ein. +Im obigen Beispiel nutzen wir die ```smoothstep()```-Funktion innerhalb der ```plot()```-Funktion, um die grüne Linie zu erzeugen, die die Ergebnisse aus der Y-Berechnung in *Zeile 20* darstellt. Siehst Du, wie diese grüne Linie nach oben und unten jeweils ein wenig ausfedert und sanft in den Hintergrund übergeht? Das erreichen wir, indem wir in *Zeile 12 und 13* zwei Aufrufe von [```smoothstep()```](../glossary/?search=smoothstep) miteinander verbinden. Schau Dir die folgende Berechnung an und setze sie in die *Zeile 20* ein. ```glsl float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x); @@ -65,7 +65,7 @@ Es ist nicht ganz leicht, alle Zusammenhänge zwischen trigonometrischen Funktio
-Schau Dir die Sinuswelle genau an und beobachte, wie der daraus abgeleitete Wert für die Y-Ordinate auf dem Einheitskreis sanft zwischen ```+1``` und ```-1``` oszilliert. Und mit der Cosinuswelle erzeugen wir die zugehörige X-Ordinate. +Schau Dir die Sinuswelle genau an und beobachte, wie der daraus abgeleitete Wert für die Y-Ordinate auf dem Einheitskreis sanft zwischen ```+1``` und ```-1``` oszilliert. Und mit der Cosinuswelle erzeugen wir die zugehörige X-Ordinate. Wie wir in dem zeitbasierten Beispiel im vorangegangenen Kapitel gesehen haben, lässt sich dieses rhythmische Verhalten von [```sin()```](../glossary/?search=sin) gut nutzen, um bestimmte Werte und Eigenschaften zu animieren. Wenn Du diesen Text in einem Internet-Browser liest, wirst du feststellen, dass Du die obige Formel *y=sin(x);* editieren kannst, um zu sehen, wie sich die Funktionskurve dadurch ändert. (Hinweis: Bitte nicht das Semikolon am Ende der Zeile vergessen, sonst gibt es einen Syntaxfehler.) @@ -77,7 +77,7 @@ Probiere die folgenden Übungen aus und beobachte, was daraufhin geschieht: * Multipliziere die Zeit (```u_time```) mit *x*, bevor Du daraus den ```sin``` berechnest. Du wirst sehen, wie die einzelnen Wellen so weit zusammengedrückt werden, dass das Ergebnis wie ein unidentifizierbares Rauschen wirkt. -* Addiere den Wert ```1.0``` zum Ergebnis von [```sin(x)```](../glossary/?search=sin) hinzu und beobachte, wie sich die Welle dadurch nach oben verschiebt und jeweils zwischen den Werten von ```0.0``` und ```2.0``` oszilliert. +* Addiere den Wert ```1.0``` zum Ergebnis von [```sin(x)```](../glossary/?search=sin) hinzu und beobachte, wie sich die Welle dadurch nach oben verschiebt und jeweils zwischen den Werten von ```0.0``` und ```2.0``` oszilliert. * Multipliziere [```sin(x)```](../glossary/?search=sin) mit ```2.0```. Du wirst feststellen, dass sich die Amplitude der Schwingung (die Minimal- und Maximalwerte) verdoppelt. @@ -105,7 +105,7 @@ Am Ende der letzten Übung haben wir einige neue Funktionen eingeführt. Jetzt i ### Fortgeschrittene formgebende Funktionen -[Golan Levin](http://www.flong.com/) hat eine großartige Dokumentation über komplexe formgebende Funktionen verfasst, die für unsere Zwecke extrem hilfreich ist. Indem Du einen Teil dieser Funktionen nach GLSL portierst, schaffst Du Dir eine wertvolle Sammlung an Codeschnipseln. +[Golan Levin](http://www.flong.com/) hat eine großartige Dokumentation über komplexe formgebende Funktionen verfasst, die für unsere Zwecke extrem hilfreich ist. Indem Du einen Teil dieser Funktionen nach GLSL portierst, schaffst Du Dir eine wertvolle Sammlung an Codeschnipseln. * [Polynomische formgebende Funktionen: www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/) @@ -117,7 +117,7 @@ Am Ende der letzten Übung haben wir einige neue Funktionen eingeführt. Jetzt i
-Genau wie Küchenchefs Gewürze und exotische Zutaten sammeln, entwickeln Digitalkünstler und kreative Entwickler häufig eine Liebe für bestimmte formgebenden Funktionen. +Genau wie Küchenchefs Gewürze und exotische Zutaten sammeln, entwickeln Digitalkünstler und kreative Entwickler häufig eine Liebe für bestimmte formgebenden Funktionen. [Inigo Quiles](http://www.iquilezles.org/) stellt eine großartige Auswahl an [nützlichen Funktionen](http://www.iquilezles.org/www/articles/functions/functions.htm) vor. Wenn Du [diesen Artikel](http://www.iquilezles.org/www/articles/functions/functions.htm) gelesen hast, dann werfe einen Blick auf die folgenden Übertragungen dieser Funktionen nach GLSL. Beobachte aufmerksam die kleinen, aber erforderlichen Anpassungen wie etwa den Punkt (".") bei Fließkommazahlen und die Umsetzung der Funktionsnamen von C auf GLSL; so heißt es in GLSL beispielsweise ```pow()``` statt ```powf()``` wie in C: diff --git a/05/README-it.md b/05/README-it.md index 6c718b6..0974d9e 100644 --- a/05/README-it.md +++ b/05/README-it.md @@ -9,7 +9,7 @@ La seguente struttura di codice sarà la nostra recinzione. In questa visualizzi
-**Nota veloce**: il costruttore di tipo ```vec3``` "capisce" che vuoi assegnare i tre canali di colori allo stesso valore, mentre ```vec4``` capisce che vuoi costruire un vettore a quattro dimensioni con tre unidimensionali più un quarto valore (in questo caso il valore che controlla l’alfa o l’opacità). Guarda, ad esempio, le righe 20 e 26 qui sopra. +**Nota veloce**: il costruttore di tipo ```vec3``` "capisce" che vuoi assegnare i tre canali di colori allo stesso valore, mentre ```vec4``` capisce che vuoi costruire un vettore a quattro dimensioni con tre unidimensionali più un quarto valore (in questo caso il valore che controlla l’alfa o l’opacità). Guarda, ad esempio, le righe 20 e 26 qui sopra. Questo codice è il tuo recinto; è importante osservarlo e capirlo. Tornerai spesso in questo spazio tra *0.0* e *1.0*. Imparerai l’arte di combinare e modellare questa linea. @@ -22,7 +22,7 @@ Interessante, vero? Alla riga 22 prova esponenti diversi, per esempio: 20.0, 2.0 [```pow()```](../glossary/?search=pow) è una funzione nativa il GLSL e ce ne sono molte altre. La maggior parte di queste sono accelerate al livello dell’hardware; ciò significa che se esse sono usate in modo appropriato e con discrezione, renderanno il tuo codice molto più veloce. Sostituisci la funzione alla riga 22. Provane altre, come: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) e [```sqrt()```](../glossary/?search=sqrt). Alcune di queste funzioni sono più interessanti quando le si utilizza con PI. Puoi vedere alla riga 8, che ho definito un macro che sostituisce qualsiasi chiamata a ```PI``` con valore ```3.14159265359```. - + ### Step e Smoothstep GLSL ha anche alcune funzioni interpolanti native uniche che sono accelerate dall’hardware. @@ -84,7 +84,7 @@ AAl termine dell’ultimo esercizio abbiamo presentato alcune nuove funzioni. È
-또 하나의 잘 알려진 함수중 하나는 [```smoothstep()```](../glossary/?search=smoothstep)이다. 두값의 레인지를 주고, 그 사이의 값으로 보간시켜주는 방법이다. 처음 두개의 인자는 레인지의 시작점과 끝점이고, 세번째 인자는 두 점사이에서 보간되고 리턴되는 값이다. +또 하나의 잘 알려진 함수중 하나는 [```smoothstep()```](../glossary/?search=smoothstep)이다. 두값의 레인지를 주고, 그 사이의 값으로 보간시켜주는 방법이다. 처음 두개의 인자는 레인지의 시작점과 끝점이고, 세번째 인자는 두 점사이에서 보간되고 리턴되는 값이다.
@@ -94,7 +94,7 @@ GLSL에는 하드웨어 가속화된 내장 보간법 함수들이 존재한다. ### 고급 쉐이핑 함수들 -[Golan Levin](http://www.flong.com/) 는 제법 복잡하지만 굉장히 유용한 쉐이핑 함수들을 잘 정리해 두었다. 이들을 GLSL로 포팅하는것또한 굉장히 유용한 공부방법일 것이다. 자신만의 쉐이핑 펑션 라이브러리를 개설해보자. +[Golan Levin](http://www.flong.com/) 는 제법 복잡하지만 굉장히 유용한 쉐이핑 함수들을 잘 정리해 두었다. 이들을 GLSL로 포팅하는것또한 굉장히 유용한 공부방법일 것이다. 자신만의 쉐이핑 펑션 라이브러리를 개설해보자. * [Polynomial Shaping Functions: www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/) @@ -106,7 +106,7 @@ GLSL에는 하드웨어 가속화된 내장 보간법 함수들이 존재한다. 요리사가 자신만의 요리재료와 소스 노하우를 모으듯, digital artist들이나, creative coder들 역시 그들만의 쉐이핑 펑션을 만드는 버릇을 가져야 할것이다. -[Iñigo Quiles](http://www .iquilezles.org/)가 가지고 있는 [useful functions](http://www.iquilezles.org/www/articles/functions/functions.htm)정리는 매우 유용하다. [이 글](http://www.iquilezles.org/www/articles/functions/functions.htm)을 읽고, GLSL로 번역해보는 작업도 해볼수 있다. 조심해야 될 점들은, "."(점)을 실수 뒤에 꼭 넣어야 한다는 점이다. 함수의 이름이 ```powf()``` 에서 ```pow()```등으로 바뀌어 구현되는 점등이다. +[Iñigo Quiles](http://www .iquilezles.org/)가 가지고 있는 [useful functions](http://www.iquilezles.org/www/articles/functions/functions.htm)정리는 매우 유용하다. [이 글](http://www.iquilezles.org/www/articles/functions/functions.htm)을 읽고, GLSL로 번역해보는 작업도 해볼수 있다. 조심해야 될 점들은, "."(점)을 실수 뒤에 꼭 넣어야 한다는 점이다. 함수의 이름이 ```powf()``` 에서 ```pow()```등으로 바뀌어 구현되는 점등이다. * [Impulse](../edit.php#05/impulse.frag) * [Cubic Pulse](../edit.php#05/cubicpulse.frag) diff --git a/05/README.md b/05/README.md index edad9b8..0315e4f 100644 --- a/05/README.md +++ b/05/README.md @@ -1,7 +1,7 @@ # Algorithmic drawing ## Shaping functions -This chapter could be named "Mr. Miyagi's fence lesson." Previously, we mapped the normalized position of *x* and *y* to the *red* and *green* channels. Essentially we made a function that takes a two dimensional vector (x and y) and returns a four dimensional vector (r, g, b and a). But before we go further transforming data between dimensions we need to start simpler... much simpler. That means understanding how to make one dimensional functions. The more energy and time you spend learning and mastering this, the stronger your shader karate will be. +This chapter could be named "Mr. Miyagi's fence lesson." Previously, we mapped the normalized position of *x* and *y* to the *red* and *green* channels. Essentially we made a function that takes a two dimensional vector (x and y) and returns a four dimensional vector (r, g, b and a). But before we go further transforming data between dimensions we need to start simpler... much simpler. That means understanding how to make one dimensional functions. The more energy and time you spend learning and mastering this, the stronger your shader karate will be. ![The Karate Kid (1984)](mr_miyagi.jpg) @@ -19,17 +19,17 @@ This one-to-one relationship between *x* and *y* (or the brightness) is know as Interesting, right? On line 22 try different exponents: 20.0, 2.0, 1.0, 0.0, 0.2 and 0.02 for example. Understanding this relationship between the value and the exponent will be very helpful. Using these types of mathematical functions here and there will give you expressive control over your code, a sort of data acupuncture that let you control the flow of values. -[```pow()```](../glossary/?search=pow) is a native function in GLSL and there are many others. Most of them are accelerated at the level of the hardware, which means if they are used in the right way and with discretion they will make your code faster. +[```pow()```](../glossary/?search=pow) is a native function in GLSL and there are many others. Most of them are accelerated at the level of the hardware, which means if they are used in the right way and with discretion they will make your code faster. Replace the power function on line 22. Try other ones like: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) and [```sqrt()```](../glossary/?search=sqrt). Some of these functions are more interesting when you play with them using PI. You can see on line 8 that I have defined a macro that will replace any call to ```PI``` with the value ```3.14159265359```. - + ### Step and Smoothstep -GLSL also has some unique native interpolation functions that are hardware accelerated. +GLSL also has some unique native interpolation functions that are hardware accelerated. -The [```step()```](../glossary/?search=step) interpolation receives two parameters. The first one is the limit or threshold, while the second one is the value we want to check or pass. Any value under the limit will return ```0.0``` while everything above the limit will return ```1.0```. +The [```step()```](../glossary/?search=step) interpolation receives two parameters. The first one is the limit or threshold, while the second one is the value we want to check or pass. Any value under the limit will return ```0.0``` while everything above the limit will return ```1.0```. -Try changing this threshold value on line 20 of the following code. +Try changing this threshold value on line 20 of the following code.
@@ -65,7 +65,7 @@ Try the following exercises and notice what happens: * Multiply time (```u_time```) by *x* before computing the ```sin```. See how the **frequency** between phases becomes more and more compressed. Note that u_time may have already become very large, making the graph hard to read. -* Add 1.0 to [```sin(x)```](../glossary/?search=sin). See how all the wave is **displaced** up and now all values are between 0.0 and 2.0. +* Add 1.0 to [```sin(x)```](../glossary/?search=sin). See how all the wave is **displaced** up and now all values are between 0.0 and 2.0. * Multiply [```sin(x)```](../glossary/?search=sin) by 2.0. See how the **amplitude** doubles in size. @@ -93,7 +93,7 @@ At the end of the last exercise we introduced some new functions. Now it’s tim ### Advance shaping functions -[Golan Levin](http://www.flong.com/) has great documentation of more complex shaping functions that are extraordinarily helpful. Porting them to GLSL is a really smart move, to start builidng your own resource of snippets of code. +[Golan Levin](http://www.flong.com/) has great documentation of more complex shaping functions that are extraordinarily helpful. Porting them to GLSL is a really smart move, to start builidng your own resource of snippets of code. * [Polynomial Shaping Functions: www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/) @@ -105,7 +105,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. +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()```: diff --git a/05/cubicpulse.frag b/05/cubicpulse.frag index 0494557..7e695c2 100644 --- a/05/cubicpulse.frag +++ b/05/cubicpulse.frag @@ -9,7 +9,7 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // www.iquilezles.org/www/articles/functions/functions.htm float cubicPulse( float c, float w, float x ){ x = abs(x - c); @@ -19,7 +19,7 @@ float cubicPulse( float c, float w, float x ){ } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -29,9 +29,9 @@ void main() { float y = cubicPulse(0.5,0.2,st.x); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/easing.frag b/05/easing.frag index 7f5bfb3..22a4904 100644 --- a/05/easing.frag +++ b/05/easing.frag @@ -179,7 +179,7 @@ float backInOut(float t) { } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -230,4 +230,4 @@ void main() { float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/expo.frag b/05/expo.frag index eda4018..3268dab 100644 --- a/05/expo.frag +++ b/05/expo.frag @@ -12,7 +12,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -25,6 +25,6 @@ void main() { float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/expstep.frag b/05/expstep.frag index a27afc8..2754f85 100644 --- a/05/expstep.frag +++ b/05/expstep.frag @@ -9,14 +9,14 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // www.iquilezles.org/www/articles/functions/functions.htm float expStep( float x, float k, float n ){ return exp( -k*pow(x,n) ); } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -26,9 +26,9 @@ void main() { float y = expStep(st.x,10.,1.0); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/featured_examples.php b/05/featured_examples.php index 02bce30..4b81131 100644 --- a/05/featured_examples.php +++ b/05/featured_examples.php @@ -1 +1 @@ -
\ No newline at end of file +
diff --git a/05/impulse.frag b/05/impulse.frag index 8572f3b..27fd711 100644 --- a/05/impulse.frag +++ b/05/impulse.frag @@ -9,7 +9,7 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // www.iquilezles.org/www/articles/functions/functions.htm float impulse( float k, float x ){ float h = k*x; @@ -17,7 +17,7 @@ float impulse( float k, float x ){ } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -27,9 +27,9 @@ void main() { float y = impulse(12.,st.x); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/index.php b/05/index.php index baf8a5f..293e33e 100644 --- a/05/index.php +++ b/05/index.php @@ -1,4 +1,4 @@ -text(file_get_contents($README.'.md')); - + echo '
@@ -29,5 +29,5 @@ '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/05/linear.frag b/05/linear.frag index e594a92..aa80120 100644 --- a/05/linear.frag +++ b/05/linear.frag @@ -8,7 +8,7 @@ uniform float u_time; // Plot a line on Y using a value between 0.0-1.0 float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -18,10 +18,10 @@ void main() { float y = st.x; vec3 color = vec3(y); - + // Plot a line float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/notes.md b/05/notes.md index 6bdae9f..37bc405 100644 --- a/05/notes.md +++ b/05/notes.md @@ -7,4 +7,4 @@ * Actually, this is the point where you lose me. I want it to be more gradual. It feels like there are 100 new concepts on this one page. ### Nicolas -* took the freedom to explain more indepth what interpolation is and why it rocks :) \ No newline at end of file +* took the freedom to explain more indepth what interpolation is and why it rocks :) diff --git a/05/parabola.frag b/05/parabola.frag index 01c0a40..4064eeb 100644 --- a/05/parabola.frag +++ b/05/parabola.frag @@ -8,14 +8,14 @@ precision mediump float; uniform vec2 u_resolution; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // www.iquilezles.org/www/articles/functions/functions.htm float parabola( float x, float k ){ return pow( 4.0*x*(1.0-x), k ); } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -25,9 +25,9 @@ void main() { float y = parabola(st.x,1.0); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/pcurve.frag b/05/pcurve.frag index 3cc8acf..57de285 100644 --- a/05/pcurve.frag +++ b/05/pcurve.frag @@ -9,7 +9,7 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // www.iquilezles.org/www/articles/functions/functions.htm float pcurve( float x, float a, float b ){ float k = pow(a+b,a+b) / (pow(a,a)*pow(b,b)); @@ -17,7 +17,7 @@ float pcurve( float x, float a, float b ){ } float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -27,9 +27,9 @@ void main() { float y = pcurve(st.x,3.0,1.0); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/smoothstep.frag b/05/smoothstep.frag index 7111a30..0ae3f8c 100644 --- a/05/smoothstep.frag +++ b/05/smoothstep.frag @@ -9,7 +9,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -20,9 +20,9 @@ void main() { float y = smoothstep(0.1,0.9,st.x); vec3 color = vec3(y); - + float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/05/step.frag b/05/step.frag index 927a213..d45152e 100644 --- a/05/step.frag +++ b/05/step.frag @@ -8,7 +8,7 @@ uniform vec2 u_resolution; uniform float u_time; float plot(vec2 st, float pct){ - return smoothstep( pct-0.02, pct, st.y) - + return smoothstep( pct-0.02, pct, st.y) - smoothstep( pct, pct+0.02, st.y); } @@ -23,6 +23,6 @@ void main() { float pct = plot(st,y); color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/06/README-ch.md b/06/README-ch.md index 23955d0..a286c2a 100644 --- a/06/README-ch.md +++ b/06/README-ch.md @@ -11,7 +11,7 @@ vec3 red = vec3(1.0,0.0,0.0); red.x = 1.0; red.y = 0.0; -red.z = 0.0; +red.z = 0.0; ``` 以x,y,z定义颜色是不是有些奇怪?正因如此,我们有其他方法访问这些变量——以不同的名字。```.x```, ```.y```, ```.z```也可以被写作```.r```, ```.g```, ```.b``` 和 ```.s```, ```.t```, ```.p```。(```.s```, ```.t```, ```.p```通常被用做后面章节提到的贴图空间坐标)你也可以通过使用索引位置```[0]```, ```[1]``` 和 ```[2]```来访问向量. @@ -34,7 +34,7 @@ GLSL中向量类型的另一大特点是可以用你需要的任意顺序简单 ```glsl vec3 yellow, magenta, green; -// Making Yellow +// Making Yellow yellow.rg = vec2(1.0); // Assigning 1. to red and green channels yellow[2] = 0.0; // Assigning 0. to blue channel @@ -42,7 +42,7 @@ yellow[2] = 0.0; // Assigning 0. to blue channel magenta = yellow.rbg; // Assign the channels with green and blue swapped // Making Green -green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels +green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels ``` #### 个人工具箱 @@ -97,9 +97,9 @@ green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue * 用 ```step()``` 函数在做一个五彩的旗子。 ### HSB - + 我们不能脱离色彩空间来谈论颜色。正如你所知,除了rgb值,有其他不同的方法去描述定义颜色。 - + [HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) 代表色相,饱和度和亮度(或称为值)。这更符合直觉也更有利于组织颜色。稍微花些时间阅读下面的 ```rgb2hsv()``` 和 ```hsv2rgb()``` 函数。 将x坐标(位置)映射到Hue值并将y坐标映射到明度,我们就得到了五彩的可见光光谱。这样的色彩空间分布实现起来非常方便,比起RGB,用HSB来拾取颜色更直观。 @@ -137,12 +137,10 @@ HSB原本是在极坐标下产生的(以半径和角度定义)而并非在 在进入下一章之前让我们停下脚步回顾下。复习下之前例子的函数。你会注意到变量类型之前有个限定符 ```in```,在这个 [*qualifier*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) (限定符)例子中它特指这个变量是只读的。在之后的例子中我们会看到可以定义一个 ```out``` 或者 ```inout```变量。最后这个 ```inout```,再概念上类似于参照输入一个变量,这意味着我们有可能修改一个传入的变量。 ```glsl -int newFunction(in vec4 aVec4, // read-only +int newFunction(in vec4 aVec4, // read-only out vec3 aVec3, // write-only inout int aInt); // read-write -``` +``` 或许你还不相信我们可以用所有这些元素来画一些炫酷的东西。下一章我们会学习如何结合所有这些技巧通过融合 (*blending*) 空间来创造几何形状。没错。。。融合(*blending*) 空间。 - - diff --git a/06/README-de.md b/06/README-de.md index 6f12ac3..72d3040 100644 --- a/06/README-de.md +++ b/06/README-de.md @@ -2,7 +2,7 @@ ## Farben -Wir hatten bislang noch wenig Gelegenheit, um über die Vektortypen von GLSL zu sprechen. Bevor es mit anderen Inhalten weitergeht, ist es wichtig, mehr über diese Variablentypen zu erfahren. Das Thema „Farben“ bietet sich dafür an. +Wir hatten bislang noch wenig Gelegenheit, um über die Vektortypen von GLSL zu sprechen. Bevor es mit anderen Inhalten weitergeht, ist es wichtig, mehr über diese Variablentypen zu erfahren. Das Thema „Farben“ bietet sich dafür an. Falls Du mit den Konzepten der objektorientierten Programmierung vertraut bist, ist Dir vielleicht schon aufgefallen, dass wir die verschiedenen Elemente innerhalb eines Vektors wie eine gewöhnliche ```struct``` in C ansprechen. @@ -10,7 +10,7 @@ Falls Du mit den Konzepten der objektorientierten Programmierung vertraut bist, vec3 red = vec3(1.0,0.0,0.0); red.x = 1.0; red.y = 0.0; -red.z = 0.0; +red.z = 0.0; ``` Die Festlegung von Farben über die Komponenten *x*, *y* und *z* wirkt auf den ersten Blick etwas merkwürdig, nicht wahr? Aus diesem Grund gibt es weitere Möglichkeiten, um auf diese Elemente zuzugreifen. Die Inhalte von ```.x```, ```.y``` und ```.z``` können auch als ```.r```, ```.g``` und ```.b```, sowie als ```.s```, ```.t``` und ```.p``` angesprochen werden (```.s```, ```.t``` und ```.p``` werden typischerweise für die Raumkoordinaten von Texturen genutzt, wie wir in späteren Kapiteln noch sehen werden). Darüber hinaus lassen sich die Elemente eines Vektors auch über ihre Index-Position als ```[0]```, ```[1]``` und ```[2]``` ansprechen. @@ -58,7 +58,7 @@ Jetzt, wo Du weißt, wie man Farben definiert, wird es Zeit, dies mit unserem bi ![](mix-f.jpg) -Lenke Dein Augenmerk im folgenden Programm besonders auf die *Zeile 18*. Schau Dir genau an, wie hier die absoluten Werte aus einer *Sinusfunktion* genutzt werden, um zeitabhängig und mit unterschiedlichen Verhältnissen die Farben aus den Variablen ```colorA``` und ```colorB``` zu mischen. +Lenke Dein Augenmerk im folgenden Programm besonders auf die *Zeile 18*. Schau Dir genau an, wie hier die absoluten Werte aus einer *Sinusfunktion* genutzt werden, um zeitabhängig und mit unterschiedlichen Verhältnissen die Farben aus den Variablen ```colorA``` und ```colorB``` zu mischen.
@@ -66,13 +66,13 @@ Jetzt zeige Deine Fähigkeiten, indem Du: * Einen ausdrucksstarken Übergang zwischen den Farben konstruierst. Denke an ein bestimmtes Gefühl, eine impulsive menschliche Regung. Welche Farbe vermag dieses Gefühl wohl am besten auszudrücken? Und wie soll sich diese Farbe entwickeln, um anschließend wieder zu verschwinden? Animiere den Übergang mit Hilfe formgebender Funktionen. Robert Penner hat eine Reihe populärer Übergangsfunktionen für Computeranimationen entwickelt, die als [easing functions](http://easings.net/) bekannt sind. Du kannst für Deine Nachforschungen und als Inspiration auf [dieses Beispiel](../edit.php#06/easing.frag) zurückgreifen. Aber die besten Ergebnisse erzielst Du natürlich, wenn Du Deine ganz eigenen Übergänge kreierst. -### Das Spiel mit Farbverläufen +### Das Spiel mit Farbverläufen Die [```mix()```](../glossary/?search=mix)-Funktion hat noch mehr zu bieten. Anstelle eines einzelnen Werts vom Typ ```float```, können wir auch einen Datentyp übergeben, der zu den ersten beiden Argumenten passt. In unserem Fall ist das ein ```vec3```. Dadurch gewinnen wir die Kontrolle über das Mischen in allen drei Farbkanälen *Rot*, *Grün* und *Blau* (```r```, ```g``` und ```b```). ![](mix-vec.jpg) -Wirf nun einen Blick auf das folgende Beispiel. Wie schon bei den Beispielen im letzten Kapitel verbinden wir den Übergang auch hier mit dem normalisierten Wert der *X-Ordinate* und visualisieren ihn als eine Linie. Im ersten Schritt folgen die Übergänge in allen drei Farbkanälen derselben Linie. +Wirf nun einen Blick auf das folgende Beispiel. Wie schon bei den Beispielen im letzten Kapitel verbinden wir den Übergang auch hier mit dem normalisierten Wert der *X-Ordinate* und visualisieren ihn als eine Linie. Im ersten Schritt folgen die Übergänge in allen drei Farbkanälen derselben Linie. Lösche jetzt die Kommentarzeichen aus der *Programmzeile 25*, damit diese ebenfalls ausgeführt wird. Dann schau, was daraufhin geschieht. Entferne anschließend auch die Kommentarzeichen vor den *Zeilen 26 und 27*. Achte darauf, dass diese drei Zeilen jeweils das Mischverhältnis für die *Rot-*, *Grün*, und *Blau-Kanäle* zwischen den Farben aus den Variablen ```colorA``` und ```colorB``` festlegen. @@ -92,9 +92,9 @@ Vielleicht erkennst Du die drei formgebenden Funktionen in den *Zeilen 25 bis 27 ### HSB -Beim Thema „Farben“ kommen wir nicht an dem Konzept der „Farbräume“ vorbei. Wie Du vielleicht weißt, gibt es unterschiedliche Möglichkeiten, Farben zu beschreiben, jenseits ihrer Auftrennung in *Rot-*, *Grün-* und *Blau-Anteile* (sprich: Kanäle). +Beim Thema „Farben“ kommen wir nicht an dem Konzept der „Farbräume“ vorbei. Wie Du vielleicht weißt, gibt es unterschiedliche Möglichkeiten, Farben zu beschreiben, jenseits ihrer Auftrennung in *Rot-*, *Grün-* und *Blau-Anteile* (sprich: Kanäle). -[HSB](https://de.wikipedia.org/wiki/HSV-Farbraum) steht für *Hue* (dt. Farbwert), *Saturation* (dt. Farbsättigung) und *Brightness* (dt. absolute Helligkeit). Dieses Farbsystem ist intuitiver und in vielen Fällen auch praktischer, wenn es um die Festlegung von Farben geht. Nimm Dir einen Moment Zeit, um die Konvertierungsfunktionen ```rgb2hsv()``` und ```hsv2rgb()``` im folgenden Programmcode zu studieren. +[HSB](https://de.wikipedia.org/wiki/HSV-Farbraum) steht für *Hue* (dt. Farbwert), *Saturation* (dt. Farbsättigung) und *Brightness* (dt. absolute Helligkeit). Dieses Farbsystem ist intuitiver und in vielen Fällen auch praktischer, wenn es um die Festlegung von Farben geht. Nimm Dir einen Moment Zeit, um die Konvertierungsfunktionen ```rgb2hsv()``` und ```hsv2rgb()``` im folgenden Programmcode zu studieren. Indem wir die Position auf der *X-Achse* auf den Farbwert und die Position auf der *Y-Achse* auf die Helligkeit abbilden, erhalten wir ein hübsches Spektralbild. Diese räumliche Verteilung der Farben kann sehr praktisch sei, wenn es um die Auswahl einer Farbe für einen bestimmten Zweck geht. @@ -104,9 +104,9 @@ Indem wir die Position auf der *X-Achse* auf den Farbwert und die Position auf d Das *HSB-Farbmodell* wurde ursprünglich entwickelt, um Farben in Polarkoordinaten (bestehend aus einem *Winkel* und einem *Radius*) auszudrücken und nicht als kartesische Koordinaten (bestehend aus einer *X-* und einer *Y-Ordinate*). Um unsere ```HSB```-Funktion mit Polarkoordinaten arbeiten zu lassen, müssen wir den Winkel und die Entfernung des jeweiligen Bildpunktes von der Mitte der Zeichenfläche berechnen. Dafür nutzen wir die [```length()```](../glossary/?search=length)-Funktion, sowie die Funktion [```atan(y,x)```](../glossary/?search=atan) (das ist die GLSL-Variante der in vielen Programmiersprachen verfügbaren Funktion ```atan2(y,x)``` zur Berechnung des Arkustangens). -Bei der Nutzung von Vektor- und Trigonometrie-Funktionen werden Variablen der Datentypen ```vec2```, ```vec3``` und ```vec4``` wie Vektoren behandelt, auch wenn sie tatsächlich Farben verkörpern. Wir beginnen hier also, Farben und Vektoren gleichermaßen zu bearbeiten - eine Flexibilität, die sich noch als äußerst praktisch und weitreichend erweisen wird. +Bei der Nutzung von Vektor- und Trigonometrie-Funktionen werden Variablen der Datentypen ```vec2```, ```vec3``` und ```vec4``` wie Vektoren behandelt, auch wenn sie tatsächlich Farben verkörpern. Wir beginnen hier also, Farben und Vektoren gleichermaßen zu bearbeiten - eine Flexibilität, die sich noch als äußerst praktisch und weitreichend erweisen wird. -**Hinweis:** Nur, falls Du Dich fragst: Abgesehen von [```length```](../glossary/?search=length) gibt es noch viele weitere geometrische Funktionen. Dazu gehören beisielsweise: [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=faceforward), [```reflect()```](../glossary/?search=reflect) und [```refract()```](../glossary/?search=refract). +**Hinweis:** Nur, falls Du Dich fragst: Abgesehen von [```length```](../glossary/?search=length) gibt es noch viele weitere geometrische Funktionen. Dazu gehören beisielsweise: [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=faceforward), [```reflect()```](../glossary/?search=reflect) und [```refract()```](../glossary/?search=refract). Außerdem bietet GLSL vergleichende Funktionen für Vektoren wie [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) und [```notEqual()```](../glossary/?search=notEqual). @@ -118,7 +118,7 @@ Wie Du siehst, dreht sich also auch hier das ganze Spiel darum, Werte zwischen ` Probiere die folgenden Übungen aus: -* Verändere das obige Programmbeispiel so, dass sich das Farbrad dreht, wie der Mauszeiger bei einer länger währenden Operation. +* Verändere das obige Programmbeispiel so, dass sich das Farbrad dreht, wie der Mauszeiger bei einer länger währenden Operation. * Nutze eine formgebende Funktion in Verbindung mit der Konvertierungsfunktion von *HSB* nach *RGB*, um einen bestimmten Farbwert in den Vordergrund zu rücken und die anderen Farben „klein“ zu halten. @@ -138,10 +138,8 @@ Bevor wir zum nächsten Kapitel springen, lass und kurz innehalten und einen Sch ```glsl int newFunction(in vec4 aVec4, // nur auslesbar - out vec3 aVec3, // nicht initalisiert, nur beschreibbar + out vec3 aVec3, // nicht initalisiert, nur beschreibbar inout int aInt); // lesen und schreiben, Aenderungen fliessen zum Aufrufer zurueck ``` Du hast vielleicht nicht damit gerechnet, aber jetzt haben wir bereits alle Elemente beisammen, um aufregende Grafiken zu erstellen. Im nächsten Kapitel werden wir lernen, wie man alle unsere kleinen Tricks nutzen kann, um den Raum richtig in Wallung zu bringen. Ja, du hast richtig gehört. Genau darum geht's. - - diff --git a/06/README-fr.md b/06/README-fr.md index faee52d..afaf27f 100644 --- a/06/README-fr.md +++ b/06/README-fr.md @@ -14,7 +14,7 @@ Si vous connaissez la Programmation Orientée Objet, vous aurez remarqué que no vec3 red = vec3(1.0,0.0,0.0); red.x = 1.0; red.y = 0.0; -red.z = 0.0; +red.z = 0.0; ``` Dans l'exemple ci dessus, *x*, *y* et *z* permettent d'**accéder** aux 3 valeurs contenues dans l'objet ```red``` de type ```vec3```, ce sont les **accesseurs** aux propriétés de ```red```. @@ -259,10 +259,7 @@ Cette dernière, ```inout```, est équivalente à passer un argument *par réfé int newFunction(in vec4 aVec4, // lecture seule out vec3 aVec3, // écriture seule inout int aInt); // lecture / écriture -``` +``` Vous ne le savez pas encore et vous pourriez ne pas le croire mais nous avons à présent tout ce qu'il nous faut pour dessiner à peu près n'importe quoi. Au prochain chapitre, nous verrons comment combiner ces techniques pour *mélanger* l'espace. Oui... *mélanger* l'espace. - - - diff --git a/06/README-it.md b/06/README-it.md index 9a9897e..353e295 100644 --- a/06/README-it.md +++ b/06/README-it.md @@ -10,7 +10,7 @@ Se siete pratici con i paradigmi di programmazione orientata agli oggetti, proba vec3 red = vec3(1.0,0.0,0.0); red.x = 1.0; red.y = 0.0; -red.z = 0.0; +red.z = 0.0; ``` Definire il colore usando una notazione *x*, *y* e *z* può essere fuorviante e creare confusione, vero? Per questo esistono altri modi di accedere alle stesse informazioni, con nomi diversi. I valori di ```.x```, ```.y``` e ```.z``` possono anche essere chiamati ```.r```, ```.g``` e ```.b```, e ```.s```, ```.t``` e ```.p```. (```.s```, ```.t``` e ```.p``` solitamente sono usati per le coordinate spaziali di una texture, che vedremo nel prossimo capitolo). Puoi anche accedere ai valori in un vettore usando gli indici di posizione ```[0]```, ```[1]``` e ```[2]```. @@ -44,7 +44,7 @@ magenta = yellow.rbg; // Invertite il canale del verde con quello del blu green.rgb = yellow.bgb; // Assegnare il canale blu del giallo (0) ai canali rosso e blu ``` -#### Per la vostra cassetta degli attrezzi +#### Per la vostra cassetta degli attrezzi Potreste non essere abituati a selezionare i colori attraverso numeri - di sicuro questo processo potrebbe risultare controintuitivo. Per vostra fortuna esistono tanti programmi che semplificano questo lavoro. Trovatene uno che vada incontro ai vostri bisogni e usatelo per ottenere colori in formato ```vec3``` 0 ```vec4``` format. Per esempio, qui trovate i templates che io uso su [Spectrum](http://www.eigenlogik.com/spectrum/mac): @@ -75,7 +75,7 @@ La funzione [```mix()```](../glossary/?search=mix) ha molto da offrire. Invece d Guardate l'esempio seguente. Così come negli esempi nel capitolo precedente, stiamo collegando la transizione alla *x* normalizzata e la visualizziamo con una linea. In questo momento tutti e tre i canali seguono la medesima linea. -Ora, togliete il commento alla riga 25 e guardate cosa succede. Poi provate a togliere il commento alle righe 26 e 27. Ricordate che le linee visualizzano la quantità di ```colorA``` e ```colorB``` da mescolare per ogni canale. +Ora, togliete il commento alla riga 25 e guardate cosa succede. Poi provate a togliere il commento alle righe 26 e 27. Ricordate che le linee visualizzano la quantità di ```colorA``` e ```colorB``` da mescolare per ogni canale.
@@ -103,7 +103,7 @@ Mappando la posizione sull'asse x con la tonalità e la posizione sull'asse y co ### HSB nelle coordinate polari -Originariamente HSB è stato creato per essere rappresentato in coordinate polari (basate su angoli e raggio) e non in coordinate cartesiane (basate su x e y). Per unire la nostra funzione HSB alle coordinate polari, dobbiamo ottenere l'angolo e la distanza dal centro del canvas per ogni coordinata pixel. Per far questo usiamo la funzione [```length()```](../glossary/?search=length) e [```atan(y,x)```](../glossary/?search=atan) (che è la versione GLSL della più comune ```atan2(y,x)```). +Originariamente HSB è stato creato per essere rappresentato in coordinate polari (basate su angoli e raggio) e non in coordinate cartesiane (basate su x e y). Per unire la nostra funzione HSB alle coordinate polari, dobbiamo ottenere l'angolo e la distanza dal centro del canvas per ogni coordinata pixel. Per far questo usiamo la funzione [```length()```](../glossary/?search=length) e [```atan(y,x)```](../glossary/?search=atan) (che è la versione GLSL della più comune ```atan2(y,x)```). Quando si usano vettori e funzioni trigonometriche, ```vec2```, ```vec3``` e ```vec4``` sono considerati come vettori anche quando rappresentano i colori. Inizieremo a considerare in modo simile i colori e i vettori, e in realtà troverete che questa flessibilità concettuale è molto potente. @@ -141,4 +141,4 @@ int newFunction(in vec4 aVec4, // solo lettura inout int aInt); // lettura e scrittura ``` -Potreste non crederci ma ora abbiamo tutti gli elementi per creare dei fantastici disegni. Nel prossimo capitolo impareremo come si possono combinare tutte queste tecniche per creare forme geometriche *fondendo* lo spazio. Sì, avete capito bene, *fondendo* lo spazio. \ No newline at end of file +Potreste non crederci ma ora abbiamo tutti gli elementi per creare dei fantastici disegni. Nel prossimo capitolo impareremo come si possono combinare tutte queste tecniche per creare forme geometriche *fondendo* lo spazio. Sì, avete capito bene, *fondendo* lo spazio. diff --git a/06/README.md b/06/README.md index d4edd50..1e0b442 100644 --- a/06/README.md +++ b/06/README.md @@ -2,7 +2,7 @@ ## Colors -We haven't much of a chance to talk about GLSL vector types. Before going further it's important to learn more about these variables and the subject of colors is a great way to find out more about them. +We haven't much of a chance to talk about GLSL vector types. Before going further it's important to learn more about these variables and the subject of colors is a great way to find out more about them. If you are familiar with object oriented programming paradigms you've probably noticed that we have been accessing the data inside the vectors like any regular C-like ```struct```. @@ -10,7 +10,7 @@ If you are familiar with object oriented programming paradigms you've probably n vec3 red = vec3(1.0,0.0,0.0); red.x = 1.0; red.y = 0.0; -red.z = 0.0; +red.z = 0.0; ``` Defining color using an *x*, *y* and *z* notation can be confusing and misleading, right? That's why there are other ways to access this same information, but with different names. The values of ```.x```, ```.y``` and ```.z``` can also be called ```.r```, ```.g``` and ```.b```, and ```.s```, ```.t``` and ```.p```. (```.s```, ```.t``` and ```.p``` are usually used for spatial coordinates of a texture, which we'll see in a later chapter.) You can also access the data in a vector by using the index position, ```[0]```, ```[1]``` and ```[2]```. @@ -25,14 +25,14 @@ vector[2] = vector.b = vector.z = vector.p; vector[3] = vector.a = vector.w = vector.q; ``` -These different ways of pointing to the variables inside a vector are just nomenclatures designed to help you write clear code. This flexibility embedded in shading language is a door for you to start thinking interchangably about color and space coordinates. +These different ways of pointing to the variables inside a vector are just nomenclatures designed to help you write clear code. This flexibility embedded in shading language is a door for you to start thinking interchangably about color and space coordinates. Another great feature of vector types in GLSL is that the properties can be combined in any order you want, which makes it easy to cast and mix values. This ability is called *swizzle*. ```glsl vec3 yellow, magenta, green; -// Making Yellow +// Making Yellow yellow.rg = vec2(1.0); // Assigning 1. to red and green channels yellow[2] = 0.0; // Assigning 0. to blue channel @@ -40,7 +40,7 @@ yellow[2] = 0.0; // Assigning 0. to blue channel magenta = yellow.rbg; // Assign the channels with green and blue swapped // Making Green -green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels +green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels ``` #### For your toolbox @@ -58,7 +58,7 @@ Now that you know how colors are defined, it's time to integrate this with our p ![](mix-f.jpg) -Check the following code at line 18 and see how we are using the absolute values of a sin wave over time to mix ```colorA``` and ```colorB```. +Check the following code at line 18 and see how we are using the absolute values of a sin wave over time to mix ```colorA``` and ```colorB```.
@@ -66,13 +66,13 @@ Show off your skills by: * Make an expressive transition between colors. Think of a particular emotion. What color seems most representative of it? How does it appear? How does it fade away? Think of another emotion and the matching color for it. Change the beginning and ending color of the above code to match those emotions. Then animate the transition using shaping functions. Robert Penner developed a series of popular shaping functions for computer animation known as [easing functions](http://easings.net/), you can use [this example](../edit.php#06/easing.frag) as research and inspiration but the best result will come from making your own transitions. -### Playing with gradients +### Playing with gradients The [```mix()```](../glossary/?search=mix) function has more to offer. Instead of a single ```float```, we can pass a variable type that matches the two first arguments, in our case a ```vec3```. By doing that we gain control over the mixing percentages of each individual color channel, ```r```, ```g``` and ```b```. ![](mix-vec.jpg) -Take a look at the following example. Like the examples in the previous chapter, we are hooking the transition to the normalized *x* coordinate and visualizing it with a line. Right now all the channels go along the same line. +Take a look at the following example. Like the examples in the previous chapter, we are hooking the transition to the normalized *x* coordinate and visualizing it with a line. Right now all the channels go along the same line. Now, uncomment line number 25 and watch what happens. Then try uncommenting lines 26 and 27. Remember that the lines visualize the amount of ```colorA``` and ```colorB``` to mix per channel. @@ -92,9 +92,9 @@ You probably recognize the three shaping functions we are using on lines 25 to 2 ### HSB -We can't talk about color without speaking about color space. As you probably know there are different ways to organize color besides by red, green and blue channels. +We can't talk about color without speaking about color space. As you probably know there are different ways to organize color besides by red, green and blue channels. -[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) stands for Hue, Saturation and Brightness (or Value) and is a more intuitive and useful organization of colors. Take a moment to read the ```rgb2hsv()``` and ```hsv2rgb()``` functions in the following code. +[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) stands for Hue, Saturation and Brightness (or Value) and is a more intuitive and useful organization of colors. Take a moment to read the ```rgb2hsv()``` and ```hsv2rgb()``` functions in the following code. By mapping the position on the x axis to the Hue and the position on the y axis to the Brightness, we obtain a nice spectrum of visible colors. This spatial distribution of color can be very handy; it's more intuitive to pick a color with HSB than with RGB. @@ -104,7 +104,7 @@ By mapping the position on the x axis to the Hue and the position on the y axis 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. +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. **Note:** If you were wondering, there are more geometric functions besides [```length```](../glossary/?search=length) like: [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=faceforward), [```reflect()```](../glossary/?search=reflect) and [```refract()```](../glossary/?search=refract). Also GLSL has special vector relational functions such as: [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) and [```notEqual()```](../glossary/?search=notEqual). @@ -135,11 +135,9 @@ Try the following exercises: Before jumping to the next chapter let’s stop and rewind. Go back and take look at the functions in previous examples. You will notice ```in``` before the type of the arguments. This is a [*qualifier*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) and in this case it specifies that the variable is read only. In future examples we will see that it is also possible to define arguments as ```out``` or ```inout```. This last one, ```inout```, is conceptually similar to passing an argument by reference which will give us the possibility to modify a passed variable. ```glsl -int newFunction(in vec4 aVec4, // read-only +int newFunction(in vec4 aVec4, // read-only out vec3 aVec3, // write-only inout int aInt); // read-write ``` 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. - - diff --git a/06/easing.frag b/06/easing.frag index 79beecf..54ca0f5 100644 --- a/06/easing.frag +++ b/06/easing.frag @@ -186,4 +186,4 @@ void main() { float pct = cubicInOut( abs(fract(t)*2.0-1.) ); gl_FragColor = vec4(vec3(mix(colorA, colorB, pct)),1.0); -} \ No newline at end of file +} diff --git a/06/gradient.frag b/06/gradient.frag index 2837b67..9a09e36 100644 --- a/06/gradient.frag +++ b/06/gradient.frag @@ -12,7 +12,7 @@ vec3 colorA = vec3(0.149,0.141,0.912); vec3 colorB = vec3(1.000,0.833,0.224); float plot (vec2 st, float pct){ - return smoothstep( pct-0.01, pct, st.y) - + return smoothstep( pct-0.01, pct, st.y) - smoothstep( pct, pct+0.01, st.y); } @@ -21,7 +21,7 @@ void main() { vec3 color = vec3(0.0); vec3 pct = vec3(st.x); - + // pct.r = smoothstep(0.0,1.0, st.x); // pct.g = sin(st.x*PI); // pct.b = pow(st.x,0.5); @@ -34,4 +34,4 @@ void main() { color = mix(color,vec3(0.0,0.0,1.0),plot(st,pct.b)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/06/hsb-colorwheel.frag b/06/hsb-colorwheel.frag index 83301c8..fbbb6b0 100644 --- a/06/hsb-colorwheel.frag +++ b/06/hsb-colorwheel.frag @@ -7,12 +7,12 @@ precision mediump float; uniform vec2 u_resolution; uniform float u_time; -// Function from Iñigo Quiles +// Function from Iñigo Quiles // https://www.shadertoy.com/view/MsS3Wc vec3 hsb2rgb( in vec3 c ){ vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), - 6.0)-3.0)-1.0, - 0.0, + 6.0)-3.0)-1.0, + 0.0, 1.0 ); rgb = rgb*rgb*(3.0-2.0*rgb); return c.z * mix( vec3(1.0), rgb, c.y); @@ -26,10 +26,10 @@ void main(){ vec2 toCenter = vec2(0.5)-st; float angle = atan(toCenter.y,toCenter.x); float radius = length(toCenter)*2.0; - + // Map the angle (-PI to PI) to the Hue (from 0 to 1) // and the Saturation to the radius color = hsb2rgb(vec3((angle/TWO_PI)+0.5,radius,1.0)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/06/hsb.frag b/06/hsb.frag index 4e00a19..1b2d73d 100644 --- a/06/hsb.frag +++ b/06/hsb.frag @@ -7,25 +7,25 @@ uniform float u_time; vec3 rgb2hsb( in vec3 c ){ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = mix(vec4(c.bg, K.wz), - vec4(c.gb, K.xy), + vec4 p = mix(vec4(c.bg, K.wz), + vec4(c.gb, K.xy), step(c.b, c.g)); - vec4 q = mix(vec4(p.xyw, c.r), - vec4(c.r, p.yzx), + vec4 q = mix(vec4(p.xyw, c.r), + vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), - d / (q.x + e), + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), + d / (q.x + e), q.x); } -// Function from Iñigo Quiles +// Function from Iñigo Quiles // https://www.shadertoy.com/view/MsS3Wc vec3 hsb2rgb( in vec3 c ){ vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), - 6.0)-3.0)-1.0, - 0.0, + 6.0)-3.0)-1.0, + 0.0, 1.0 ); rgb = rgb*rgb*(3.0-2.0*rgb); return c.z * mix(vec3(1.0), rgb, c.y); @@ -40,4 +40,4 @@ void main(){ color = hsb2rgb(vec3(st.x,1.0,st.y)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/06/index.php b/06/index.php index d2bca38..703b3b8 100644 --- a/06/index.php +++ b/06/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/06/mix.frag b/06/mix.frag index 1cb18f2..8c43457 100644 --- a/06/mix.frag +++ b/06/mix.frag @@ -13,9 +13,9 @@ void main() { float pct = abs(sin(u_time)); - // Mix uses pct (a value from 0-1) to + // Mix uses pct (a value from 0-1) to // mix the two colors - color = mix(colorA, colorB, pct); + color = mix(colorA, colorB, pct); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/06/notes.md b/06/notes.md index f49c64a..88331a7 100644 --- a/06/notes.md +++ b/06/notes.md @@ -94,7 +94,7 @@ or you can instead, use a single ```vec4``` which ```.xy``` **accessor** will re [/NICO] -These different ways of pointing to the variables inside a vector are just nomenclatures designed to help you write clear code. This flexibility embedded in shading language is a door for you to start thinking interchangably about color and space coordinates. +These different ways of pointing to the variables inside a vector are just nomenclatures designed to help you write clear code. This flexibility embedded in shading language is a door for you to start thinking interchangably about color and space coordinates. [NICO] @@ -104,4 +104,4 @@ Another great feature of vector types in GLSL is that the properties can be comb to: Concatenation or *swizzle* gets really interesting when we need to cast and mix values. The following example show you how to *swizzle* properties between vectors. -[/NICO] \ No newline at end of file +[/NICO] diff --git a/07/NOTES.md b/07/NOTES.md index a09bb46..41f4c56 100644 --- a/07/NOTES.md +++ b/07/NOTES.md @@ -8,4 +8,4 @@ * L 113 the longest distance between a pixel and the center in a normalised space is: SQRT( 2 ) * 0.5 = ~0.7071..., not 0.5 (also present ion chapter 6) * L 123 'a bigger or smaller circular surface' a circular surface is called a 'disc' :) * L 175 a word about Quadrants and its relation to the bi-unit square maybe? or just explaining why we use a bi-unit square instead of the regular 0-1 normalized space... -* L 217 'how use' missing 'to' \ No newline at end of file +* L 217 'how use' missing 'to' diff --git a/07/README-ch.md b/07/README-ch.md index 566f1fa..cac8d2e 100644 --- a/07/README-ch.md +++ b/07/README-ch.md @@ -1,5 +1,5 @@ ## 形状 - + ![Alice Hubbard, Providence, United States, ca. 1892. Photo: Zindman/Freemont.](froebel.jpg) @@ -20,7 +20,7 @@ ```glsl if ( (X GREATER THAN 1) AND (Y GREATER THAN 1) ) paint white - else + else paint black ``` @@ -32,13 +32,13 @@ uniform vec2 u_resolution; void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // Each result will return 1.0 (white) or 0.0 (black). float left = step(0.1,st.x); // Similar to ( X greater than 0.1 ) float bottom = step(0.1,st.y); // Similar to ( Y greater than 0.1 ) // The multiplication of left*bottom will be similar to the logical AND. - color = vec3( left * bottom ); + color = vec3( left * bottom ); gl_FragColor = vec4(color,1.0); } @@ -51,7 +51,7 @@ step()函数会让没每一个小于0.1的像素变成黑色(vec3(0.0) 在前一例代码中我们重复每个像素的结构(左边和底边)。我们可以把原来的一个值换成两个值直接给step()来精减代码。就像这样: ```glsl - vec2 borders = step(vec2(0.1),st); + vec2 borders = step(vec2(0.1),st); float pct = borders.x * borders.y; ``` @@ -131,7 +131,7 @@ There are several ways to calculate that distance. The easiest one uses the [``` 其实我们是通过“空间距离”来重新解释什么是图形。这种技巧被称之为“距离场”,从字体轮廓到3D图形被广泛应用。 来小试下牛刀: - + * 用[```step()```](../glossary/?search=step)函数把所有大于0.5的像素点变成白色,并把小于的变成黑色(0.0)。 * 反转前景色和背景色。 @@ -229,10 +229,10 @@ pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6))); * 用这个例子,改造一个输入位置,指定图形(形状)的顶点数来返回一个距离场(的值)。 -* 结合使用 [```min()```](../glossary/?search=min) 和 [```max()```](../glossary/?search=max) 函数混合距离场。 +* 结合使用 [```min()```](../glossary/?search=min) 和 [```max()```](../glossary/?search=max) 函数混合距离场。 * 用距离场画个自己感兴趣的logo。 恭喜!你完成了最艰难的部分!休息下让这些概念沉淀一下吧 —— 用Processing 来画简单的形状很容易,但却不到火候。在 shader 的世界里,画形状是很纠结,而且适应这种新的编程范式会有些累人。 -既然现在你知道了如何画形状,我十分肯定你脑袋里已经充满了新的点子。在接下来的章节里你会学习到怎么移动,旋转以及缩放图形。这将使你的创作如虎添翼! \ No newline at end of file +既然现在你知道了如何画形状,我十分肯定你脑袋里已经充满了新的点子。在接下来的章节里你会学习到怎么移动,旋转以及缩放图形。这将使你的创作如虎添翼! diff --git a/07/README-de.md b/07/README-de.md index 92b674c..328a878 100644 --- a/07/README-de.md +++ b/07/README-de.md @@ -19,7 +19,7 @@ Lass uns mit etwas Pseudocode beginnen, der mit ```if```-Befehlen auf die Lage d ```glsl if ( (X GROESSER ALS 1) UND (Y GROESSER ALS 1) ) male weiss - else + else male schwarz ``` @@ -31,13 +31,13 @@ uniform vec2 u_resolution; void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // diese Berechnungen liefern jeweils 1.0 (weiss) oder 0.0 (schwarz). float left = step(0.1,st.x); // entspricht X groesser als 0.1 float bottom = step(0.1,st.y); // entspricht Y groesser als 0.1 // die Multiplikation von left*bottom entspricht der logischen Verknüpfung durch UND - color = vec3( left * bottom ); + color = vec3( left * bottom ); gl_FragColor = vec4(color,1.0); } @@ -50,7 +50,7 @@ Die [```step()```](../glossary/?search=step)-Funktion setzt jedes Pixel unterhal Im obigen Programmcode wiederholen wir die gleiche Vorgehensweise für beide Ränder (links und unten). Wir können das noch etwas kompakter formulieren, indem wir in einem Aufruf zwei Testwerte in Form eines zweidimensionalen Vektors an [```step()```](../glossary/?search=step) übergeben. Das sieht dann so aus: ```glsl - vec2 borders = step(vec2(0.1),st); + vec2 borders = step(vec2(0.1),st); float pct = borders.x * borders.y; ``` @@ -58,7 +58,7 @@ Bis jetzt haben wir nur zwei Kanten unseres Rechtecks bearbeitet. Jetzt kommen a
-Entferne die Kommentarzeichen aus den *Zeilen 21-22* und beobachte, wie wir die Koordinaten auf den linken und unteren Rand abbilden (```1-st```), damit wir sie wieder mit der [```step()```](../glossary/?search=step) Funktion und dem Wert von ```0.1``` vergleichen können. Aus der oberen rechten Ecke (```vec2(1.0,1.0)```) wird so für unsere Berechnungen quasi die untere linke Ecke ```vec2(0.0,0.0)```. Das ist so, als würden wir die Zeichenfläche einfach um 180 Grad drehen und den Test dann wie zuvor wiederholen. +Entferne die Kommentarzeichen aus den *Zeilen 21-22* und beobachte, wie wir die Koordinaten auf den linken und unteren Rand abbilden (```1-st```), damit wir sie wieder mit der [```step()```](../glossary/?search=step) Funktion und dem Wert von ```0.1``` vergleichen können. Aus der oberen rechten Ecke (```vec2(1.0,1.0)```) wird so für unsere Berechnungen quasi die untere linke Ecke ```vec2(0.0,0.0)```. Das ist so, als würden wir die Zeichenfläche einfach um 180 Grad drehen und den Test dann wie zuvor wiederholen. ![](rect-02.jpg) @@ -96,7 +96,7 @@ Doch wie soll das funktionieren? Lasse uns noch einmal zum Mathematikunterricht ![](compass.jpg) -Will man diese Vorgehensweise auf ein Shader-Programm übertragen, bei dem jedes kleine Feld auf dem Millimeterpapier einem Pixel entspricht, muss man jedes Pixel (bzw. Thread) *fragen*, ob es zum Kreis gehört. Das machen wir, indem wir die Entfernung des Pixels zum Mittelpunkt des gewünschten Kreises berechnen. +Will man diese Vorgehensweise auf ein Shader-Programm übertragen, bei dem jedes kleine Feld auf dem Millimeterpapier einem Pixel entspricht, muss man jedes Pixel (bzw. Thread) *fragen*, ob es zum Kreis gehört. Das machen wir, indem wir die Entfernung des Pixels zum Mittelpunkt des gewünschten Kreises berechnen. ![](circle.jpg) @@ -112,7 +112,7 @@ Man kann wahlweise die [```distance()```](../glossary/?search=distance)-Funktion In dem obigen Beispiel bilden wir die Entfernung zum Mittelpunkt der Zeichenfläche auf die Helligkeit der Pixel ab. Je näher sich ein Pixel beim Mittelpunkt befindet, desto geringer (dunkler) ist sein Farbwert. Beachte bitte, dass die Pixel auch zum Rand hin nicht allzu hell werden, weil die Entfernung vom Mittelpunkt ( ```vec2(0.5, 0.5)``` ) zu den Rändern maximal ```0.5``` beträgt. Denke ein wenig über die Abbildung nach und überlege Dir: -* Was kannst Du daraus ableiten? +* Was kannst Du daraus ableiten? * Wie kannst Du all dies nutzen, um einen Kreis zu malen? @@ -124,17 +124,17 @@ Man kann sich das obige Beispiel auch als eine Art Höhenprofil vorstellen, bei ![](distance-field.jpg) -Im Prinzip nutzen wir also eine Neuinterpretation des Raumes (ausgehend vom Abstand zur Mitte), um eine bestimmte Form zu kreieren. Diese Technik ist als „Distanzfeld“ bekannt und wird bei der Erstellung von 3D-Grafiken auf vielfältige Weise genutzt. +Im Prinzip nutzen wir also eine Neuinterpretation des Raumes (ausgehend vom Abstand zur Mitte), um eine bestimmte Form zu kreieren. Diese Technik ist als „Distanzfeld“ bekannt und wird bei der Erstellung von 3D-Grafiken auf vielfältige Weise genutzt. Versuche Dich doch einmal an folgenden Übungen: - + * Nutze die [```step()```](../glossary/?search=step)-Funktion, um alle Punkte größer als ```0.5``` weiß zu malen und alles darunter schwarz. * Invertiere die Farben von Vordergrund und Hintergrund. * Setze [```smoothstep()```](../glossary/?search=smoothstep) ein und experimentiere mit verschiedenen Grenzwerten, um angenehm sanfte Übergänge am Rand Deines Kreises zu erzeugen. -* Sobald Dir die Implementierung gefällt, baue daraus eine Funktion, die Du in zukünftigen Projekten einsetzen kannst. +* Sobald Dir die Implementierung gefällt, baue daraus eine Funktion, die Du in zukünftigen Projekten einsetzen kannst. * Fülle den Kreis mit einer Farbe. @@ -194,7 +194,7 @@ Im Kapitel über die Verwendung von Farben haben wir kartesische Koordinaten auf Einige dieser Formeln haben wir auch am Anfang dieses Kapitels genutzt, als es darum ging, Kreise zu zeichnen. Wir berechneten die Entfernung zum Kreismittelpunkt mit Hilfe der [```length()```](../glossary/?search=length)-Funktion. Jetzt, wo wir Distanzfelder kennengelernt haben, öffnet sich uns ein weiterer Weg zum Zeichnen komplexer Formen mithilfe von Polarkoordinaten. -Diese Technik unterliegt gewissen Beschränkungen, ist dafür aber sehr simpel und leistungsfähig. Sie beruht darauf, den Radius eines Kreises in Abhängigkeit des jeweiligen Winkels zu verändern, um unterschiedliche Formen zu erschaffen. Wie genau läuft diese Modulierung ab? Nun, Du hast es vielleicht schon erraten: Mit formgebenden Funktionen. +Diese Technik unterliegt gewissen Beschränkungen, ist dafür aber sehr simpel und leistungsfähig. Sie beruht darauf, den Radius eines Kreises in Abhängigkeit des jeweiligen Winkels zu verändern, um unterschiedliche Formen zu erschaffen. Wie genau läuft diese Modulierung ab? Nun, Du hast es vielleicht schon erraten: Mit formgebenden Funktionen. Unten findest Du verschiedene Funktionen jeweils zwei Mal: einmal als Verlaufskurve in einem kartesischen Koordinatensystem und dann als Shader-Programmcode in einem polaren Koordinatensystem. Dort stehen die verschiedenen formgebenden Funktionen in den *Programmzeilen 21 bis 25*. Entferne nun Schritt für Schritt die Kommentarzeilen und vergleiche den jeweiligen Funktionsgraphen im kartesischen Koordinatensystem mit seinem Äquivalent beim Zeichnen innerhalb eines Polarkoordinatensystem mit GLSL. @@ -218,7 +218,7 @@ Versuche doch einmal: Wir haben gelernt, den Radius einer Kreisform mit Hilfe der [```atan()```](../glossary/?search=atan)-Funktion in Abhängigkeit des Winkels für das Zeichnen unterschiedlicher Formen zu nutzen. Nun können wir ```atan()``` auch mit Distanzfeldern einsetzen, um ganz unterschiedliche Effekte zu erzielen. -Unser Trick nutzt die gegebene Anzahl der Seiten eines Polygons, um das benötigte Distanzfeld mit Hilfe von Polarkoordinaten zu erzeugen. Schau Dir dazu auch den [folgenden Programmcode](http://thndl.com/square-shaped-shaders.html) von [Andrew Baldwin](https://twitter.com/baldand) an. +Unser Trick nutzt die gegebene Anzahl der Seiten eines Polygons, um das benötigte Distanzfeld mit Hilfe von Polarkoordinaten zu erzeugen. Schau Dir dazu auch den [folgenden Programmcode](http://thndl.com/square-shaped-shaders.html) von [Andrew Baldwin](https://twitter.com/baldand) an.
@@ -231,4 +231,3 @@ Unser Trick nutzt die gegebene Anzahl der Seiten eines Polygons, um das benötig Herzlichen Glückwunsch! Du hast Dich durch schwieriges Fahrwasser gekämpft. Nimm eine kleine Pause, damit sich das Erlernte setzen kann. Das Zeichnen komplexer Formen im Land der Shader ist wahrlich nicht ganz trivial, das kann durchaus ein wenig erschöpfen. Da Du nun weißt, wie man unterschiedliche Formen zeichnet, kommen Dir bestimmt viele interessante Ideen in den Sinn. In den folgenden Kapiteln lernen wir, wie man Formen verschieben, skalieren und rotieren kann. Das wird Dir ermöglichen, komplexe Kompositionen zu erstellen. - diff --git a/07/README-it.md b/07/README-it.md index 9a778c3..213384a 100644 --- a/07/README-it.md +++ b/07/README-it.md @@ -19,7 +19,7 @@ Iniziamo facendo uno pseudocodice che usi la dichiarazione ```if``` sul campo d ```glsl if ( (X più grande di 1) AND (Y più grande di 1) ) colora di bianco - else + else colora di nero ``` @@ -31,13 +31,13 @@ uniform vec2 u_resolution; void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // per ogni valore restituirà 1.0 (bianco) o 0.0 (nero). float left = step(0.1,st.x); // Simile a ( X più grande di 0.1 ) float bottom = step(0.1,st.y); // Simile a ( Y più grande di 0.1 ) // La moltiplicazione di left*bottom sarà simile alla porta logica AND. - color = vec3( left * bottom ); + color = vec3( left * bottom ); gl_FragColor = vec4(color,1.0); } @@ -50,7 +50,7 @@ La funzione [```step()```](../glossary/?search=step) trasformerà ogni pixel al Nel codice precedente abbiamo ripetuto la struttura per ciascun asse (sinistra e base). Possiamo risparmiare alcune linee di codice passando due valori, invece di uno, direttamente a [```step()```](../glossary/?search=step) Ecco com’è: ```glsl - vec2 borders = step(vec2(0.1),st); + vec2 borders = step(vec2(0.1),st); float pct = borders.x * borders.y; ``` @@ -213,7 +213,7 @@ Provate a: ### Unire i poteri -Ora che abbiamo imparato come modulare il raggio di una circonferenza in relazione all’angolo, usando la funzione [```atan()```](../glossary/?search=atan) per disegnare diverse forme, possiamo imparare come usare ```atan()``` con i campi di distanza e applicare tutti i trucchi e gli effetti possibili con i campi di distanza. +Ora che abbiamo imparato come modulare il raggio di una circonferenza in relazione all’angolo, usando la funzione [```atan()```](../glossary/?search=atan) per disegnare diverse forme, possiamo imparare come usare ```atan()``` con i campi di distanza e applicare tutti i trucchi e gli effetti possibili con i campi di distanza. Il nostro trucco userà il numero di lati di un poligono per costruire il campo di distanza, usando le coordinate polari. Controllate [il seguente codice](http://thndl.com/square-shaped-shaders.html) di [Andrew Baldwin](https://twitter.com/baldand). @@ -227,4 +227,4 @@ Il nostro trucco userà il numero di lati di un poligono per costruire il campo Congratulazioni! Avete affrontato la parte più complicata! Fate una pausa per poter assimilare questi concetti: disegnare delle semplici forme con Processing è facile, ma qui no. Nella “terra degli Shader”, disegnare le forme è contorto e può essere faticoso adattarsi al nuovo paradigma di codificazione. -Ora che sapete come disegnare le forme, sono sicuro che vi verranno in mente nuove idee. Nel capitolo successivo imparerete a spostare, ruotare e ridimensionare le forme. Questo vi permetterà di fare delle composizioni! \ No newline at end of file +Ora che sapete come disegnare le forme, sono sicuro che vi verranno in mente nuove idee. Nel capitolo successivo imparerete a spostare, ruotare e ridimensionare le forme. Questo vi permetterà di fare delle composizioni! diff --git a/07/README.md b/07/README.md index 48d8fca..ecf2824 100644 --- a/07/README.md +++ b/07/README.md @@ -2,7 +2,7 @@ ## Shapes -Finally! We have been building skills for this moment! You have learned most of the GLSL foundations, types and functions. You have practiced your shaping equations over and over. Now is the time to put it all together. You are up for this challenge! In this chapter you'll learn how to draw simple shapes in a parallel procedural way. +Finally! We have been building skills for this moment! You have learned most of the GLSL foundations, types and functions. You have practiced your shaping equations over and over. Now is the time to put it all together. You are up for this challenge! In this chapter you'll learn how to draw simple shapes in a parallel procedural way. ### Rectangle @@ -10,7 +10,7 @@ Imagine we have grid paper like we used in math classes and our homework is to d ![](grid_paper.jpg) -You'd paint everything except the first and last rows and the first and last column, right? +You'd paint everything except the first and last rows and the first and last column, right? How does this relate to shaders? Each little square of our grid paper is a thread (a pixel). Each little square knows its position, like the coordinates of a chess board. In previous chapters we mapped *x* and *y* to the *red* and *green* color channels, and we learned how to use the narrow two dimensional territory between 0.0 and 1.0. How can we use this to draw a centered square in the middle of our billboard? @@ -19,7 +19,7 @@ Let's start by sketching pseudocode that uses ```if``` statements over the spati ```glsl if ( (X GREATER THAN 1) AND (Y GREATER THAN 1) ) paint white - else + else paint black ``` @@ -31,13 +31,13 @@ uniform vec2 u_resolution; void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // Each result will return 1.0 (white) or 0.0 (black). float left = step(0.1,st.x); // Similar to ( X greater than 0.1 ) float bottom = step(0.1,st.y); // Similar to ( Y greater than 0.1 ) // The multiplication of left*bottom will be similar to the logical AND. - color = vec3( left * bottom ); + color = vec3( left * bottom ); gl_FragColor = vec4(color,1.0); } @@ -50,7 +50,7 @@ The [```step()```](../glossary/?search=step) function will turn every pixel belo In the previous code we repeat the structure for each axis (left and bottom). We can save some lines of code by passing two values directly to [```step()```](../glossary/?search=step) instead of one. That looks like this: ```glsl - vec2 borders = step(vec2(0.1),st); + vec2 borders = step(vec2(0.1),st); float pct = borders.x * borders.y; ``` @@ -58,7 +58,7 @@ So far, we’ve only drawn two borders (bottom-left) of our rectangle. Let's do
-Uncomment *lines 21-22* and see how we invert the ```st``` coordinates and repeat the same [```step()```](../glossary/?search=step) function. That way the ```vec2(0.0,0.0)``` will be in the top right corner. This is the digital equivalent of flipping the page and repeating the previous procedure. +Uncomment *lines 21-22* and see how we invert the ```st``` coordinates and repeat the same [```step()```](../glossary/?search=step) function. That way the ```vec2(0.0,0.0)``` will be in the top right corner. This is the digital equivalent of flipping the page and repeating the previous procedure. ![](rect-02.jpg) @@ -90,13 +90,13 @@ 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. ![](compass.jpg) -Translating this to a shader where each square on the grid paper is a pixel implies *asking* each pixel (or thread) if it is inside the area of the circle. We do this by computing the distance from the pixel to the center of the circle. +Translating this to a shader where each square on the grid paper is a pixel implies *asking* each pixel (or thread) if it is inside the area of the circle. We do this by computing the distance from the pixel to the center of the circle. ![](circle.jpg) @@ -112,7 +112,7 @@ You can use [```distance()```](../glossary/?search=distance), [```length()```](. In the previous example we map the distance to the center of the billboard to the color brightness of the pixel. The closer a pixel is to the center, the lower (darker) value it has. Notice that the values don't get too high because from the center ( ```vec2(0.5, 0.5)``` ) the maximum distance barely goes over 0.5. Contemplate this map and think: -* What you can infer from it? +* What you can infer from it? * How we can use this to draw a circle? @@ -127,14 +127,14 @@ We can also think of the above example as an altitude map, where darker implies Basically we are using a re-interpretation of the space (based on the distance to the center) to make shapes. This technique is known as a “distance field” and is used in different ways from font outlines to 3D graphics. Try the following exercises: - + * Use [```step()```](../glossary/?search=step) to turn everything above 0.5 to white and everything below to 0.0. * Inverse the colors of the background and foreground. * Using [```smoothstep()```](../glossary/?search=smoothstep), experiment with different values to get nice smooth borders on your circle. -* Once you are happy with an implementation, make a function of it that you can reuse in the future. +* Once you are happy with an implementation, make a function of it that you can reuse in the future. * Add color to the circle. @@ -172,7 +172,7 @@ Take a look at the following code. We start by moving the coordinate system to the center and shrinking it in half in order to remap the position values between -1 and 1. Also on *line 24* we are visualizing the distance field values using a [```fract()```](../glossary/?search=fract) function making it easy to see the pattern they create. The distance field pattern repeats over and over like rings in a Zen garden. -Let’s take a look at the distance field formula on *line 19*. There we are calculating the distance to the position on ```(.3,.3)``` or ```vec3(.3)``` in all four quadrants (that’s what [```abs()```](../glossary/?search=abs) is doing there). +Let’s take a look at the distance field formula on *line 19*. There we are calculating the distance to the position on ```(.3,.3)``` or ```vec3(.3)``` in all four quadrants (that’s what [```abs()```](../glossary/?search=abs) is doing there). If you uncomment *line 20*, you will note that we are combining the distances to these four points using the [```min()```](../glossary/?search=min) to zero. The result produces an interesting new pattern. @@ -192,7 +192,7 @@ In the chapter about color we map the cartesian coordinates to polar coordinates float a = atan(pos.y,pos.x); ``` -We use part of this formula at the beginning of the chapter to draw a circle. We calculated the distance to the center using [```length()```](../glossary/?search=length). Now that we know about distance fields we can learn another way of drawing shapes using polar coordinates. +We use part of this formula at the beginning of the chapter to draw a circle. We calculated the distance to the center using [```length()```](../glossary/?search=length). Now that we know about distance fields we can learn another way of drawing shapes using polar coordinates. 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! @@ -216,7 +216,7 @@ Try to: Now that we've learned how to modulate the radius of a circle according to the angle using the [```atan()```](../glossary/?search=atan) to draw different shapes, we can learn how use ```atan()``` with distance fields and apply all the tricks and effects possible with distance fields. -The trick will use the number of edges of a polygon to construct the distance field using polar coordinates. Check out [the following code](http://thndl.com/square-shaped-shaders.html) from [Andrew Baldwin](https://twitter.com/baldand). +The trick will use the number of edges of a polygon to construct the distance field using polar coordinates. Check out [the following code](http://thndl.com/square-shaped-shaders.html) from [Andrew Baldwin](https://twitter.com/baldand).
diff --git a/07/arrow.frag b/07/arrow.frag index 581d4d4..04f1401 100644 --- a/07/arrow.frag +++ b/07/arrow.frag @@ -39,8 +39,8 @@ void main(){ st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(0.0); float d = 0.0; - + d = min(shape(st,3),shape(st+vec2(0.,0.19),4)); gl_FragColor = vec4(vec3(1.0-aastep(.2,d)),1.0); -} \ No newline at end of file +} diff --git a/07/batman.frag b/07/batman.frag index b686166..a2314b1 100644 --- a/07/batman.frag +++ b/07/batman.frag @@ -10,7 +10,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot (float y, float pct){ - return smoothstep( pct-0.01, pct, y) - + return smoothstep( pct-0.01, pct, y) - smoothstep( pct, pct+0.01, y); } @@ -35,4 +35,4 @@ void main(){ gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/07/circle-making.frag b/07/circle-making.frag index c7888bd..921ab06 100644 --- a/07/circle-making.frag +++ b/07/circle-making.frag @@ -16,17 +16,17 @@ void main(){ // a. The DISTANCE from the pixel to the center pct = distance(st,vec2(0.5)); - // b. The LENGTH of the vector - // from the pixel to the center + // b. The LENGTH of the vector + // from the pixel to the center // vec2 toCenter = vec2(0.5)-st; // pct = length(toCenter); - // c. The SQUARE ROOT of the vector - // from the pixel to the center + // c. The SQUARE ROOT of the vector + // from the pixel to the center // vec2 tC = vec2(0.5)-st; // pct = sqrt(tC.x*tC.x+tC.y*tC.y); vec3 color = vec3(pct); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/07/circle.frag b/07/circle.frag index d9b7b7e..63f5629 100644 --- a/07/circle.frag +++ b/07/circle.frag @@ -18,8 +18,8 @@ float circle(in vec2 _st, in float _radius){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; - + vec3 color = vec3(circle(st,0.9)); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/07/cross.frag b/07/cross.frag index a42d89a..080cf09 100644 --- a/07/cross.frag +++ b/07/cross.frag @@ -21,7 +21,7 @@ float box(in vec2 st, in vec2 size){ } float cross(in vec2 st, float size){ - return box(st, vec2(size,size/4.)) + + return box(st, vec2(size,size/4.)) + box(st, vec2(size/4.,size)); } @@ -29,4 +29,4 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; gl_FragColor = vec4( vec3( cross(st,0.4) ) ,1.0); -} \ No newline at end of file +} diff --git a/07/index.php b/07/index.php index 491c360..15582de 100644 --- a/07/index.php +++ b/07/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/07/line.frag b/07/line.frag index f9534c1..cf176ac 100644 --- a/07/line.frag +++ b/07/line.frag @@ -6,10 +6,10 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float line( vec2 _st, - vec2 _p1, vec2 _p2, +float line( vec2 _st, + vec2 _p1, vec2 _p2, float _width, float _spread){ - + _width = 1.0 / _width; vec2 p2p1 = _p1 - _p2; vec2 p1p2 = -(p2p1); @@ -22,8 +22,8 @@ float line( vec2 _st, float pr2 = dot(p1p2, p1p); if(pr1 > 0.0 && pr2 > 0.0) { - return pow(1.0 / abs(proj * _width), _spread); - } else { + return pow(1.0 / abs(proj * _width), _spread); + } else { return 0.0; } } @@ -37,4 +37,4 @@ void main(){ 0.005, 3.0) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/polar.frag b/07/polar.frag index 83e6efa..b6d9edf 100644 --- a/07/polar.frag +++ b/07/polar.frag @@ -27,4 +27,4 @@ void main(){ color = vec3( 1.-smoothstep(f,f+0.02,r) ); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/07/rect-df.frag b/07/rect-df.frag index 6cdf598..e5d3744 100644 --- a/07/rect-df.frag +++ b/07/rect-df.frag @@ -27,4 +27,4 @@ void main(){ // gl_FragColor = vec4(vec3( step(.3,d) ),1.0); // gl_FragColor = vec4(vec3( step(.3,d) * step(d,.4)),1.0); // gl_FragColor = vec4(vec3( smoothstep(.3,.4,d)* smoothstep(.6,.5,d)) ,1.0); -} \ No newline at end of file +} diff --git a/07/rect-making.frag b/07/rect-making.frag index 0464458..0e3eedc 100644 --- a/07/rect-making.frag +++ b/07/rect-making.frag @@ -12,16 +12,16 @@ uniform float u_time; void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // bottom-left - vec2 bl = step(vec2(0.1),st); + vec2 bl = step(vec2(0.1),st); float pct = bl.x * bl.y; - // top-right + // top-right // vec2 tr = step(vec2(0.1),1.0-st); // pct *= tr.x * tr.y; - + color = vec3(pct); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/rect.frag b/07/rect.frag index 85f2fe0..f05a935 100644 --- a/07/rect.frag +++ b/07/rect.frag @@ -21,4 +21,4 @@ void main(){ vec3 color = vec3( rect(st, vec2(0.9) ) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/shapes.frag b/07/shapes.frag index 700ac9d..6d7f5d8 100644 --- a/07/shapes.frag +++ b/07/shapes.frag @@ -27,7 +27,7 @@ void main(){ // Angle and radius from the current pixel float a = atan(st.x,st.y)+PI; float r = TWO_PI/float(N); - + // Shaping function that modulate the distance d = cos(floor(.5+a/r)*r-a)*length(st); @@ -35,4 +35,4 @@ void main(){ // color = vec3(d); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/tmp/tritri.frag b/07/tmp/tritri.frag index da6d551..af466a1 100644 --- a/07/tmp/tritri.frag +++ b/07/tmp/tritri.frag @@ -63,4 +63,4 @@ void main(){ color += shapeBorder(st+offset+vec2(0.,0.05), 3, .05, .03); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/tmp/warp-shape.frag b/07/tmp/warp-shape.frag index 7f02d91..95b438b 100644 --- a/07/tmp/warp-shape.frag +++ b/07/tmp/warp-shape.frag @@ -36,4 +36,4 @@ void main(){ d = step(.4,d); gl_FragColor = vec4(vec3(1.0-d),1.0); -} \ No newline at end of file +} diff --git a/07/triangle-making.frag b/07/triangle-making.frag index b1ccac2..18dcf44 100644 --- a/07/triangle-making.frag +++ b/07/triangle-making.frag @@ -10,7 +10,7 @@ uniform vec2 u_mouse; uniform float u_time; // Based on https://www.shadertoy.com/view/4sSSzG -float triangleDF(vec2 st, +float triangleDF(vec2 st, vec2 p0, vec2 p1, vec2 p2){ vec3 e0, e1, e2; @@ -34,9 +34,9 @@ void main(){ vec3 color = vec3(0.0); // Distance Field in 3 channels - float df = triangleDF(st, - vec2(0.40,0.45), - vec2(0.60,0.45), + float df = triangleDF(st, + vec2(0.40,0.45), + vec2(0.60,0.45), vec2(0.5,0.60)); color = vec3(df); @@ -47,4 +47,4 @@ void main(){ smoothstep(size+0.001,size+1e-7,df); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/07/triangle.frag b/07/triangle.frag index f62ab43..60212a6 100644 --- a/07/triangle.frag +++ b/07/triangle.frag @@ -10,8 +10,8 @@ uniform vec2 u_mouse; uniform float u_time; // Based on https://www.shadertoy.com/view/4sSSzG -float triangle (vec2 st, - vec2 p0, vec2 p1, vec2 p2, +float triangle (vec2 st, + vec2 p0, vec2 p1, vec2 p2, float smoothness){ vec3 e0, e1, e2; @@ -27,19 +27,19 @@ float triangle (vec2 st, float b = max(0.0, dot(e1.xy, st) - e1.z); float c = max(0.0, dot(e2.xy, st) - e2.z); - return smoothstep(smoothness * 2.0, - 1e-7, + return smoothstep(smoothness * 2.0, + 1e-7, length(vec3(a, b, c))); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; - vec3 color = vec3( triangle(st, - vec2(0.0,0.15), - vec2(1.0,0.15), - vec2(0.5,0.88), + vec3 color = vec3( triangle(st, + vec2(0.0,0.15), + vec2(1.0,0.15), + vec2(0.5,0.88), 0.001) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/README-ch.md b/08/README-ch.md index 0d0f59e..ef6c96c 100644 --- a/08/README-ch.md +++ b/08/README-ch.md @@ -75,7 +75,7 @@ mat2 scale(vec2 _scale){ } ``` -
+
试试下面的练习,尝试深入理解矩阵的工作机制: diff --git a/08/README-de.md b/08/README-de.md index b72188e..7040466 100644 --- a/08/README-de.md +++ b/08/README-de.md @@ -4,16 +4,16 @@ ### Verschieben -Im letzten Kapitel haben wir gesehen, wie man unterschiedliche Formen zeichnet. Der Trick, um diese Formen auf der Zeichenfläche beliebig zu positionieren, besteht nun darin, das Koordinatensystem „unterhalb“ dieser Formen zu verschieben. Wir erreichen dies, indem wir einfach einen Vektor zu der ```st```-Variable addieren, die die Lage des jeweiligen Objekts beim Zeichnen bestimmt. Dadurch verschiebt sich das gesamte Koordinatensystem. +Im letzten Kapitel haben wir gesehen, wie man unterschiedliche Formen zeichnet. Der Trick, um diese Formen auf der Zeichenfläche beliebig zu positionieren, besteht nun darin, das Koordinatensystem „unterhalb“ dieser Formen zu verschieben. Wir erreichen dies, indem wir einfach einen Vektor zu der ```st```-Variable addieren, die die Lage des jeweiligen Objekts beim Zeichnen bestimmt. Dadurch verschiebt sich das gesamte Koordinatensystem. ![](translate.jpg) Es ist vermutlich einfacher, das Verfahren in der Praxis nachzuvollziehen, als es in der Theorie zu studieren. Schau einfach selbst: -* Entferne die Kommentarzeichen in der *Programmzeile 35*, und Du wirst sehen, wie sich das Zeichenobjekt gemeinsam mit dem darunterliegenden Koordinatenraum bewegt. +* Entferne die Kommentarzeichen in der *Programmzeile 35*, und Du wirst sehen, wie sich das Zeichenobjekt gemeinsam mit dem darunterliegenden Koordinatenraum bewegt.
- + Jetzt versuche Dich an der folgenden Aufgabe: * Nutze ```u_time``` in Verbindung mit einer formgebenden Funktion, um das kleine Kreuz auf interessante Weise über die Zeichenfläche zu bewegen. Das Vorbild dafür kann durchaus aus der realen Welt stammen, beispielsweise eine Wellenbewegung, das Schwingen eines Pendels, ein springender Ball, ein beschleunigendes Auto oder ein stoppendes Fahrrad. @@ -30,11 +30,11 @@ Darauf basierend, wie Matrizen funktionieren, kann man Matrizen mit einem bestim ![](3dtransmat.png) -Noch interessanter wird es, wenn wir eine Matrix zur Drehung des Koordinatensystems verwenden: +Noch interessanter wird es, wenn wir eine Matrix zur Drehung des Koordinatensystems verwenden: ![](rotmat.png) -Schau Dir den folgenden Programmcode an, der die benötigte Matrix für eine Rotation des Koordinatensystems um einen vorgegebenen Winkel produziert. Diese Funktion folgt der obigen Formel für zweidimensionale Vektoren, um die Koordinaten um einen ```vec2(0.0)```-Punkt rotieren zu lassen. +Schau Dir den folgenden Programmcode an, der die benötigte Matrix für eine Rotation des Koordinatensystems um einen vorgegebenen Winkel produziert. Diese Funktion folgt der obigen Formel für zweidimensionale Vektoren, um die Koordinaten um einen ```vec2(0.0)```-Punkt rotieren zu lassen. ```glsl mat2 rotate2d(float _angle){ @@ -57,11 +57,11 @@ Probiere die folgenden Übungen aus: * Kommentiere das Verschieben vor und nach der Rotation in den *Zeilen 37 und 39* aus und beobachte die Konsequenzen. -* Nutze Rotationen, um die Animation zu verbessern, die Du beim Beispiel zum Verschieben erstellt hast. +* Nutze Rotationen, um die Animation zu verbessern, die Du beim Beispiel zum Verschieben erstellt hast. ### Skalieren -Wir haben gesehen, wie man die Verschiebung und die Rotation von Objekten realisiert, indem man mit Matrizen auf den Koordinatenraum einwirkt. Falls Du bereits mit 3D-Modellierungssoftware oder den Matrizenfunktionen in Procesing gearbeitet hast, weißt Du wahrscheinlich, dass man Matrizen auch für die Skalierung von Objekten verwenden kann. +Wir haben gesehen, wie man die Verschiebung und die Rotation von Objekten realisiert, indem man mit Matrizen auf den Koordinatenraum einwirkt. Falls Du bereits mit 3D-Modellierungssoftware oder den Matrizenfunktionen in Procesing gearbeitet hast, weißt Du wahrscheinlich, dass man Matrizen auch für die Skalierung von Objekten verwenden kann. ![](scale.png) @@ -74,7 +74,7 @@ mat2 scale(vec2 _scale){ } ``` -
+
Probiere die folgenden Übungen aus, um noch besser zu verstehen, wie das Ganze funktioniert. diff --git a/08/README-it.md b/08/README-it.md index 128c300..3f11bf7 100644 --- a/08/README-it.md +++ b/08/README-it.md @@ -74,7 +74,7 @@ mat2 scale(vec2 _scale){ } ``` -
+
Provate i seguenti esercizi per capirne il funzionamento. diff --git a/08/README-jp.md b/08/README-jp.md index ef0883d..a8d86cc 100644 --- a/08/README-jp.md +++ b/08/README-jp.md @@ -100,4 +100,3 @@ mat2 scale(vec2 _scale){ 見てのとおり色をベクトルとして扱い行列を掛け合わせています。このようにして色の値を「動かす」ことができるのです。 この章では行列を使ってベクトルを移動、回転、拡大・縮小する方法を学びました。これらの変形は、前章で学んだ図形を組み合わせてより複雑な図を作成するのに欠かせない技術です。次の章ではこれまで学んだことを全て活かして、規則に基づいた美しいパターンを作成します。コードによる反復と変化の楽しさを発見しましょう。 - diff --git a/08/README.md b/08/README.md index ccb2eac..9f5b764 100644 --- a/08/README.md +++ b/08/README.md @@ -4,7 +4,7 @@ ### Translate -In the previous chapter we learned how to make some shapes - the trick to moving those shapes is to move the coordinate system itself. We can achieve that by simply adding a vector to the ```st``` variable that contains the location of each fragment. This causes the whole space coordinate system to move. +In the previous chapter we learned how to make some shapes - the trick to moving those shapes is to move the coordinate system itself. We can achieve that by simply adding a vector to the ```st``` variable that contains the location of each fragment. This causes the whole space coordinate system to move. ![](translate.jpg) @@ -13,7 +13,7 @@ This is easier to see than to explain, so to see for yourself: * Uncomment line 35 of the code below to see how the space itself moves around.
- + Now try the following exercise: * Using ```u_time``` together with the shaping functions move the small cross around in an interesting way. Search for a specific quality of motion you are interested in and try to make the cross move in the same way. Recording something from the "real world" first might be useful - it could be the coming and going of waves, a pendulum movement, a bouncing ball, a car accelerating, a bicycle stopping. @@ -30,11 +30,11 @@ Based on how matrices behave it's possible to construct matrices to produce spec ![](3dtransmat.png) -More interestingly, we can use a matrix to rotate the coordinate system: +More interestingly, we can use a matrix to rotate the coordinate system: ![](rotmat.png) -Take a look at the following code for a function that constructs a 2D rotation matrix. This function follows the above [formula](http://en.wikipedia.org/wiki/Rotation_matrix) for two dimentional vectors to rotate the coordinates around the ```vec2(0.0)``` point. +Take a look at the following code for a function that constructs a 2D rotation matrix. This function follows the above [formula](http://en.wikipedia.org/wiki/Rotation_matrix) for two dimentional vectors to rotate the coordinates around the ```vec2(0.0)``` point. ```glsl mat2 rotate2d(float _angle){ @@ -57,11 +57,11 @@ Try the following exercises: * Comment the translations before and after the rotation, on lines 37 and 39, and observe the consequences. -* Use rotations to improve the animation you simulated in the translation exercise. +* Use rotations to improve the animation you simulated in the translation exercise. ### Scale -We've seen how matrices are used to translate and rotate objects in space. (Or more precisely to transform the coordinate system to rotate and move the objects.) If you've used 3D modeling software or the push and pop matrix functions in Processing, you will know that matrices can also be used to scale the size of an object. +We've seen how matrices are used to translate and rotate objects in space. (Or more precisely to transform the coordinate system to rotate and move the objects.) If you've used 3D modeling software or the push and pop matrix functions in Processing, you will know that matrices can also be used to scale the size of an object. ![](scale.png) @@ -74,7 +74,7 @@ mat2 scale(vec2 _scale){ } ``` -
+
Try the following exercises to understand more deeply how this works. diff --git a/08/cross-animated.frag b/08/cross-animated.frag index 5f3f313..f7c9f1f 100644 --- a/08/cross-animated.frag +++ b/08/cross-animated.frag @@ -26,21 +26,21 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size,_size/4.)) + + return box(_st, vec2(_size,_size/4.)) + box(_st, vec2(_size/4.,_size)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // move space from the center to the vec2(0.0) st -= vec2(0.5); // rotate the space st = rotate2d( sin(u_time*0.5)*PI ) * st; // move it back to the original place st += vec2(0.5); - + // To move the cross we move the space vec2 translate = vec2(cos(u_time),sin(u_time)); st += translate*0.35; @@ -52,4 +52,4 @@ void main(){ color += vec3(cross(st,0.25)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/cross-rotate.frag b/08/cross-rotate.frag index b20686a..df1e5d6 100644 --- a/08/cross-rotate.frag +++ b/08/cross-rotate.frag @@ -26,14 +26,14 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size,_size/4.)) + + return box(_st, vec2(_size,_size/4.)) + box(_st, vec2(_size/4.,_size)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // move space from the center to the vec2(0.0) st -= vec2(0.5); // rotate the space @@ -48,4 +48,4 @@ void main(){ color += vec3(cross(st,0.4)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/cross-scale.frag b/08/cross-scale.frag index 703e96f..4cbfe46 100644 --- a/08/cross-scale.frag +++ b/08/cross-scale.frag @@ -26,14 +26,14 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size,_size/4.)) + + return box(_st, vec2(_size,_size/4.)) + box(_st, vec2(_size/4.,_size)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + st -= vec2(0.5); st = scale( vec2(sin(u_time)+1.0) ) * st; st += vec2(0.5); @@ -45,4 +45,4 @@ void main(){ color += vec3(cross(st,0.2)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/cross-translate.frag b/08/cross-translate.frag index c7fad90..60fccb6 100644 --- a/08/cross-translate.frag +++ b/08/cross-translate.frag @@ -19,14 +19,14 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size,_size/4.)) + + return box(_st, vec2(_size,_size/4.)) + box(_st, vec2(_size/4.,_size)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // To move the cross we move the space vec2 translate = vec2(cos(u_time),sin(u_time)); st += translate*0.35; @@ -38,4 +38,4 @@ void main(){ color += vec3(cross(st,0.25)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/cross.frag b/08/cross.frag index ab317f7..4f0792b 100644 --- a/08/cross.frag +++ b/08/cross.frag @@ -24,4 +24,4 @@ void main(){ vec3 color = vec3( box(st, vec2(0.4,0.1)) + box(st, vec2(0.1,0.4)) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/index.php b/08/index.php index 9ae20b0..e9b3539 100644 --- a/08/index.php +++ b/08/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); -?> \ No newline at end of file + include($path."/footer.php"); +?> diff --git a/08/matrices.frag b/08/matrices.frag index 1688e34..04c2f65 100644 --- a/08/matrices.frag +++ b/08/matrices.frag @@ -80,4 +80,4 @@ mat4 translate4D(float x, float y, float z){ vec4(0.0, 0.0, 1.0, 0.0), vec4(x, y, z, 1.0) ); -} \ No newline at end of file +} diff --git a/08/matrix.frag b/08/matrix.frag index 63dbabe..fa25838 100644 --- a/08/matrix.frag +++ b/08/matrix.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; @@ -31,7 +31,7 @@ vec3 matrix(in vec2 st){ ipos += vec2(.0,floor(u_time*20.*random(ipos.x))); - + vec2 fpos = fract(st*rows); vec2 center = (.5-fpos); @@ -50,4 +50,4 @@ void main(){ color = matrix(st); gl_FragColor = vec4( 1.-color , 1.0); -} \ No newline at end of file +} diff --git a/08/tmp/circleWave.frag b/08/tmp/circleWave.frag index 7309a08..4fb0996 100644 --- a/08/tmp/circleWave.frag +++ b/08/tmp/circleWave.frag @@ -39,4 +39,4 @@ void main() { color = mix(color,vec3(1.0),circleWaveLine(st,0.8,0.02)); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/08/tmp/circleWave2.frag b/08/tmp/circleWave2.frag index 6bcd801..af0eba8 100644 --- a/08/tmp/circleWave2.frag +++ b/08/tmp/circleWave2.frag @@ -47,4 +47,4 @@ void main() { color += vec3(0.489,0.630,1.000) * circleWaveLine(st,size,width) * alpha; gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/08/tmp/cross-doted.frag b/08/tmp/cross-doted.frag index 2eb4f23..b2d15c3 100644 --- a/08/tmp/cross-doted.frag +++ b/08/tmp/cross-doted.frag @@ -38,7 +38,7 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(0.0); - + st -= vec2(0.5); st = rotate2d( sin(u_time)*PI ) * st; st += vec2(0.5); @@ -47,4 +47,4 @@ void main(){ color += cross(st,(1.0-abs(sin(u_time)))*.5); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/08/tmp/cross.frag b/08/tmp/cross.frag index 0c4c8de..992a307 100644 --- a/08/tmp/cross.frag +++ b/08/tmp/cross.frag @@ -23,4 +23,4 @@ void main(){ float pct = box(st, vec2(0.9,0.3)) + box(st, vec2(0.3,0.9)); gl_FragColor = vec4( vec3(1.-pct),pct ); -} \ No newline at end of file +} diff --git a/08/tmp/linesWave.frag b/08/tmp/linesWave.frag index 4584767..63176b1 100644 --- a/08/tmp/linesWave.frag +++ b/08/tmp/linesWave.frag @@ -32,4 +32,4 @@ void main() { pattern = mix(stripes(st,-0.786375),stripes(st,0.786375),pattern); gl_FragColor = vec4( vec3(smoothstep(.4,.5,pattern)), 1.0 ); -} \ No newline at end of file +} diff --git a/08/yuv.frag b/08/yuv.frag index 7ab282f..1991ce9 100644 --- a/08/yuv.frag +++ b/08/yuv.frag @@ -8,13 +8,13 @@ uniform vec2 u_resolution; uniform float u_time; // YUV to RGB matrix -mat3 yuv2rgb = mat3(1.0, 0.0, 1.13983, - 1.0, -0.39465, -0.58060, +mat3 yuv2rgb = mat3(1.0, 0.0, 1.13983, + 1.0, -0.39465, -0.58060, 1.0, 2.03211, 0.0); // RGB to YUV matrix mat3 rgb2yuv = mat3(0.2126, 0.7152, 0.0722, - -0.09991, -0.33609, 0.43600, + -0.09991, -0.33609, 0.43600, 0.615, -0.5586, -0.05639); void main(){ @@ -22,14 +22,14 @@ void main(){ vec3 color = vec3(0.0); // UV values goes from -1 to 1 - // So we need to remap st (0.0 to 1.0) + // So we need to remap st (0.0 to 1.0) st -= 0.5; // becomes -0.5 to 0.5 st *= 2.0; // becomes -1.0 to 1.0 - // we pass st as the y & z values of + // we pass st as the y & z values of // a three dimentional vector to be // properly multiply by a 3x3 matrix color = yuv2rgb * vec3(0.5, st.x, st.y); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/README-ch.md b/09/README-ch.md index de313b9..c594cb9 100755 --- a/09/README-ch.md +++ b/09/README-ch.md @@ -34,7 +34,7 @@ void main(){ * 把画布分成 3 行 3 列。 指出如何定义行和列的线程的,并用这种方式改变显示着的图形。试着做一个井字棋。 -### 在图案内部应用矩阵 +### 在图案内部应用矩阵 鉴于每个细分或者说单元都是我们正在使用的单位化坐标系的小单元,我们可以对每个内部空间施以矩阵变换来平移,旋转和缩放。 diff --git a/09/README-de.md b/09/README-de.md index a64c5bc..2b7140d 100644 --- a/09/README-de.md +++ b/09/README-de.md @@ -1,6 +1,6 @@ ## Muster -Weil Shader-Programme Bildpunkt für Bildpunkt ausgeführt werden, spielt es keine große Rolle, wie oft man ein bestimmtes Muster innerhalb der Zeichenfläche wiederholt – die Anzahl der Berechnungen bleibt gleich. Aus diesem Grund eignen sich Fragment-Shader ganz hervorragend für die Erzeugung sich wiederholender Kachelmuster. +Weil Shader-Programme Bildpunkt für Bildpunkt ausgeführt werden, spielt es keine große Rolle, wie oft man ein bestimmtes Muster innerhalb der Zeichenfläche wiederholt – die Anzahl der Berechnungen bleibt gleich. Aus diesem Grund eignen sich Fragment-Shader ganz hervorragend für die Erzeugung sich wiederholender Kachelmuster. [ ![Nina Warmerdam – Das IMPRINT Projekt (2013)](warmerdam.jpg) ](../edit.php#09/dots5.frag) @@ -86,7 +86,7 @@ Wir haben nun gelernt, wie man feststellt, ob sich die zu zeichnende Gitterzelle ![](truchet-00.png) -Indem wir die Anordnung des Musters von Kachel zu Kachel variieren, können wir eine unendliche Menge von Designs erzeugen. +Indem wir die Anordnung des Musters von Kachel zu Kachel variieren, können wir eine unendliche Menge von Designs erzeugen. ![](truchet-01.png) @@ -108,9 +108,8 @@ Schaue Die die Funktion ```rotateTilePattern()``` genau an. Sie unterteilt den R ## Erschaffe Deine eigenen Regeln -Prozedurale, sich wiederholende Muster zu kreieren, ist eine interessante Übung für den Geist. Es geht darum, den minimalen Satz an Elementen zu finden, die sich wiederholen müssen, um ein größeres komplexes Ganzes zu erschaffen. Diese Vorgehensweise ist sehr alt. Die Menschheit benutzt Muster und Gitternetze schon seit tausenden von Jahren, um Wände und Böden, Textilien und andere Objekte zu verzieren. Angefangen von mäandernden Mustern im alten Griechenland bis hin zu chinesischen Gitterfenstern, ist es immer wieder das Spiel aus Wiederholung bei gleichzeitiger Variation, die unsere Fantasie anregt. Nimm Dir ein wenig Zeit, um diese Art von [Dekorationen](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) und [Mustern](https://www.pinterest.com/patriciogonzv/paterns/) zu studieren. Von geometrischen Mustern aus Arabien bis hin zu prachtvollen Stoffmustern aus dem afrikanischem Kulturkreis eröffnet sich Dir ein ganzes Universum an Mustern, von denen Du lernen kannst. +Prozedurale, sich wiederholende Muster zu kreieren, ist eine interessante Übung für den Geist. Es geht darum, den minimalen Satz an Elementen zu finden, die sich wiederholen müssen, um ein größeres komplexes Ganzes zu erschaffen. Diese Vorgehensweise ist sehr alt. Die Menschheit benutzt Muster und Gitternetze schon seit tausenden von Jahren, um Wände und Böden, Textilien und andere Objekte zu verzieren. Angefangen von mäandernden Mustern im alten Griechenland bis hin zu chinesischen Gitterfenstern, ist es immer wieder das Spiel aus Wiederholung bei gleichzeitiger Variation, die unsere Fantasie anregt. Nimm Dir ein wenig Zeit, um diese Art von [Dekorationen](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) und [Mustern](https://www.pinterest.com/patriciogonzv/paterns/) zu studieren. Von geometrischen Mustern aus Arabien bis hin zu prachtvollen Stoffmustern aus dem afrikanischem Kulturkreis eröffnet sich Dir ein ganzes Universum an Mustern, von denen Du lernen kannst. ![Franz Sales Meyer – Handbuch der Ornamentik (1920)](geometricpatters.png) Mit diesem Kapitel enden die Abschnitte zum algorithmischen Zeichnen. In den folgenden Kapiteln werden wir sehen, wie man ein wenig mehr Zufall in unsere Shader bringt, um die Natur nachzuempfinden. - diff --git a/09/README-it.md b/09/README-it.md index c983dbe..6c07f85 100644 --- a/09/README-it.md +++ b/09/README-it.md @@ -34,7 +34,7 @@ Provate alcuni dei seguenti esercizi per capire meglio: * Suddividete lo spazio in 3 righe e 3 colonne. Trovate un modo di sapere in quale colonna e quale riga si trova il thread e usatelo per cambiare la forma che è mostrata. Provate a creare una griglia per il tris. -### Applicare le matrici all'interno dei motivi +### Applicare le matrici all'interno dei motivi Siccome ciascuna suddivisione, o cella, è una versione più piccola del sistema normalizzato di coordinate che abbiamo già usato, possiamo applicarle una trasformazione matrice per traslare, ruotare o ridimensionare lo spazio interno. @@ -116,4 +116,4 @@ Creare motivi procedurali è un esercizio mentale nel trovare il più piccole el ![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png) -Con questo capitolo terminiamo la sezione sul disegno algoritmico. Nei prossimi capitoli impareremo a portare dell'entropia nei nostri shader e a produrre motivi generativi. \ No newline at end of file +Con questo capitolo terminiamo la sezione sul disegno algoritmico. Nei prossimi capitoli impareremo a portare dell'entropia nei nostri shader e a produrre motivi generativi. diff --git a/09/README.md b/09/README.md index 6240e47..eaf8728 100644 --- a/09/README.md +++ b/09/README.md @@ -1,10 +1,10 @@ ## Patterns -Since shader programs are executed by pixel-by-pixel no matter how much you repeat a shape the number of calculations stays constant. This means that fragment shaders are particulary suitable for tile patterns. +Since shader programs are executed by pixel-by-pixel no matter how much you repeat a shape the number of calculations stays constant. This means that fragment shaders are particulary suitable for tile patterns. [ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.php#09/dots5.frag) -In this chapter we are going to apply what we've learned so far and repeat it along a canvas. Like in previous chapters, our strategy will be based on multiplying the space coordinates (between 0.0 and 1.0), so that the shapes we draw between the values 0.0 and 1.0 will be repeated to make a grid. +In this chapter we are going to apply what we've learned so far and repeat it along a canvas. Like in previous chapters, our strategy will be based on multiplying the space coordinates (between 0.0 and 1.0), so that the shapes we draw between the values 0.0 and 1.0 will be repeated to make a grid. *"The grid provides a framework within which human intuition and invention can operate and that it can subvert. Within the chaos of nature patterns provide a constrast and promise of order. From early patterns on pottery to geometric mosaics in Roman baths, people have long used grids to enhance their lives with decoration."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/) @@ -34,9 +34,9 @@ Try some of the following exercises to get a deeper understanding: * Divide the space into 3 rows and 3 columns. Find a way to know in which column and row the thread is and use that to change the shape that is displaying. Try to compose a tic-tac-toe match. -### Apply matrices inside patterns +### Apply matrices inside patterns -Since each subdivision or cell is a smaller version of the normalized coordinate system we have already been using, we can apply a matrix transformation to it in order to translate, rotate or scale the space inside. +Since each subdivision or cell is a smaller version of the normalized coordinate system we have already been using, we can apply a matrix transformation to it in order to translate, rotate or scale the space inside.
@@ -91,7 +91,7 @@ Now that we've learned how to tell if our cell is in an even or odd row or colum ![](truchet-00.png) -By changing the pattern across tiles, it's possible to construct an infinite set of complex designs. +By changing the pattern across tiles, it's possible to construct an infinite set of complex designs. ![](truchet-01.png) @@ -113,7 +113,7 @@ Pay close attention to the function ```rotateTilePattern()```, which subdivides ## Making your own rules -Making procedural patterns is a mental exercise in finding minimal reusable elements. This practice is old; we as a species have been using grids and patterns to decorate textiles, floors and borders of objects for a long time: from meanders patterns in ancient Greece, to Chinese lattice design, the pleasure of repetition and variation catches our imagination. Take some time to look at [decorative](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [patterns](https://www.pinterest.com/patriciogonzv/paterns/) and see how artists and designers have a long history of navigating the fine edge between the predictability of order and the surprise of variation and chaos. From Arabic geometrical patterns, to gorgeous African fabric designs, there is an entire universe of patterns to learn from. +Making procedural patterns is a mental exercise in finding minimal reusable elements. This practice is old; we as a species have been using grids and patterns to decorate textiles, floors and borders of objects for a long time: from meanders patterns in ancient Greece, to Chinese lattice design, the pleasure of repetition and variation catches our imagination. Take some time to look at [decorative](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [patterns](https://www.pinterest.com/patriciogonzv/paterns/) and see how artists and designers have a long history of navigating the fine edge between the predictability of order and the surprise of variation and chaos. From Arabic geometrical patterns, to gorgeous African fabric designs, there is an entire universe of patterns to learn from. ![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png) diff --git a/09/bricks.frag b/09/bricks.frag index bff66de..9aef79f 100644 --- a/09/bricks.frag +++ b/09/bricks.frag @@ -40,4 +40,4 @@ void main(void){ // color = vec3(st,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/checks.frag b/09/checks.frag index 6d22549..118fcf2 100644 --- a/09/checks.frag +++ b/09/checks.frag @@ -45,4 +45,4 @@ void main(void){ // color = vec3(st,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/cross.frag b/09/cross.frag index 1566f81..7fa15a1 100644 --- a/09/cross.frag +++ b/09/cross.frag @@ -25,7 +25,7 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size*0.5,_size*0.125)) + + return box(_st, vec2(_size*0.5,_size*0.125)) + box(_st, vec2(_size*0.125,_size*0.5)); } @@ -37,4 +37,4 @@ void main(){ vec3 color = vec3( clamp(cross(fract(st),0.3),0.0,1.0) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/deco.frag b/09/deco.frag index 908bc61..307fd20 100644 --- a/09/deco.frag +++ b/09/deco.frag @@ -31,7 +31,7 @@ void main(){ vec3 color = vec3(0.0); st = mirrorTile(st,10.); - float x = st.x*2.; + float x = st.x*2.; float a = floor(1.+sin(x*3.14)); float b = floor(1.+sin((x+1.)*3.14)); float f = fract(x); @@ -39,4 +39,4 @@ void main(){ color = vec3( fillY(st,mix(a,b,f),0.01) ); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/09/diamondtiles.frag b/09/diamondtiles.frag index d727d66..70a7ad9 100644 --- a/09/diamondtiles.frag +++ b/09/diamondtiles.frag @@ -1,4 +1,4 @@ -// Author @patriciogv ( patriciogonzalezvivo.com ) - 2015 +// Author @patriciogv ( patriciogonzalezvivo.com ) - 2015 // Title: Diamond Tiles #ifdef GL_ES @@ -38,13 +38,13 @@ vec2 offset(vec2 _st, vec2 _offset){ uv.x = _st.x - 0.5; } else { uv.x = _st.x + 0.5; - } + } if(_st.y>0.5){ uv.y = _st.y - 0.5; } else { uv.y = _st.y + 0.5; - } + } return uv; } @@ -61,5 +61,5 @@ void main(void){ vec3 color = vec3( box(offsetSt,vec2(0.95),0.01) - box(st,vec2(0.3),0.01) + 2.*box(st,vec2(0.2),0.01) ); - gl_FragColor = vec4(color,1.0); -} \ No newline at end of file + gl_FragColor = vec4(color,1.0); +} diff --git a/09/dots.frag b/09/dots.frag index 3604a74..77ed704 100644 --- a/09/dots.frag +++ b/09/dots.frag @@ -27,4 +27,4 @@ void main(){ vec3 color = vec3(circle(st, 0.2)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/dots1.frag b/09/dots1.frag index 4f31a56..c62bb0d 100644 --- a/09/dots1.frag +++ b/09/dots1.frag @@ -30,4 +30,4 @@ void main(){ circle(st+vec2(.5,0.), 0.35)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/dots2.frag b/09/dots2.frag index 3117bd7..1f8a7e1 100644 --- a/09/dots2.frag +++ b/09/dots2.frag @@ -28,9 +28,9 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + st = brickTile(st,5.); vec3 color = vec3(1.0-circle(st, 0.11)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/dots3.frag b/09/dots3.frag index d1363e4..d97fba3 100644 --- a/09/dots3.frag +++ b/09/dots3.frag @@ -31,11 +31,11 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + st = brickMirrorTile(st,5.); - vec3 color = vec3(circle(st+vec2(0.,0.05), 0.007)+ - circle(st+vec2(0.075,-0.07), 0.007)+ + vec3 color = vec3(circle(st+vec2(0.,0.05), 0.007)+ + circle(st+vec2(0.075,-0.07), 0.007)+ circle(st+vec2(-0.075,-0.07), 0.007)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/dots4.frag b/09/dots4.frag index d35a54e..8148f5b 100644 --- a/09/dots4.frag +++ b/09/dots4.frag @@ -30,12 +30,12 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + st = brickTile(st,5.); - vec3 color = vec3(circle(st+vec2(0.,0.1), 0.007)+ - circle(st+vec2(0.00,-0.1), 0.007)+ - circle(st+vec2(-0.1,0.), 0.007)+ + vec3 color = vec3(circle(st+vec2(0.,0.1), 0.007)+ + circle(st+vec2(0.00,-0.1), 0.007)+ + circle(st+vec2(-0.1,0.), 0.007)+ circle(st+vec2(0.1,0), 0.007)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/dots5.frag b/09/dots5.frag index 4ccb880..3803d7a 100644 --- a/09/dots5.frag +++ b/09/dots5.frag @@ -41,4 +41,4 @@ void main(){ color = mix(color, vec3(0.761,0.247,0.102), circlePattern(grid2,0.2)) - circlePattern(grid2,0.05), gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/grid-making.frag b/09/grid-making.frag index 48e0962..1b6b3b8 100644 --- a/09/grid-making.frag +++ b/09/grid-making.frag @@ -25,8 +25,6 @@ void main() { color = vec3(st,0.0); //color = vec3(circle(st,0.5)); - + gl_FragColor = vec4(color,1.0); } - - diff --git a/09/grid-side.frag b/09/grid-side.frag index 9ce6dae..a671ff9 100644 --- a/09/grid-side.frag +++ b/09/grid-side.frag @@ -29,8 +29,8 @@ float X(vec2 _st, float _width){ void main(void){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st = tile(st,10.0); - + vec3 color = vec3(X(st,0.03)); - gl_FragColor = vec4(color,1.0); -} \ No newline at end of file + gl_FragColor = vec4(color,1.0); +} diff --git a/09/grid.frag b/09/grid.frag index a90335b..df314b1 100644 --- a/09/grid.frag +++ b/09/grid.frag @@ -23,7 +23,7 @@ void main(void){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - // Repat the space + // Repat the space st = tile(st,10.0); // Draw a rectangle in each one @@ -32,5 +32,5 @@ void main(void){ // Show the space coordinates // color = vec3(st,0.0); - gl_FragColor = vec4(color,1.0); -} \ No newline at end of file + gl_FragColor = vec4(color,1.0); +} diff --git a/09/iching-01.frag b/09/iching-01.frag index 72cdd7c..92906ff 100644 --- a/09/iching-01.frag +++ b/09/iching-01.frag @@ -70,10 +70,10 @@ void main(){ st *= 10.0; vec2 fpos = fract(st); vec2 ipos = floor(st); - + float t = u_time*5.0; float df = 1.0; df = hex(fpos,ipos.x+ipos.y+t)+(1.0-rect(fpos,vec2(0.7))); gl_FragColor = vec4(mix(vec3(0.),vec3(1.),step(0.7,df)),1.0); -} \ No newline at end of file +} diff --git a/09/index.php b/09/index.php index f8612e5..b7c3eff 100644 --- a/09/index.php +++ b/09/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> - diff --git a/09/lines-wave.frag b/09/lines-wave.frag index 8162b06..ba0d486 100644 --- a/09/lines-wave.frag +++ b/09/lines-wave.frag @@ -27,9 +27,9 @@ float line(vec2 st, float width) { void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + st *= 10.; st = wave(st, 3.); vec3 color = vec3(line(st,.5)); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/09/lines.frag b/09/lines.frag index 3280a44..c423f2f 100644 --- a/09/lines.frag +++ b/09/lines.frag @@ -23,7 +23,7 @@ float stripes(vec2 st){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(stripes(st)); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/09/marching_dots.frag b/09/marching_dots.frag index 54337ac..e1ebd25 100644 --- a/09/marching_dots.frag +++ b/09/marching_dots.frag @@ -18,13 +18,13 @@ vec2 movingTiles(vec2 _st, float _zoom, float _speed){ _st.x += fract(time)*2.0; } else { _st.x -= fract(time)*2.0; - } + } } else { if (fract( _st.x * 0.5) > 0.5){ _st.y += fract(time)*2.0; } else { _st.y -= fract(time)*2.0; - } + } } return fract(_st); } @@ -43,4 +43,4 @@ void main() { vec3 color = vec3( 1.0-circle(st, 0.3 ) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/mirrortiles.frag b/09/mirrortiles.frag index a56e307..a23f40f 100644 --- a/09/mirrortiles.frag +++ b/09/mirrortiles.frag @@ -33,4 +33,4 @@ void main(){ color = vec3(fillY(st,0.5+sin(st.x*PI*2.0)*0.45,0.02)); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/09/nuts.frag b/09/nuts.frag index bb1c04b..a20bc5b 100644 --- a/09/nuts.frag +++ b/09/nuts.frag @@ -46,4 +46,4 @@ void main(){ vec3 color = vec3( 1.0-smoothstep( 0.5,0.6, pow(pct,st.y) ) * 1.0-smoothstep( 0.79,0.81, pow(pct,2.0-st.y ) ) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/rotatedtiles.frag b/09/rotatedtiles.frag index 99189b4..5988124 100644 --- a/09/rotatedtiles.frag +++ b/09/rotatedtiles.frag @@ -26,7 +26,7 @@ vec2 tile (vec2 _st, float _zoom) { vec2 rotateTile(vec2 _st){ _st *= 2.0; - float index = 0.0; + float index = 0.0; if (fract(_st.x * 0.5) > 0.5){ index += 1.0; } @@ -48,8 +48,8 @@ vec2 rotateTile(vec2 _st){ } // Based on https://www.shadertoy.com/view/4sSSzG -float triangle (vec2 _st, - vec2 _p0, vec2 _p1, vec2 _p2, +float triangle (vec2 _st, + vec2 _p0, vec2 _p1, vec2 _p2, float _smoothness) { vec3 e0, e1, e2; @@ -65,8 +65,8 @@ float triangle (vec2 _st, float b = max(0.0, dot(e1.xy, _st) - e1.z); float c = max(0.0, dot(e2.xy, _st) - e2.z); - return smoothstep(_smoothness * 2.0, - 1e-7, + return smoothstep(_smoothness * 2.0, + 1e-7, length(vec3(a, b, c))); } @@ -75,17 +75,17 @@ void main (void) { st = tile(st,3.0); st = rotateTile(st); - + float pattern = 0.0; st = rotate2D(st,-PI*u_time*0.25); - pattern = triangle(st, - vec2(0.30,-0.5), - vec2(0.70,0.-0.5), - vec2(0.5,1.0), + pattern = triangle(st, + vec2(0.30,-0.5), + vec2(0.70,0.-0.5), + vec2(0.5,1.0), 0.01); vec3 color = vec3(pattern); - gl_FragColor = vec4(color,1.0); -} \ No newline at end of file + gl_FragColor = vec4(color,1.0); +} diff --git a/09/tmp/checker.frag b/09/tmp/checker.frag index 00251a5..910a707 100644 --- a/09/tmp/checker.frag +++ b/09/tmp/checker.frag @@ -29,4 +29,4 @@ void main(){ pct += abs(mod(st_i.x,2.)-mod(st_i.y,2.)); gl_FragColor = vec4(vec3(pct),1.0); -} \ No newline at end of file +} diff --git a/09/tmp/dots-animation.frag b/09/tmp/dots-animation.frag index cb66e55..ed105cd 100644 --- a/09/tmp/dots-animation.frag +++ b/09/tmp/dots-animation.frag @@ -28,11 +28,11 @@ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec2 pos = vec2(0.5)-st; st = brickTile(st,20.); - + float t = u_time*.5; float r = dot(pos,pos)*4.; @@ -42,4 +42,4 @@ void main(){ vec3 color = vec3(circle(st, pattern)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/tmp/dots-texture.frag b/09/tmp/dots-texture.frag index 58441bf..5d9932a 100644 --- a/09/tmp/dots-texture.frag +++ b/09/tmp/dots-texture.frag @@ -39,9 +39,9 @@ void main(){ st.x += 0.5; pos.x += 0.5/grid; } - + float pattern = texture2D(u_tex0,clamp(floor(pos*grid)/grid+vec2(.5,.5)/grid,vec2(0.),vec2(1.))).r; pattern = circle(fract(st), smoothstep(0.1,1.,pattern)); gl_FragColor = vec4(pattern,0.,0.,pattern); -} \ No newline at end of file +} diff --git a/09/tmp/dots-tide.frag b/09/tmp/dots-tide.frag index d704fda..6a0b78a 100644 --- a/09/tmp/dots-tide.frag +++ b/09/tmp/dots-tide.frag @@ -30,4 +30,4 @@ void main(){ pct += circle(st,size); gl_FragColor = vec4(vec3(pct),1.0); -} \ No newline at end of file +} diff --git a/09/tmp/dots-zoom-00.frag b/09/tmp/dots-zoom-00.frag index bbf18af..03518b1 100644 --- a/09/tmp/dots-zoom-00.frag +++ b/09/tmp/dots-zoom-00.frag @@ -18,7 +18,7 @@ float aastep(float threshold, float value) { return smoothstep(threshold-afwidth, threshold+afwidth, value); #else return step(threshold, value); - #endif + #endif } vec2 brickTile(vec2 st, float zoom){ st *= zoom; @@ -53,7 +53,7 @@ void main(){ vec2 IN = st; vec2 OUT = st*2.; - + float pct = 1.0-fract(u_mouse.y/u_resolution.y); pct = pow(pct,6.); @@ -65,4 +65,4 @@ void main(){ color = vec3(d); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/tmp/dots-zoom-01.frag b/09/tmp/dots-zoom-01.frag index 7df2b6b..7ab6421 100644 --- a/09/tmp/dots-zoom-01.frag +++ b/09/tmp/dots-zoom-01.frag @@ -18,7 +18,7 @@ float aastep(float threshold, float value) { return smoothstep(threshold-afwidth, threshold+afwidth, value); #else return step(threshold, value); - #endif + #endif } vec2 brickTile(vec2 st, float zoom){ st *= zoom; @@ -39,7 +39,7 @@ void main(){ vec2 IN = st; vec2 OUT = st*2.; - + float pct = 1.0-fract(u_mouse.y/u_resolution.y); float A = circleDF(vec2(0.5)-st); @@ -55,4 +55,4 @@ void main(){ color = vec3(d); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/tmp/dots.frag b/09/tmp/dots.frag index 3604a74..77ed704 100644 --- a/09/tmp/dots.frag +++ b/09/tmp/dots.frag @@ -27,4 +27,4 @@ void main(){ vec3 color = vec3(circle(st, 0.2)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/tmp/grid-fine.frag b/09/tmp/grid-fine.frag index 952e0ec..1b8d2c9 100644 --- a/09/tmp/grid-fine.frag +++ b/09/tmp/grid-fine.frag @@ -18,11 +18,11 @@ bool grid(vec2 _pos, float _res){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy-vec2(.5); st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(0.0); if(grid(st,0.01)) color += vec3(0.25); if(grid(st,0.1)) color += vec3(0.15); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/09/tmp/grid-warp.frag b/09/tmp/grid-warp.frag index 6e0d9ed..10dbab1 100644 --- a/09/tmp/grid-warp.frag +++ b/09/tmp/grid-warp.frag @@ -29,5 +29,5 @@ void main(void){ vec2 xy = st-vec2(.5); float grid = 1.0-X(tile(xy,10.+20.0*dot(xy,xy)),0.05); - gl_FragColor = vec4(vec3(grid),1.0); -} \ No newline at end of file + gl_FragColor = vec4(vec3(grid),1.0); +} diff --git a/09/tmp/lines-thin.frag b/09/tmp/lines-thin.frag index 414795c..756d3db 100644 --- a/09/tmp/lines-thin.frag +++ b/09/tmp/lines-thin.frag @@ -16,7 +16,7 @@ float aastep(float threshold, float value) { return smoothstep(threshold-afwidth, threshold+afwidth, value); #else return step(threshold, value); - #endif + #endif } mat2 rotate2d(float angle){ @@ -32,7 +32,7 @@ float stripes(vec2 st){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(stripes(st)); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/09/tmp/lines-wave.frag b/09/tmp/lines-wave.frag index 325a9d3..0cfc62b 100644 --- a/09/tmp/lines-wave.frag +++ b/09/tmp/lines-wave.frag @@ -16,7 +16,7 @@ float aastep(float threshold, float value) { return smoothstep(threshold-afwidth, threshold+afwidth, value); #else return step(threshold, value); - #endif + #endif } float stripes(vec2 st, float width){ @@ -26,9 +26,9 @@ float stripes(vec2 st, float width){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec2 pos = st; pos.y += sin(pos.x*30.)*.01; vec3 color = vec3(stripes(pos*92.,.4)); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/09/tmp/lines-zigzag.frag b/09/tmp/lines-zigzag.frag index b456467..603aa03 100644 --- a/09/tmp/lines-zigzag.frag +++ b/09/tmp/lines-zigzag.frag @@ -16,7 +16,7 @@ float aastep(float threshold, float value) { return smoothstep(threshold-afwidth, threshold+afwidth, value); #else return step(threshold, value); - #endif + #endif } float stripes(vec2 st, float width){ @@ -26,10 +26,10 @@ float stripes(vec2 st, float width){ void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec2 pos = fract(st*30.); pos.y += mix(fract(pos.x),fract(1.0-pos.x),step(.5,pos.x))*3.; vec3 color = vec3(stripes(pos,.3)); gl_FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/09/tmp/seamless-tile.frag b/09/tmp/seamless-tile.frag index 1d02feb..99a6b1b 100644 --- a/09/tmp/seamless-tile.frag +++ b/09/tmp/seamless-tile.frag @@ -14,7 +14,7 @@ vec2 tile (vec2 st, float _zoom) { vec2 seamlessTile(vec2 st){ st *= 2.0; - float index = 0.0; + float index = 0.0; index += step(1., mod(st.x,2.0)); index += step(1., mod(st.y,2.0))*2.0; st = fract(st); @@ -36,6 +36,6 @@ void main (void) { // step(st.x,st.y) just makes a b&w triangles - // but you can use whatever design you want. + // but you can use whatever design you want. gl_FragColor = vec4(vec3(step(st.x,st.y)),1.0); -} \ No newline at end of file +} diff --git a/09/truchet.frag b/09/truchet.frag index a3aedb7..4d99e22 100644 --- a/09/truchet.frag +++ b/09/truchet.frag @@ -24,15 +24,15 @@ vec2 tile (vec2 _st, float _zoom) { vec2 rotateTilePattern(vec2 _st){ - // Scale the coordinate system by 2x2 + // Scale the coordinate system by 2x2 _st *= 2.0; // Give each cell an index number // according to its position - float index = 0.0; + float index = 0.0; index += step(1., mod(_st.x,2.0)); index += step(1., mod(_st.y,2.0))*2.0; - + // | // 2 | 3 // | @@ -72,6 +72,6 @@ void main (void) { // st = rotate2D(st,PI*u_time*0.25); // step(st.x,st.y) just makes a b&w triangles - // but you can use whatever design you want. + // but you can use whatever design you want. gl_FragColor = vec4(vec3(step(st.x,st.y)),1.0); -} \ No newline at end of file +} diff --git a/09/zigzag.frag b/09/zigzag.frag index 6a010d9..fddfa1c 100644 --- a/09/zigzag.frag +++ b/09/zigzag.frag @@ -28,7 +28,7 @@ void main(){ vec3 color = vec3(0.0); st = mirrorTile(st*vec2(1.,2.),5.); - float x = st.x*2.; + float x = st.x*2.; float a = floor(1.+sin(x*3.14)); float b = floor(1.+sin((x+1.)*3.14)); float f = fract(x); @@ -36,4 +36,4 @@ void main(){ color = vec3( fillY(st,mix(a,b,f),0.01) ); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/10/1d-random.frag b/10/1d-random.frag index e07cb1c..3cbaebe 100644 --- a/10/1d-random.frag +++ b/10/1d-random.frag @@ -10,7 +10,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot(vec2 _st, float _pct){ - return smoothstep( _pct-0.01, _pct, _st.y) - + return smoothstep( _pct-0.01, _pct, _st.y) - smoothstep( _pct, _pct+0.01, _st.y); } @@ -30,4 +30,4 @@ void main() { color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/10/2d-random-dots.frag b/10/2d-random-dots.frag index 83170a3..51e3c31 100644 --- a/10/2d-random-dots.frag +++ b/10/2d-random-dots.frag @@ -21,7 +21,7 @@ float random(in vec2 st){ return fract(sin(dot(st.xy ,vec2(12.9898,78.233))) * 4 void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + st *= 10.0; // Offset every other row st.x -= step(1., mod(st.y,2.0)) * 0.5; @@ -38,4 +38,4 @@ void main(){ // pct = 1.-pct; gl_FragColor = vec4(vec3(pct),1.0); -} \ No newline at end of file +} diff --git a/10/2d-random-mosaic.frag b/10/2d-random-mosaic.frag index 945f929..e613ac0 100644 --- a/10/2d-random-mosaic.frag +++ b/10/2d-random-mosaic.frag @@ -9,9 +9,9 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float random (vec2 st) { +float random (vec2 st) { return fract(sin(dot(st.xy, - vec2(12.9898,78.233)))* + vec2(12.9898,78.233)))* 43758.5453123); } @@ -23,10 +23,10 @@ void main() { vec2 fpos = fract(st); // get the fractional coords // Assign a random value based on the integer coord - vec3 color = vec3(random( ipos )); + vec3 color = vec3(random( ipos )); // Uncomment to see the subdivided grid // color = vec3(fpos,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/10/2d-random-truchet.frag b/10/2d-random-truchet.frag index 5a2915f..f125a35 100644 --- a/10/2d-random-truchet.frag +++ b/10/2d-random-truchet.frag @@ -1,5 +1,5 @@ // Author @patriciogv - 2015 -// Title: Truchet - 10 print +// Title: Truchet - 10 print #ifdef GL_ES precision mediump float; @@ -11,9 +11,9 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float random (in vec2 _st) { +float random (in vec2 _st) { return fract(sin(dot(_st.xy, - vec2(12.9898,78.233)))* + vec2(12.9898,78.233)))* 43758.5453123); } @@ -56,4 +56,4 @@ void main() { // color = step(tile.x,tile.y); gl_FragColor = vec4(vec3(color),1.0); -} \ No newline at end of file +} diff --git a/10/2d-random.frag b/10/2d-random.frag index ce15143..13a1447 100644 --- a/10/2d-random.frag +++ b/10/2d-random.frag @@ -21,4 +21,4 @@ void main() { float rnd = random( st ); gl_FragColor = vec4(vec3(rnd),1.0); -} \ No newline at end of file +} diff --git a/10/README-de.md b/10/README-de.md index 9a59a1b..8e17bee 100644 --- a/10/README-de.md +++ b/10/README-de.md @@ -1,8 +1,8 @@ # Generative Designs -Nachdem wir in den vorangegangenen Kapiteln so viel über Wiederholungen und wohlgeformte Ordnungen gelernt haben, ist es nur konsequent, nun eine kleine Exkursion in das Reich des Chaotischen zu unternehmen. +Nachdem wir in den vorangegangenen Kapiteln so viel über Wiederholungen und wohlgeformte Ordnungen gelernt haben, ist es nur konsequent, nun eine kleine Exkursion in das Reich des Chaotischen zu unternehmen. -## Zufall +## Zufall [![Ryoji Ikeda – Testmuster (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set) @@ -18,7 +18,7 @@ Spätestens, wenn Du bei ```100000.0``` angekommen bist (und die Formel so aussi ## Wir steuern das -Zufälligkeit für die Shader-Programmierung nutzbar zu machen, kann ganz schön kompliziert sein. Manchmal ist der Zufall zu chaotisch, dann wieder nicht zufällig genug. Schau Dir den folgenden Funktionsgraphen an. Wir haben ihn mit Hilfe der ```rand()```-Funktion konstruiert, die nach eben jenem Prinzip aufgebaut ist, das wir eben beschrieben haben. +Zufälligkeit für die Shader-Programmierung nutzbar zu machen, kann ganz schön kompliziert sein. Manchmal ist der Zufall zu chaotisch, dann wieder nicht zufällig genug. Schau Dir den folgenden Funktionsgraphen an. Wir haben ihn mit Hilfe der ```rand()```-Funktion konstruiert, die nach eben jenem Prinzip aufgebaut ist, das wir eben beschrieben haben. Bei einem genauen Blick erkennst Du, dass die [```sin()```](../glossary/?search=sin)-Funktion ihren Scheitel bei ```-1.5707``` und ```1.5707``` hat. Ich wette, Du ahnst bereits warum – weil dort das Maximum und Minimum einer Sinuswelle liegt, nämlich bei *PI /2.0*. @@ -33,7 +33,7 @@ Vor einiger Zeit hat der Autor mit dem Pseudonym [Pixelero](https://pixelero.wor Wenn Du den bereits zitierten Artikel von [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) liest, darfst Du nicht vergessen, das unsere ```rand()```-Funktionen deterministische Zufallswerte erzeugt, die als „pseudo-zufällig“ bezeichnet werden. Damit ist unter anderem gemeint, das beispielsweise ```rand(1.)``` immer den gleichen Wert zurückliefern wird. Pixelero geht in seinem Artikel auch auf die Funktion ```Math.random()```unter *ActionScript* ein, die beispielsweise nicht-deterministisch ist. Jeder Aufruf mit einem gegebenen Wert als Funktionsargument liefert bei ihr andere Werte zurück. -## 2D-Zufall +## 2D-Zufall Mit diesem vertieften Verständnis von Zufall im Gepäck ist es an der Zeit, den Zufall in zwei Dimensionen wirken zu lassen – entlang der *x-Achse* und der *y-Achse*. Dafür müssen wir einen zweidimensionalen Vektor in einen eindimensionalen Fließkommawert verwandeln. Man kann dies auf verschiedenen Wegen erreichen, aber die Nutzung der [```dot()```](../glossary/?search=dot)-Funktion ist in diesem Fall besonders hilfreich. Sie liefert einen Fließkommawert zwischen ```0.0``` und ```1.0``` zurück, je nachdem wie die beiden Vektoren, deren Skalarprodukt sie bildet, zueinander stehen. @@ -65,7 +65,7 @@ Schau Dir einmal die GLSL-Portierung des berühmten Labyrinth-Generators in BASI Hier nutze ich die Zufallswerte der Zellen, um innerhalb der Zellen eine Linie mal in die eine, mal in die andere Richtung zu zeichnen. Ich setze dafür die ```truchetPattern()```-Funktion aus dem vorangehenden Kapitel ein (es geht um die *Programmzeilen 41 bis 47*). -Du erhältst ein sehenswertes animiertes Muster, wenn Du die Kommentarzeichen aus den *Programmzeilen 35 und 36* entfernst. +Du erhältst ein sehenswertes animiertes Muster, wenn Du die Kommentarzeichen aus den *Programmzeilen 35 und 36* entfernst. ## Meister des Zufalls @@ -90,4 +90,3 @@ Schau Dir die Arbeiten von [Ikeda](http://www.ryojiikeda.com/) an und versuche D Zufallswerte auf ästhetische Art und Weise einzusetzen, kann schwierig sein, besonders wenn man Simulationen erstellen möchten, die die Natur nachahmen. Zufall ist einfach zu chaotisch und nur sehr wenige Dinge ums uns herum entstehen wirklich komplett zufällig. Wenn Du Dir beispielsweise das Muster von Regentropfen oder den Verlauf eines Aktienkurses anschaust – zwei Vorgänge, die Beide sicherlich eine Menge mit Zufall zu tun haben – wirst Du eben doch kein Chaos, sondern komplexe Strukturen und Abhängigkeiten erkennen. Schließlich sind hier jenseits des Zufälligen immer auch systemabhängige Korrelationen und ein Bezug auf vorherige Systemzustände am Werk. Das nächste Kapitel beschäftigt sich deshalb mit Rauschen, dem sanften und der Natur nachempfunden Weg, um Dinge dynamisch und innerhalb des Chaotischen auch ein wenig strukturiert wirken zu lassen. - diff --git a/10/README-it.md b/10/README-it.md index 650da8b..e087373 100644 --- a/10/README-it.md +++ b/10/README-it.md @@ -89,4 +89,4 @@ Date un'occhiata al lavoro di [Ikeda](http://www.ryojiikeda.com/) e provate i se L'utilizzo del random può essere problematico dal punto di vista estetico, soprattutto se si vuole creare simulazioni che sembrano naturali. Il random è semplicemente troppo caotico e poche cose nella vita di tutti i giorni sembrano ```random()```. Se si considera un pattern generato dalla pioggia o un grafico azionario, che sono entrambi abbastanza casuali, questi non assomigliano per niente al pattern random che abbiamo fatto all'inizio di questo capitolo. La ragione? Beh, i valori random non hanno alcuna correlazione tra di loro e la maggior parte dei motivi naturali conserva una certa memoria dello stato precedente. -Nel prossimo capitolo impareremo di più a proposito del rumore, una maniera semplice e dall'*aspetto naturale* di creare il caos computazionale. +Nel prossimo capitolo impareremo di più a proposito del rumore, una maniera semplice e dall'*aspetto naturale* di creare il caos computazionale. diff --git a/10/README.md b/10/README.md index 6eccb69..28da45d 100644 --- a/10/README.md +++ b/10/README.md @@ -18,9 +18,9 @@ By the time you get to ```100000.0``` ( and the equation looks like this: ```y = ## Controlling chaos -Using random can be hard; it is both too chaotic and sometimes not random enough. Take a look at the following graph. To make it, we are using a ```rand()``` function which is implemented exactly like we describe above. +Using random can be hard; it is both too chaotic and sometimes not random enough. Take a look at the following graph. To make it, we are using a ```rand()``` function which is implemented exactly like we describe above. -Taking a closer look, you can see the [```sin()```](../glossary/?search=sin) wave crest at ```-1.5707``` and ```1.5707```. I bet you now understand why - it's where the maximum and minimum of the sine wave happens. +Taking a closer look, you can see the [```sin()```](../glossary/?search=sin) wave crest at ```-1.5707``` and ```1.5707```. I bet you now understand why - it's where the maximum and minimum of the sine wave happens. If look closely at the random distribution, you will note that the there is some concentration around the middle compared to the edges. @@ -41,7 +41,7 @@ Now that we have a better understanding of randomness, it's time to apply it in Take a look at lines 13 to 15 and notice how we are comparing the ```vec2 st``` with another two dimensional vector ( ```vec2(12.9898,78.233)```). -* Try changing the values on lines 14 and 15. See how the random pattern changes and think about what we can learn from this. +* Try changing the values on lines 14 and 15. See how the random pattern changes and think about what we can learn from this. * Hook this random function to the mouse interaction (```u_mouse```) and time (```u_time```) to understand better how it works. @@ -65,7 +65,7 @@ Take a look at this GLSL port of the famouse ```10 PRINT CHR$(205.5+RND(1)); : G Here I'm using the random values of the cells to draw a line in one direction or the other using the ```truchetPattern()``` function from the previous chapter (lines 41 to 47). -You can get another interesting pattern by uncommenting the block of lines between 50 to 53, or animate the pattern by uncommenting lines 35 and 36. +You can get another interesting pattern by uncommenting the block of lines between 50 to 53, or animate the pattern by uncommenting lines 35 and 36. ## Master Random @@ -87,6 +87,6 @@ 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. +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. +In the next chapter we will learn about noise, the smooth and *natural looking* way of creating computational chaos. diff --git a/10/iching-02.frag b/10/iching-02.frag index 25ed526..47d8f2c 100644 --- a/10/iching-02.frag +++ b/10/iching-02.frag @@ -72,10 +72,10 @@ void main(){ st *= 10.0; vec2 fpos = fract(st); vec2 ipos = floor(st); - + float t = u_time*5.0; float df = 1.0; df = hex(fpos,ipos.x+ipos.y+t*random(ipos))+(1.0-rect(fpos,vec2(0.7))); gl_FragColor = vec4(mix(vec3(0.),vec3(1.),step(0.7,df)),1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-00.frag b/10/ikeda-00.frag index 4d5f000..561e65b 100644 --- a/10/ikeda-00.frag +++ b/10/ikeda-00.frag @@ -13,7 +13,7 @@ float random (in float x) { return fract(sin(x)*1e4); } -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123); } @@ -24,7 +24,7 @@ float randomSerie(float x, float freq, float t) { void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(0.0); float cols = 2.; @@ -43,4 +43,4 @@ void main() { randomSerie(st.x, freq*100., t-offset)); gl_FragColor = vec4(1.0-color,1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-01.frag b/10/ikeda-01.frag index 2803b95..85c6d85 100644 --- a/10/ikeda-01.frag +++ b/10/ikeda-01.frag @@ -15,7 +15,7 @@ float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(0.0); vec2 grid = vec2(100.0,2.0); @@ -33,4 +33,4 @@ void main() { color += step(fpos.y*1.5,value); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-02.frag b/10/ikeda-02.frag index 9ca1bea..1c94555 100644 --- a/10/ikeda-02.frag +++ b/10/ikeda-02.frag @@ -20,13 +20,13 @@ void main() { vec2 ipos = floor(st); // integer vec2 fpos = fract(st); // fraction - + vec2 vel = floor(vec2(u_time*10.)); // time vel *= vec2(-1.,0.); // direction vel *= (step(1., mod(ipos.y,2.0))-0.5)*2.; // Oposite directions vel *= random(ipos.y); // random speed - + // Move ipos += floor(vel); // Assign a random value base on the integer coord @@ -37,4 +37,4 @@ void main() { pct = step(0.001+u_mouse.x/u_resolution.x,pct); // threshold gl_FragColor = vec4(vec3(pct),1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-03.frag b/10/ikeda-03.frag index 6545020..b8d2d31 100644 --- a/10/ikeda-03.frag +++ b/10/ikeda-03.frag @@ -13,7 +13,7 @@ float random (in float x) { return fract(sin(x)*1e4); } -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123); } @@ -28,10 +28,10 @@ void main() { vec2 grid = vec2(100.0,50.); st *= grid; - + vec2 ipos = floor(st); // integer vec2 fpos = fract(st); // fraction - + vec2 vel = vec2(u_time*2.*max(grid.x,grid.y)); // time vel *= vec2(-1.,0.0) * random(1.0+ipos.y); // direction @@ -47,4 +47,4 @@ void main() { color *= step(0.2,fpos.y); gl_FragColor = vec4(1.0-color,1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-04.frag b/10/ikeda-04.frag index c25d68c..a88fdba 100644 --- a/10/ikeda-04.frag +++ b/10/ikeda-04.frag @@ -21,13 +21,13 @@ void main() { st *= grid; vec2 ipos = floor(st); // integer - + vec2 vel = floor(vec2(u_time*10.)); // time vel *= vec2(-1.,0.); // direction vel *= (step(1., mod(ipos.y,2.0))-0.5)*2.; // Oposite directions vel *= random(ipos.y); // random speed - + // 100% float totalCells = grid.x*grid.y; float t = mod(u_time*max(grid.x,grid.y)+floor(1.0+u_time*u_mouse.y),totalCells); @@ -52,4 +52,4 @@ void main() { color *= step(.1,fract(st.x+vel.x))*step(.1,fract(st.y+vel.y)); gl_FragColor = vec4(1.0-color,1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-digits.frag b/10/ikeda-digits.frag index e209e75..f20b824 100644 --- a/10/ikeda-digits.frag +++ b/10/ikeda-digits.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -34,15 +34,15 @@ float char(vec2 st, float n){ n = floor(mod(n,10.)); float digit = 0.0; - if (n < 1. ) { digit = 31600.; } - else if (n < 2. ) { digit = 9363.0; } - else if (n < 3. ) { digit = 31184.0; } - else if (n < 4. ) { digit = 31208.0; } - else if (n < 5. ) { digit = 23525.0; } - else if (n < 6. ) { digit = 29672.0; } - else if (n < 7. ) { digit = 29680.0; } - else if (n < 8. ) { digit = 31013.0; } - else if (n < 9. ) { digit = 31728.0; } + if (n < 1. ) { digit = 31600.; } + else if (n < 2. ) { digit = 9363.0; } + else if (n < 3. ) { digit = 31184.0; } + else if (n < 4. ) { digit = 31208.0; } + else if (n < 5. ) { digit = 23525.0; } + else if (n < 6. ) { digit = 29672.0; } + else if (n < 7. ) { digit = 29680.0; } + else if (n < 8. ) { digit = 31013.0; } + else if (n < 9. ) { digit = 31728.0; } else if (n < 10. ) { digit = 31717.0; } float pct = bin(ipos, digit); @@ -67,4 +67,4 @@ void main(){ color = mix(color,vec3(color.r,0.,0.),step(.99,pct)); gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-numered-grid.frag b/10/ikeda-numered-grid.frag index f95bc72..d53635f 100644 --- a/10/ikeda-numered-grid.frag +++ b/10/ikeda-numered-grid.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -34,15 +34,15 @@ float char(vec2 st, float n){ n = floor(mod(n,10.)); float digit = 0.0; - if (n < 1. ) { digit = 31600.; } - else if (n < 2. ) { digit = 9363.0; } - else if (n < 3. ) { digit = 31184.0; } - else if (n < 4. ) { digit = 31208.0; } - else if (n < 5. ) { digit = 23525.0; } - else if (n < 6. ) { digit = 29672.0; } - else if (n < 7. ) { digit = 29680.0; } - else if (n < 8. ) { digit = 31013.0; } - else if (n < 9. ) { digit = 31728.0; } + if (n < 1. ) { digit = 31600.; } + else if (n < 2. ) { digit = 9363.0; } + else if (n < 3. ) { digit = 31184.0; } + else if (n < 4. ) { digit = 31208.0; } + else if (n < 5. ) { digit = 23525.0; } + else if (n < 6. ) { digit = 29672.0; } + else if (n < 7. ) { digit = 29680.0; } + else if (n < 8. ) { digit = 31013.0; } + else if (n < 9. ) { digit = 31728.0; } else if (n < 10. ) { digit = 31717.0; } float pct = bin(ipos, digit); @@ -79,7 +79,7 @@ void main(){ st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(0.0); - + // Grid vec2 grid_st = st*300.; color += vec3(0.5,0.,0.)*grid(grid_st,0.01); @@ -108,4 +108,4 @@ void main(){ color += vec3(char(digits_st_f,100.*pct)); } gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/ikeda-simple-grid.frag b/10/ikeda-simple-grid.frag index a749e51..8bf293b 100644 --- a/10/ikeda-simple-grid.frag +++ b/10/ikeda-simple-grid.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -37,7 +37,7 @@ void main(){ st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(0.0); - + // Grid vec2 grid_st = st*300.; color += vec3(0.5,0.,0.)*grid(grid_st,0.01); @@ -59,4 +59,4 @@ void main(){ color.rgb += step(0.9,random(blocks_st+time_i))*(1.0-time_f); gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/index.php b/10/index.php index b57b66f..d693fb9 100644 --- a/10/index.php +++ b/10/index.php @@ -1,4 +1,4 @@ -< < Previous - + '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/10/matrix.frag b/10/matrix.frag index e24e0a1..248872e 100644 --- a/10/matrix.frag +++ b/10/matrix.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -41,4 +41,4 @@ void main(){ color = vec3(pct); gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/notes.md b/10/notes.md index 5226ebb..cfb17ae 100644 --- a/10/notes.md +++ b/10/notes.md @@ -7,4 +7,4 @@ also, if the result is positive, both vectors point in the same direction, if zero, they're perpendicualer, if negative, they point in opposite directions. - * L62 famous**e** typo en \ No newline at end of file + * L62 famous**e** typo en diff --git a/10/tmp/barcode.frag b/10/tmp/barcode.frag index ca93313..c6429e5 100644 --- a/10/tmp/barcode.frag +++ b/10/tmp/barcode.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -33,15 +33,15 @@ float char (vec2 st, float n) { n = floor(mod(n,10.)); float digit = 0.0; - if (n < 1. ) { digit = 31600.; } - else if (n < 2. ) { digit = 9363.0; } - else if (n < 3. ) { digit = 31184.0; } - else if (n < 4. ) { digit = 31208.0; } - else if (n < 5. ) { digit = 23525.0; } - else if (n < 6. ) { digit = 29672.0; } - else if (n < 7. ) { digit = 29680.0; } - else if (n < 8. ) { digit = 31013.0; } - else if (n < 9. ) { digit = 31728.0; } + if (n < 1. ) { digit = 31600.; } + else if (n < 2. ) { digit = 9363.0; } + else if (n < 3. ) { digit = 31184.0; } + else if (n < 4. ) { digit = 31208.0; } + else if (n < 5. ) { digit = 23525.0; } + else if (n < 6. ) { digit = 29672.0; } + else if (n < 7. ) { digit = 29680.0; } + else if (n < 8. ) { digit = 31013.0; } + else if (n < 9. ) { digit = 31728.0; } else if (n < 10. ) { digit = 31717.0; } float pct = binChar(ipos, digit); @@ -81,8 +81,8 @@ float bar (vec2 st, float n, bool L) { else if (n < 5. ) { digit = 92.0; } else if (n < 6. ) { digit = 78.0; } else if (n < 7. ) { digit = 80.0; } - else if (n < 8. ) { digit = 68.0; } - else if (n < 9. ) { digit = 72.0; } + else if (n < 8. ) { digit = 68.0; } + else if (n < 9. ) { digit = 72.0; } else if (n < 10. ) { digit = 116.0; } float pct = binBar(ipos, digit+1.); @@ -149,8 +149,8 @@ void main(){ color += barCode(fpos,12.,value); } else { - color += 1.; + color += 1.; } gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/tmp/digits.frag b/10/tmp/digits.frag index 5269a6f..2346990 100644 --- a/10/tmp/digits.frag +++ b/10/tmp/digits.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -33,15 +33,15 @@ float char(vec2 st, float n){ n = floor(mod(n,10.)); float digit = 0.0; - if (n < 1. ) { digit = 31600.; } - else if (n < 2. ) { digit = 9363.0; } - else if (n < 3. ) { digit = 31184.0; } - else if (n < 4. ) { digit = 31208.0; } - else if (n < 5. ) { digit = 23525.0; } - else if (n < 6. ) { digit = 29672.0; } - else if (n < 7. ) { digit = 29680.0; } - else if (n < 8. ) { digit = 31013.0; } - else if (n < 9. ) { digit = 31728.0; } + if (n < 1. ) { digit = 31600.; } + else if (n < 2. ) { digit = 9363.0; } + else if (n < 3. ) { digit = 31184.0; } + else if (n < 4. ) { digit = 31208.0; } + else if (n < 5. ) { digit = 23525.0; } + else if (n < 6. ) { digit = 29672.0; } + else if (n < 7. ) { digit = 29680.0; } + else if (n < 8. ) { digit = 31013.0; } + else if (n < 9. ) { digit = 31728.0; } else if (n < 10. ) { digit = 31717.0; } float pct = bin(ipos, digit); @@ -66,4 +66,4 @@ void main(){ color = mix(color,vec3(color.r,0.,0.),step(.99,pct)); gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/10/tmp/glitch.sh b/10/tmp/glitch.sh index bf57f5c..df454f6 100755 --- a/10/tmp/glitch.sh +++ b/10/tmp/glitch.sh @@ -7,7 +7,7 @@ COUNTER=0 for i in `seq -w 0.01 .031 $SEC`; do echo $i `glslViewer $SHADER -s $i -o frame-$COUNTER.png` - let COUNTER=COUNTER+1 + let COUNTER=COUNTER+1 done convert -delay 3.5 -loop 1 frame-*.png animated.gif diff --git a/10/tmp/ikeda-01.frag b/10/tmp/ikeda-01.frag index 655a9e7..388eee0 100644 --- a/10/tmp/ikeda-01.frag +++ b/10/tmp/ikeda-01.frag @@ -20,7 +20,7 @@ float noise (in float x) { void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; - + vec3 color = vec3(0.0); vec2 grid = vec2(20.0,2.0); @@ -39,4 +39,4 @@ void main() { color += step(fpos.y*1.5,value)*step(.5,fpos.x); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/10/tmp/ikeda-03.frag b/10/tmp/ikeda-03.frag index 70974f0..71433d9 100644 --- a/10/tmp/ikeda-03.frag +++ b/10/tmp/ikeda-03.frag @@ -26,10 +26,10 @@ void main() { } vec2 grid = vec2(100.0,50.); st *= grid; - + vec2 ipos = floor(st); // integer vec2 fpos = fract(st); // fraction - + vec2 vel = vec2(u_time*2.*max(grid.x,grid.y)); // time vel *= vec2(-1.,0.0) * random(1.0+ipos.y); // direction diff --git a/10/tmp/ikeda-04.frag b/10/tmp/ikeda-04.frag index 756fa06..480311c 100644 --- a/10/tmp/ikeda-04.frag +++ b/10/tmp/ikeda-04.frag @@ -21,13 +21,13 @@ void main() { st *= grid; vec2 ipos = floor(st); // integer - + vec2 vel = floor(vec2(u_time*10.)); // time vel *= vec2(-1.,0.); // direction vel *= (step(1., mod(ipos.y,2.0))-0.5)*2.; // Oposite directions vel *= random(ipos.y); // random speed - + // 100% float totalCells = grid.x*grid.y; float t = mod(u_time*max(grid.x,grid.y)+floor(1.0+u_time*u_mouse.y),totalCells); diff --git a/10/tmp/img-glitch.frag b/10/tmp/img-glitch.frag index e3def29..7fa1bdd 100644 --- a/10/tmp/img-glitch.frag +++ b/10/tmp/img-glitch.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform sampler2D u_tex; uniform vec2 u_resolution; uniform float u_time; @@ -41,7 +41,7 @@ float fbm( in vec2 p ){ void main(){ vec2 st = gl_FragCoord.st/u_resolution.xy; float aspect = u_resolution.x/u_resolution.y; - + vec2 grain_st = st-.5; float grain = 0.0; grain = mix(1., 0.9, dot(grain_st,grain_st) + (fbm(gl_FragCoord.xy*0.6)*0.1) ); @@ -68,4 +68,4 @@ void main(){ color.rgb *= 0.4+sin((st.y*3.1415+u_time)*500.); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/10/tmp/matrix.frag b/10/tmp/matrix.frag index 594175e..b93d2dd 100644 --- a/10/tmp/matrix.frag +++ b/10/tmp/matrix.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; diff --git a/10/tmp/numered-grid.frag b/10/tmp/numered-grid.frag index dadf9b8..d64cdd7 100644 --- a/10/tmp/numered-grid.frag +++ b/10/tmp/numered-grid.frag @@ -4,7 +4,7 @@ #ifdef GL_ES precision mediump float; #endif - + uniform vec2 u_resolution; uniform float u_time; @@ -59,15 +59,15 @@ float char(vec2 st, float n){ n = floor(mod(n,10.)); float digit = 0.0; - if (n < 1. ) { digit = 31600.; } - else if (n < 2. ) { digit = 9363.0; } - else if (n < 3. ) { digit = 31184.0; } - else if (n < 4. ) { digit = 31208.0; } - else if (n < 5. ) { digit = 23525.0; } - else if (n < 6. ) { digit = 29672.0; } - else if (n < 7. ) { digit = 29680.0; } - else if (n < 8. ) { digit = 31013.0; } - else if (n < 9. ) { digit = 31728.0; } + if (n < 1. ) { digit = 31600.; } + else if (n < 2. ) { digit = 9363.0; } + else if (n < 3. ) { digit = 31184.0; } + else if (n < 4. ) { digit = 31208.0; } + else if (n < 5. ) { digit = 23525.0; } + else if (n < 6. ) { digit = 29672.0; } + else if (n < 7. ) { digit = 29680.0; } + else if (n < 8. ) { digit = 31013.0; } + else if (n < 9. ) { digit = 31728.0; } else if (n < 10. ) { digit = 31717.0; } float pct = bin(ipos, digit); @@ -108,7 +108,7 @@ float cross(in vec2 st, vec2 size){ void main(){ vec2 st = gl_FragCoord.st/u_resolution.xy; float aspect = u_resolution.x/u_resolution.y; - + vec2 grain_st = st-.5; vec3 color = vec3(0.0); float grain = 0.0; @@ -153,7 +153,7 @@ void main(){ // Digits vec2 digits_st = mod(st*60.,20.); vec2 digits_st_i = floor(digits_st); - float digits_n = ceil(block*5.); + float digits_n = ceil(block*5.); offset *= 10.; if (block > 0.0 && digits_st_i.y == 1. && @@ -175,4 +175,4 @@ void main(){ color.b += block*char(digits_st_f-offset,100.*pct); } gl_FragColor = vec4( (1.0-color) * grain, 1.0); -} \ No newline at end of file +} diff --git a/11/1d-noise.frag b/11/1d-noise.frag index dcb9115..c1dbae9 100644 --- a/11/1d-noise.frag +++ b/11/1d-noise.frag @@ -10,7 +10,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot(vec2 st, float pct){ - return smoothstep( pct-0.01, pct, st.y) - + return smoothstep( pct-0.01, pct, st.y) - smoothstep( pct, pct+0.01, st.y); } @@ -21,7 +21,7 @@ float random (in float x) { float noise (in float x) { float i = floor(x); float f = fract(x); - + // Cubic Hermine Curve float u = f * f * (3.0 - 2.0 * f); @@ -42,4 +42,4 @@ void main() { color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/2d-gnoise.frag b/11/2d-gnoise.frag index 6255162..1dcdadb 100644 --- a/11/2d-gnoise.frag +++ b/11/2d-gnoise.frag @@ -20,9 +20,9 @@ float noise(vec2 st) { vec2 u = f*f*(3.0-2.0*f); - return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), + return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), - mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), + mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); } @@ -36,4 +36,4 @@ void main() { color = vec3( noise(pos)*.5+.5 ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/2d-noise.frag b/11/2d-noise.frag index b206e16..74be372 100644 --- a/11/2d-noise.frag +++ b/11/2d-noise.frag @@ -7,7 +7,7 @@ uniform vec2 u_mouse; uniform float u_time; // 2D Random -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); @@ -32,8 +32,8 @@ float noise (in vec2 st) { // u = smoothstep(0.,1.,f); // Mix 4 coorners porcentages - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + + return mix(a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } @@ -48,4 +48,4 @@ void main() { float n = noise(pos); gl_FragColor = vec4(vec3(n), 1.0); -} \ No newline at end of file +} diff --git a/11/2d-pnoise.frag b/11/2d-pnoise.frag index cd6b5ba..fa4a97f 100644 --- a/11/2d-pnoise.frag +++ b/11/2d-pnoise.frag @@ -48,10 +48,10 @@ float cnoise(vec2 P) { vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); @@ -88,10 +88,10 @@ float pnoise(vec2 P, vec2 rep) { vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); @@ -113,4 +113,4 @@ void main() { color = vec3( cnoise(pos) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/2d-snoise-clear.frag b/11/2d-snoise-clear.frag index 15ce951..cb37471 100644 --- a/11/2d-snoise-clear.frag +++ b/11/2d-snoise-clear.frag @@ -16,21 +16,21 @@ vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } // Author : Ian McEwan, Ashima Arts // Maintainer : ijm // Lastmod : 20110822 (ijm) -// License : +// License : // Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// float snoise(vec2 v) { // Precompute values for skewed triangular grid const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 - 0.366025403784439, + 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) - -0.577350269189626, + -0.577350269189626, // -1.0 + 2.0 * C.x - 0.024390243902439); + 0.024390243902439); // 1.0 / 41.0 // First corner (x0) @@ -51,17 +51,17 @@ float snoise(vec2 v) { + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3( - dot(x0,x0), - dot(x1,x1), + dot(x0,x0), + dot(x1,x1), dot(x2,x2) ), 0.0); m = m*m ; m = m*m ; - // Gradients: + // Gradients: // 41 pts uniformly over a line, mapped onto a diamond - // The ring size 17*17 = 289 is close to a multiple + // The ring size 17*17 = 289 is close to a multiple // of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; @@ -92,4 +92,4 @@ void main() { color = vec3(snoise(st)*.5+.5); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/2d-snoise.frag b/11/2d-snoise.frag index abba274..29c085e 100644 --- a/11/2d-snoise.frag +++ b/11/2d-snoise.frag @@ -11,19 +11,19 @@ uniform float u_time; // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm // Lastmod : 20110822 (ijm) -// License : +// License : // Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, - 0.366025403784439, - -0.577350269189626, - 0.024390243902439); + 0.366025403784439, + -0.577350269189626, + 0.024390243902439); vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); vec2 i1 = vec2(0.0); @@ -35,8 +35,8 @@ float snoise(vec2 v) { permute( i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3( - dot(x0,x0), - dot(x12.xy,x12.xy), + dot(x0,x0), + dot(x12.xy,x12.xy), dot(x12.zw,x12.zw) ), 0.0); m = m*m ; @@ -61,4 +61,4 @@ void main() { color = vec3(snoise(pos)*.5+.5); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/3d-noise.frag b/11/3d-noise.frag index 3d47e3c..755bfbc 100644 --- a/11/3d-noise.frag +++ b/11/3d-noise.frag @@ -17,10 +17,10 @@ float noise (in vec3 p) { vec3 i = floor(p); vec3 f = fract(p); - - // For performance, compute the base input to a - // 1D random from the integer part of the - // argument and the incremental change to the + + // For performance, compute the base input to a + // 1D random from the integer part of the + // argument and the incremental change to the // 1D based on the 3D -> 1D wrapping float n = dot(i, step); @@ -30,7 +30,7 @@ float noise (in vec3 p) { u.x), mix(random(n + dot(step, vec3(0,1,0))), random(n + dot(step, vec3(1,1,0))), - u.x), + u.x), u.y), mix(mix(random(n + dot(step, vec3(0,0,1))), random(n + dot(step, vec3(1,0,1))), @@ -51,4 +51,4 @@ void main() { color = vec3(noise(pos)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/3d-pnoise.frag b/11/3d-pnoise.frag index a1eb366..9e561f4 100644 --- a/11/3d-pnoise.frag +++ b/11/3d-pnoise.frag @@ -91,7 +91,7 @@ float cnoise(vec3 P) { vec3 fade_xyz = fade(Pf0); vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); - float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } @@ -160,7 +160,7 @@ float pnoise(vec3 P, vec3 rep) { vec3 fade_xyz = fade(Pf0); vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); - float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } @@ -174,4 +174,4 @@ void main() { // color = vec3(pnoise(pos,vec3(0.0))); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/3d-snoise.frag b/11/3d-snoise.frag index d6629b0..4d61367 100644 --- a/11/3d-snoise.frag +++ b/11/3d-snoise.frag @@ -7,7 +7,7 @@ uniform vec2 u_mouse; uniform float u_time; // -// Description : Array and textureless GLSL 2D/3D/4D simplex +// Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm @@ -15,13 +15,13 @@ uniform float u_time; // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } -float snoise(vec3 v) { +float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); @@ -40,10 +40,10 @@ float snoise(vec3 v) { vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations - i = mod289(i); - vec4 p = permute( permute( permute( + i = mod289(i); + vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. @@ -85,7 +85,7 @@ float snoise(vec3 v) { // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), + return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } @@ -98,4 +98,4 @@ void main() { color = vec3(snoise(pos)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/README-ch.md b/11/README-ch.md index 836e0c1..d4c5b6c 100644 --- a/11/README-ch.md +++ b/11/README-ch.md @@ -37,7 +37,7 @@ y = rand(i); //rand() 在之前的章节提过 ```glsl y = mix(rand(i), rand(i + 1.0), f); -``` +``` 试试取消这句的注释,看一下会变成什么样子。注意我们储存在 `f` 中的 [```fract()```](.../glossary/?search=fract) 值[```mix()```](.../glossary/?search=mix)了两个随机值。 @@ -140,7 +140,7 @@ Noise 算法的设计初衷是将难以言说的自然质感转化成数字图 第三种方法是用 noise 函数来变换一个形状。这个也需要我们在[第七章](../07/)学到的技术。 - + 给你的练习: @@ -205,11 +205,11 @@ y = x*x*(3.0-2.0*x); * 做一个 shader 来表现流体的质感。比如像[熔岩灯](https://en.wikipedia.org/wiki/Lava_lamp?oldformat=true),墨水滴,水,等等。 - + * 用 Simplex Noise 给你现在的作品添加更多的材质效果。 - + 在本章我们介绍了一些操控混沌的方法。这并不是一件简单的工作!成为 noise 超级大师需要时间和努力。 @@ -217,4 +217,4 @@ y = x*x*(3.0-2.0*x);

“和树聊聊天吧,和它交个朋友。” Bob Ross -

+

diff --git a/11/README-de.md b/11/README-de.md index f6e417d..008de6b 100644 --- a/11/README-de.md +++ b/11/README-de.md @@ -4,7 +4,7 @@ Im letzten Kapitel haben wir mit Zufallsfunktionen gearbeitet, die wie weißes Rauschen auf dem Fernsehbildschirm wirken. Nach so vielen Shader-Funktionen auf einmal dreht sich Dir bestimmt der Kopf und vielleicht sind auch Deine Augen etwas müde. Jetzt ist ein guter Moment, um einen kleinen Spaziergang zu unternehmen und ein wenig nach Luft zu schnappen. -Draußen im Freien spüren wir den Luftzug auf unserer Haut und die Sonne in unserem Gesicht. Die Erde ist ein so lebendiger und vielgestaltiger Ort voller Farben, Texturen und Klängen. Während wir uns in der Natur bewegen, können wir gar nicht anders, als die unterschiedlichen Oberflächen von Straßen, Gestein, Bäumen und Wolken wahrzunehmen. +Draußen im Freien spüren wir den Luftzug auf unserer Haut und die Sonne in unserem Gesicht. Die Erde ist ein so lebendiger und vielgestaltiger Ort voller Farben, Texturen und Klängen. Während wir uns in der Natur bewegen, können wir gar nicht anders, als die unterschiedlichen Oberflächen von Straßen, Gestein, Bäumen und Wolken wahrzunehmen. ![](texture-00.jpg) ![](texture-01.jpg) @@ -36,7 +36,7 @@ Dahinter folgen zwei Programmzeilen, die zunächst auskommentiert sind. Die Erst ```glsl y = mix(rand(i), rand(i + 1.0), f); -``` +``` Fahre fort, indem Du die Kommentarzeichen für diese Zeile entfernst und Dir das Ergebnis anschaust. @@ -46,7 +46,7 @@ An diesem Punkt unseres kleinen GLSL-Kurses wissen wir bereits, dass es noch etw y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f)); ``` -Sobald Du die Kommentarzeichen aus dieser Zeile entfernt hast, erscheint ein anderes Ergebnis. In einigen Implementationen für Rausch-Funktionen verwenden die Autoren lieber ihre eigenen kubischen Kurven an Stelle von [```smoothstep()```](.../glossary/?search=smoothstep), wie etwa im folgenden Beispiel. +Sobald Du die Kommentarzeichen aus dieser Zeile entfernt hast, erscheint ein anderes Ergebnis. In einigen Implementationen für Rausch-Funktionen verwenden die Autoren lieber ihre eigenen kubischen Kurven an Stelle von [```smoothstep()```](.../glossary/?search=smoothstep), wie etwa im folgenden Beispiel. ```glsl float u = f * f * (3.0 - 2.0 * f ); // kubische Verlaufskurve @@ -85,7 +85,7 @@ Wie schon bei unserem Beispiel für den eindimensionalen Raum, erfolgt die Inter ![](05.jpg) -Schau Dir die folgende Noise-Funktion an. +Schau Dir die folgende Noise-Funktion an.
@@ -119,7 +119,7 @@ Wie die vorangegangenen Abschnitte gezeigt haben, tendiert *Value Noise* zur Erz Nimm Dir einen Moment Zeit, um die beiden folgenden Beispiele von [Inigo Quilez](http://www.iquilezles.org/) zu studieren und richte Deine Aufmerksamkeit dabei besonders auf die Unterschiede zwischen [*Value Noise*](https://www.shadertoy.com/view/lsf3WH) und [*Gradient Noise*](https://www.shadertoy.com/view/XdXGW8). -Wie ein Maler, der genau weiß, wie die Farben auf seiner Staffelei miteinander harmonieren, werden auch wir die Noise-Funktionen umso besser nutzen können, je mehr wir deren Vorgehensweise verstehen. Wenn wir beispielsweise eine zweidimensionale Noise-Funktion nutzen, um den Raum zu drehen, während wir gerade Linien zeichnen, entsteht der folgende Dreheffekt, der stark an die Maserung von Holz erinnert. Auch hier kannst Du wieder auf die Grafik klicken, um der den Shader-Code dahinter anzuschauen. +Wie ein Maler, der genau weiß, wie die Farben auf seiner Staffelei miteinander harmonieren, werden auch wir die Noise-Funktionen umso besser nutzen können, je mehr wir deren Vorgehensweise verstehen. Wenn wir beispielsweise eine zweidimensionale Noise-Funktion nutzen, um den Raum zu drehen, während wir gerade Linien zeichnen, entsteht der folgende Dreheffekt, der stark an die Maserung von Holz erinnert. Auch hier kannst Du wieder auf die Grafik klicken, um der den Shader-Code dahinter anzuschauen. [ ![Holzmaserung](wood-long.png) ](../edit.php#11/wood.frag) @@ -139,7 +139,7 @@ Ein anderer Weg zur Erzeugung interessanter Muster mit Hilfe von Noise-Funktione Ein dritter Weg basiert auf der Modulation einer Form mit Hilfe einer Noise-Funktion. Auch dabei kommen einige der Techniken zum Einsatz, die wir im [Kapitel über Formen](../07/) kennengelernt haben. - + Empfohlene Übungen: @@ -179,11 +179,11 @@ Für Ken Perlin war der Erfolg seines ersten Noise-Algorithmus noch nicht genug. * Ein Rauschen ohne sichtbare Richtungsartefakte. -* Ein Rauschen mit sauber definierten und nahtlosen Übergangen, das sich einfach berechnen lässt. +* Ein Rauschen mit sauber definierten und nahtlosen Übergangen, das sich einfach berechnen lässt. * Ein Algorithmus, der auch in der Hardware einfach zu implementieren ist. -Ich weiß, was Du jetzt denkst... „Wow, wer ist dieser Mann?“ Ja, seine Leistungen sind wirklich großartig. Aber mal ganz im Ernst, wie ist es ihm gelungen, seinen Algorithmus zu verbessern? Nun, wir haben gesehen, dass er zur Berechnung des Rauschens in zwei Dimensionen zwischen den vier Eckpunkten eines Vierecks interpoliert. Man darf deshalb zurecht davon ausgehen, dass er für die Berechnung in drei Dimensionen ([eine Implementierung in GLSL findest Du hier](../edit.php#11/3d-noise.frag)) und vier Dimensionen zwischen 8 bzw. 16 einzelnen Eckpunkten interpolieren muss. Korrekt? +Ich weiß, was Du jetzt denkst... „Wow, wer ist dieser Mann?“ Ja, seine Leistungen sind wirklich großartig. Aber mal ganz im Ernst, wie ist es ihm gelungen, seinen Algorithmus zu verbessern? Nun, wir haben gesehen, dass er zur Berechnung des Rauschens in zwei Dimensionen zwischen den vier Eckpunkten eines Vierecks interpoliert. Man darf deshalb zurecht davon ausgehen, dass er für die Berechnung in drei Dimensionen ([eine Implementierung in GLSL findest Du hier](../edit.php#11/3d-noise.frag)) und vier Dimensionen zwischen 8 bzw. 16 einzelnen Eckpunkten interpolieren muss. Korrekt? In anderen Worten: Für die Berechnung des Rauschens in N Dimensionen muss man zwischen *2 hoch N* (_2^N_) verschiedenen Punkten interpolieren. Ken war jedoch aufgefallen, dass die offensichtliche „Bauweise“ für eine flächenfüllende Form zwar fraglos ein Viereck darstellt, die einfachste Form der Abdeckung jedoch mit gleichseitigen Dreiecken erzielt wird. Deshalb ersetzte er das rechtwinklige Gitternetz durch ein Netz aus gleichseitigen Dreiecken. @@ -199,7 +199,7 @@ Doch wie wird dieses vereinfachte Gitternetz aufgebaut? In einem weiteren brilla ![](simplex-grid-02.png) -Anschließend fahren wir fort, wie es [Stefan Gustavson in seinen Ausführungen beschreibt](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): "*... indem wir uns die ganzzahligen Anteile der transformierten Koordinaten (x,y) des zu berechnenden Punktes anschauen, denn darüber können wir leicht feststellen, zu welchen zwei Dreiecken der Punkt gehört. Indem wir die Werte von x und y vergleichen, erfahren wir, ob sich der Punkt in dem oberen oder in dem unteren Dreieck befindet. So können wir die drei korrekten Eckpunkte in die Berechnung einbeziehen.*“ +Anschließend fahren wir fort, wie es [Stefan Gustavson in seinen Ausführungen beschreibt](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): "*... indem wir uns die ganzzahligen Anteile der transformierten Koordinaten (x,y) des zu berechnenden Punktes anschauen, denn darüber können wir leicht feststellen, zu welchen zwei Dreiecken der Punkt gehört. Indem wir die Werte von x und y vergleichen, erfahren wir, ob sich der Punkt in dem oberen oder in dem unteren Dreieck befindet. So können wir die drei korrekten Eckpunkte in die Berechnung einbeziehen.*“ Im folgenden Programmcode kannst Du die Kommentarzeichen aus der *Programmzeile 44* entfernen, um zu sehen, wie das Gitternetz gezerrt wird. Und sobald Du die Kommentierung von *Zeile 47* aufhebst, erkennst Du die Aufteilung der Fläche in gleichschenklige Dreiecke. Beachte, wie wir in *Zeile 22* das verzerrte Rechteck einfach in zwei gleichseitige Dreiecke aufteilen, indem wir testen, ob ```x > y``` ist („unteres“ Dreieck) oder ```y > x``` („oberes“ Dreieck). @@ -215,16 +215,15 @@ Nun aber genug der technischen Spitzfindigkeiten. Es ist an der Zeit, dass Du de * Entwickle einen Shader, der die Illusion einer Strömung von Flüssigkeiten erweckt. Etwa wie bei einer Lava-Lampe, Tintentropfen, Wasser etc. - + * Nutze den Simplex Noise-Algorithmus um Deinen bisherigen Arbeiten mehr Textur zu verleihen. - + In diesem Kapitel haben wir versucht, Kontrolle über das Chaos zu erlangen. Das war keine leichte Aufgabe. Es braucht seine Zeit, um ein Meister des Rauschens und der Raumkrümmung zu werden. In den folgenden Kapiteln werden wir einige bekannte Techniken aufgreifen, mit Denen Du deine Fähigkeiten weiter verbessern kannst. Bis dahin genieße ein wenig Zeit draußen an der frischen Luft und lasse Dich von den Mustern und Strukturen der Natur inspirieren. Denn Deine Fähigkeiten zur Beobachtung müssen ähnlich gut entwickelt sein, wie Deine Programmierfähigkeiten. Vielleicht sogar noch besser. Genieße die wertvolle Zeit abseits des Computers!

"Sprich mit den Bäumen und werdet Freunde." Bob Ross -

- +

diff --git a/11/README-fr.md b/11/README-fr.md index 745d355..970fd68 100644 --- a/11/README-fr.md +++ b/11/README-fr.md @@ -46,7 +46,7 @@ Après quoi, vous voyez deux lignes commentées, la première fait une interpola ```glsl y = mix(rand(i), rand(i + 1.0), f); -``` +``` Décommentez cette ligne pour voir ce que ça donne. Nous utilisons la partie fractionnelle `f` pour mélanger ([```mix()```](.../glossary/?search=mix)) les deux valeurs aléatoires. @@ -160,7 +160,7 @@ Une autre approche pour créer des motifs consiste à les considérer comme des Une troisième approche consiste consiste à moduler une forme. Cela fait également appel aux techniques vues au [chapitre des formes](../07/?lan=fr). - + Entraînement: @@ -243,11 +243,11 @@ Que voyez vous? qu'est ce que ça vous rappelle? quelles utilisations potentiell * Créez un shader qui donne l'illusion d'un flux ; une lava-lamp, des goutes d'encre, de l'eau, etc. - + * Utilisez le bruit simplexe pour texturer un de vos exercices précédents. - + Dans ce chapitre, nous avons appris à contrôler le chaos et ce n'était pas chose aisée! Devenir maître du Bruit demande temps et énergie. @@ -258,4 +258,4 @@ La capacité d'observation est au moins aussi importante (sinon plus) que la cap Sortez et profitez du reste de votre journée!

"Parler à l'arbre, s'en faire un ami." Bob Ross -

+

diff --git a/11/README-it.md b/11/README-it.md index 617a8ea..242a076 100644 --- a/11/README-it.md +++ b/11/README-it.md @@ -37,7 +37,7 @@ Dopo di che si osservino le due righe commentate. La prima interpola ogni valore ```glsl y = mix(rand(i), rand(i + 1.0), f); -``` +``` Andate avanti e rimuovete il commento di questa linea per vedere che cosa succede. Utilizziamo la parte frazionale `f` per mischiare ([```mix()```](../glossary/?search=mix)) i due valori random. @@ -141,7 +141,7 @@ Un altro modo per ottenere dal rumore dei pattern interessanti è quello di trat Un terzo modo di utilizzare la funzione di rumore è di modulare una forma. Questo richiede anche alcune delle tecniche che abbiamo imparato nel [capitolo sulle figure](../07/). - + Per la vostra pratica: @@ -203,15 +203,15 @@ Beh... direi che abbiamo avuto abbastanza tecnicismi, è il momento d'utilizzare * Fate uno shader che crea l'illusione di un flusso. Come una lampada di lava, gocce d'inchiostro, dell'acqua, ecc. - + * Utilizzate il rumore simplesso per aggiungere delle texture a dei lavori precedenti. - + In questo capitolo abbiamo preso controllo sul caos. Non è stato un lavoro facile! Diventare un maestro del rumore richiede tempo e impegno. Nei capitoli seguenti vedremo alcune tecniche ben note per perfezionare le proprie competenze e ottenere di più dal vostro rumore per progettare del contenuto generativo di qualità. Fino ad allora godetevi un po' di tempo all'aria aperta, contemplate la natura e i suoi pattern complicati. La capacità d'osservazione è altrettanto importante (se non di più) rispetto a quella di creare dei pattern. Andate fuori e godetevi il resto della giornata!

"Parla con l'albero, per farsi un amico." Bob Ross -

+

diff --git a/11/README-jp.md b/11/README-jp.md index 0d92611..faafa81 100644 --- a/11/README-jp.md +++ b/11/README-jp.md @@ -228,4 +228,4 @@ y = x*x*(3.0-2.0*x); 続く章ではスキルを完璧なものにし、シェーダーによる質の高い作品作りにノイズをさらに生かすため、幾つかの有名なテクニックを見ていくことになります。それまでの間、少し外で自然とその複雑なパターンをじっくり眺めて楽しんでください。物事を観察するスキルは、何かを作り出すスキルと同じくらいの(もしかするともっと)献身を必要とします。外に出かけて残りの一日を楽しみましょう。

「木に話しかけて、友達になりましょう。」 - ボブの絵画教室

\ No newline at end of file + ボブの絵画教室

diff --git a/11/README.md b/11/README.md index 983e562..391c3cf 100644 --- a/11/README.md +++ b/11/README.md @@ -5,7 +5,7 @@ It's time for a break! We've been playing with random functions that look like TV white noise, our head is still spinning thinking about shaders, and our eyes are tired. Time to go out for a walk! -We feel the air on our skin, the sun in our face. The world is such a vivid and rich place. Colors, textures, sounds. While we walk we can't avoid noticing the surface of the roads, rocks, trees and clouds. +We feel the air on our skin, the sun in our face. The world is such a vivid and rich place. Colors, textures, sounds. While we walk we can't avoid noticing the surface of the roads, rocks, trees and clouds. ![](texture-00.jpg) ![](texture-01.jpg) @@ -37,18 +37,18 @@ After that you see two commented lines. The first one interpolates each random v ```glsl y = mix(rand(i), rand(i + 1.0), f); -``` +``` Go ahead and uncomment this line to see how this looks. We use the [```fract()```](../glossary/?search=fract) value store in `f` to [```mix()```](../glossary/?search=mix) the two random values. -At this point in the book, we've learned that we can do better than a linear interpolation, right? +At this point in the book, we've learned that we can do better than a linear interpolation, right? Now try uncommenting the following line, which uses a [```smoothstep()```](../glossary/?search=smoothstep) interpolation instead of a linear one. ```glsl y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f)); ``` -After uncommenting it, notice how the transition between the peaks gets smooth. In some noise implementations you will find that programmers prefer to code their own cubic curves (like the following formula) instead of using the [```smoothstep()```](../glossary/?search=smoothstep). +After uncommenting it, notice how the transition between the peaks gets smooth. In some noise implementations you will find that programmers prefer to code their own cubic curves (like the following formula) instead of using the [```smoothstep()```](../glossary/?search=smoothstep). ```glsl float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve @@ -87,7 +87,7 @@ Like the 1D example, this interpolation is not linear but cubic, which smoothly ![](05.jpg) -Take a look at the following noise function. +Take a look at the following noise function.
@@ -121,7 +121,7 @@ As you discovered in the previous exercises, value noise tends to look "blocky." Take a minute to look at these two examples by [Inigo Quilez](http://www.iquilezles.org/) and pay attention to the differences between [value noise](https://www.shadertoy.com/view/lsf3WH) and [gradient noise](https://www.shadertoy.com/view/XdXGW8). -Like a painter who understands how the pigments of their paints work, the more we know about noise implementations the better we will be able to use them. For example, if we use a two dimensional noise implementation to rotate the space where straight lines are rendered, we can produce the following swirly effect that looks like wood. Again you can click on the image to see what the code looks like. +Like a painter who understands how the pigments of their paints work, the more we know about noise implementations the better we will be able to use them. For example, if we use a two dimensional noise implementation to rotate the space where straight lines are rendered, we can produce the following swirly effect that looks like wood. Again you can click on the image to see what the code looks like. [ ![Wood texture](wood-long.png) ](../edit.php#11/wood.frag) @@ -141,7 +141,7 @@ Another way to get interesting patterns from noise is to treat it like a distanc A third way of using the noise function is to modulate a shape. This also requires some of the techniques we learned in the [chapter about shapes](../07/). - + For you to practice: @@ -154,7 +154,7 @@ For you to practice: ## Improved Noise -An improvement by Perlin to his original non-simplex noise **Simplex Noise**, is the replacement of the cubic Hermite curve ( _f(x) = 3x^2-2x^3_ , which is identical to the [```smoothstep()```](../glossary/?search=smoothstep) function) with a quintic interpolation curve ( _f(x) = 6x^5-15x^4+10x^3_ ). This makes both ends of the curve more "flat" so each border gracefully stitches with the next one. In other words, you get a more continuous transition between the cells. You can see this by uncommenting the second formula in the following graph example (or see the [two equations side by side here](https://www.desmos.com/calculator/2xvlk5xp8b)). +An improvement by Perlin to his original non-simplex noise **Simplex Noise**, is the replacement of the cubic Hermite curve ( _f(x) = 3x^2-2x^3_ , which is identical to the [```smoothstep()```](../glossary/?search=smoothstep) function) with a quintic interpolation curve ( _f(x) = 6x^5-15x^4+10x^3_ ). This makes both ends of the curve more "flat" so each border gracefully stitches with the next one. In other words, you get a more continuous transition between the cells. You can see this by uncommenting the second formula in the following graph example (or see the [two equations side by side here](https://www.desmos.com/calculator/2xvlk5xp8b)).
y``` ("lower" triangle) or ```y > x``` ("upper" triangle). @@ -206,15 +206,15 @@ Well... enough technicalities, it's time for you to use this resource in your ow * Make a shader that projects the illusion of flow. Like a lava lamp, ink drops, water, etc. - + * Use Simplex Noise to add some texture to a work you've already made. - + -In this chapter we have introduced some control over the chaos. It was not an easy job! Becoming a noise-bender-master takes time and effort. +In this chapter we have introduced some control over the chaos. It was not an easy job! Becoming a noise-bender-master takes time and effort. In the following chapters we will see some well known techniques to perfect your skills and get more out of your noise to design quality generative content with shaders. Until then enjoy some time outside contemplating nature and its intricate patterns. Your ability to observe needs equal (or probably more) dedication than your making skills. Go outside and enjoy the rest of the day!

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

+

diff --git a/11/circleWave-noise.frag b/11/circleWave-noise.frag index 5605f31..51acfde 100644 --- a/11/circleWave-noise.frag +++ b/11/circleWave-noise.frag @@ -26,9 +26,9 @@ float noise(vec2 st) { vec2 u = f*f*(3.0-2.0*f); - return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), + return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), - mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), + mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); } @@ -60,4 +60,4 @@ void main() { vec3 color = vec3(1.0) * shapeBorder(st,0.8,0.02); gl_FragColor = vec4( 1.-color, 1.0 ); -} \ No newline at end of file +} diff --git a/11/iching-03.frag b/11/iching-03.frag index 8653775..e8bfbee 100644 --- a/11/iching-03.frag +++ b/11/iching-03.frag @@ -111,4 +111,4 @@ void main(){ df = mix(hex(st,t),hex(st,t+1.),fract(t)); df += snoise(vec3(st*75.,t*0.1))*0.03; gl_FragColor = vec4(mix(vec3(0.),vec3(1.),step(0.7,df)),1.0); -} \ No newline at end of file +} diff --git a/11/index.php b/11/index.php index 4245102..99aad27 100644 --- a/11/index.php +++ b/11/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/11/lava-lamp.frag b/11/lava-lamp.frag index d8e8126..5760515 100644 --- a/11/lava-lamp.frag +++ b/11/lava-lamp.frag @@ -63,4 +63,4 @@ void main() { color = vec3( smoothstep(.7,.75,fract(DF)) ); gl_FragColor = vec4(1.0-color,1.0); -} \ No newline at end of file +} diff --git a/11/notes.md b/11/notes.md index 58a06ba..4ee18ae 100644 --- a/11/notes.md +++ b/11/notes.md @@ -1,2 +1,2 @@ ### nicolas -* L78 replace `fract()` with `floor()` to match the prvious definition \ No newline at end of file +* L78 replace `fract()` with `floor()` to match the prvious definition diff --git a/11/simplex-grid.frag b/11/simplex-grid.frag index 978e600..8e9368f 100644 --- a/11/simplex-grid.frag +++ b/11/simplex-grid.frag @@ -47,4 +47,4 @@ void main() { // color = simplexGrid(st); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/splatter.frag b/11/splatter.frag index dea10fa..86a9bb3 100644 --- a/11/splatter.frag +++ b/11/splatter.frag @@ -20,9 +20,9 @@ float noise(vec2 st) { vec2 u = f*f*(3.0-2.0*f); - return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), + return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), - mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), + mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); } @@ -41,4 +41,4 @@ void main() { color -= smoothstep(.35,.4,noise(st*10.)); // Holes on splatter gl_FragColor = vec4(1.-color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/2d-snoise-normal.frag b/11/tmp/2d-snoise-normal.frag index 3706a76..063a23d 100644 --- a/11/tmp/2d-snoise-normal.frag +++ b/11/tmp/2d-snoise-normal.frag @@ -58,11 +58,11 @@ float snoise(vec2 v) { void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; - + float scale = 10.0; st += vec2(u_time*0.1); st *= scale; - + vec2 offset = vec2(1.)/u_resolution.xy; float center = snoise(vec2(st.x, st.y)); float topLeft = snoise(vec2(st.x - offset.x, st.y - offset.y)); @@ -73,11 +73,11 @@ void main(){ float topRight = snoise(vec2(st.x + offset.x, st.y - offset.y)); float right = snoise(vec2(st.x + offset.x, st.y)); float bottomRight= snoise(vec2(st.x + offset.x, st.y + offset.y)); - + float dX = topRight + 2.0 * right + bottomRight - topLeft - 2.0 * left - bottomLeft; float dY = bottomLeft + 2.0 * bottom + bottomRight - topLeft - 2.0 * top - topRight; - + vec3 N = normalize(vec3( dX, dY, 0.01))*.5+.5; gl_FragColor= vec4(N,1.); -} \ No newline at end of file +} diff --git a/11/tmp/3d-snoise-normal.frag b/11/tmp/3d-snoise-normal.frag index ba33196..430a6eb 100644 --- a/11/tmp/3d-snoise-normal.frag +++ b/11/tmp/3d-snoise-normal.frag @@ -13,7 +13,7 @@ vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } -float snoise(vec3 v) { +float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); @@ -32,10 +32,10 @@ float snoise(vec3 v) { vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations - i = mod289(i); - vec4 p = permute( permute( permute( + i = mod289(i); + vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. @@ -77,17 +77,17 @@ float snoise(vec3 v) { // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), + return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; - + float scale = 10.0; st *= scale; float t = u_time*0.3; - + vec2 offset = vec2(1.)/u_resolution.xy; float center = snoise(vec3(st.x, st.y, t)); float topLeft = snoise(vec3(st.x - offset.x, st.y - offset.y, t)); @@ -98,11 +98,11 @@ void main(){ float topRight = snoise(vec3(st.x + offset.x, st.y - offset.y, t)); float right = snoise(vec3(st.x + offset.x, st.y, t)); float bottomRight= snoise(vec3(st.x + offset.x, st.y + offset.y, t)); - + float dX = topRight + 2.0 * right + bottomRight - topLeft - 2.0 * left - bottomLeft; float dY = bottomLeft + 2.0 * bottom + bottomRight - topLeft - 2.0 * top - topRight; - + vec3 N = normalize(vec3( dX, dY, 0.01))*.5+.5; gl_FragColor= vec4(N,1.); -} \ No newline at end of file +} diff --git a/11/tmp/circleDistortion.frag b/11/tmp/circleDistortion.frag index 46d4063..51ee869 100644 --- a/11/tmp/circleDistortion.frag +++ b/11/tmp/circleDistortion.frag @@ -90,7 +90,7 @@ float shapeBorder(vec2 st, float radius, float width) { void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; - + vec3 color = vec3(0.0); vec3 normals = nNoise(st*6.+u_time); color = vec3(1.) * shapeBorder(st,0.8,0.02); @@ -98,4 +98,4 @@ void main() { color.g = shapeBorder(st+normals.xy*.01,0.81,0.03); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/11/tmp/circleWave-noiseChannels.frag b/11/tmp/circleWave-noiseChannels.frag index cb573cd..ded8162 100644 --- a/11/tmp/circleWave-noiseChannels.frag +++ b/11/tmp/circleWave-noiseChannels.frag @@ -86,7 +86,7 @@ void main() { float t = u_time*.1; color.r = shapeBorder(st,vec2(0.1,t),0.8,0.02); color.g = shapeBorder(st,vec2(0.2,t),0.8,0.02); - color.b = shapeBorder(st,vec2(0.3,t),0.8,0.02); + color.b = shapeBorder(st,vec2(0.3,t),0.8,0.02); gl_FragColor = vec4( color, 1.0 ); -} \ No newline at end of file +} diff --git a/11/tmp/displace-grid.frag b/11/tmp/displace-grid.frag index 3de7b53..de0b7d2 100644 --- a/11/tmp/displace-grid.frag +++ b/11/tmp/displace-grid.frag @@ -67,10 +67,10 @@ vec3 nNoise(vec2 st) { float topRight = snoise(vec2(st.x + offset.x, st.y - offset.y)); float right = snoise(vec2(st.x + offset.x, st.y)); float bottomRight= snoise(vec2(st.x + offset.x, st.y + offset.y)); - + float dX = topRight + 2.0 * right + bottomRight - topLeft - 2.0 * left - bottomLeft; float dY = bottomLeft + 2.0 * bottom + bottomRight - topLeft - 2.0 * top - topRight; - + return normalize(vec3( dX, dY, 0.01))*.5+.5; } @@ -96,6 +96,6 @@ void main(){ st += nNoise(st*10.).xy*.02*sin(u_time); float grid = 1.0-X(tile(st,10.),0.05); - + gl_FragColor= vec4(vec3(grid),1.); -} \ No newline at end of file +} diff --git a/11/tmp/displace-lines.frag b/11/tmp/displace-lines.frag index fb71d88..5f995c4 100644 --- a/11/tmp/displace-lines.frag +++ b/11/tmp/displace-lines.frag @@ -67,10 +67,10 @@ vec3 nNoise(vec2 st) { float topRight = snoise(vec2(st.x + offset.x, st.y - offset.y)); float right = snoise(vec2(st.x + offset.x, st.y)); float bottomRight= snoise(vec2(st.x + offset.x, st.y + offset.y)); - + float dX = topRight + 2.0 * right + bottomRight - topLeft - 2.0 * left - bottomLeft; float dY = bottomLeft + 2.0 * bottom + bottomRight - topLeft - 2.0 * top - topRight; - + return normalize(vec3( dX, dY, 0.01))*.5+.5; } @@ -82,6 +82,6 @@ void main(){ st += nNoise(st).xy*.1*sin(u_time); float df = sin(fract(st.y)*10.); - + gl_FragColor= vec4(vec3(1.0-smoothstep(.9,.99,df)),1.); -} \ No newline at end of file +} diff --git a/11/tmp/makegif.sh b/11/tmp/makegif.sh index d2edaf8..19bb662 100755 --- a/11/tmp/makegif.sh +++ b/11/tmp/makegif.sh @@ -7,7 +7,7 @@ COUNTER=0 for i in `seq -w 0.01 .031 $SEC`; do echo $i `glslViewer $FILE -s $i -o frame-$COUNTER.png` - let COUNTER=COUNTER+1 + let COUNTER=COUNTER+1 done convert -delay 3.5 -loop 1 frame-*.png animated.gif diff --git a/11/tmp/noise-move.frag b/11/tmp/noise-move.frag index 0d82c7f..f6b18c9 100644 --- a/11/tmp/noise-move.frag +++ b/11/tmp/noise-move.frag @@ -34,14 +34,14 @@ float box(in vec2 _st, in vec2 _size){ } float cross(in vec2 _st, float _size){ - return box(_st, vec2(_size,_size/4.)) + + return box(_st, vec2(_size,_size/4.)) + box(_st, vec2(_size/4.,_size)); } void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); - + // To move the cross we move the space vec2 translate = vec2(cos(noise(u_time)*3.1415*2.0), sin(noise(u_time)*3.1415*2.0)); @@ -54,4 +54,4 @@ void main(){ color += vec3(cross(st,0.25)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/simplex-pattern-00.frag b/11/tmp/simplex-pattern-00.frag index 401223a..d624658 100644 --- a/11/tmp/simplex-pattern-00.frag +++ b/11/tmp/simplex-pattern-00.frag @@ -114,4 +114,4 @@ void main() { gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/simplex-pattern-01.frag b/11/tmp/simplex-pattern-01.frag index c08a2e7..c28a068 100644 --- a/11/tmp/simplex-pattern-01.frag +++ b/11/tmp/simplex-pattern-01.frag @@ -61,4 +61,4 @@ void main() { color += step(.5,abs(sin(.5-S.b*3.1415*5.-t))); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/simplex-pattern-02.frag b/11/tmp/simplex-pattern-02.frag index ce86045..4b42c69 100644 --- a/11/tmp/simplex-pattern-02.frag +++ b/11/tmp/simplex-pattern-02.frag @@ -84,4 +84,4 @@ void main() { color = 1.-vec3(color.r + color.g + color.b); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/simplex-pattern-03.frag b/11/tmp/simplex-pattern-03.frag index 1860728..28b0ebd 100644 --- a/11/tmp/simplex-pattern-03.frag +++ b/11/tmp/simplex-pattern-03.frag @@ -84,7 +84,7 @@ vec2 sphereCoords(vec2 _st, float _scale){ } // -// Description : Array and textureless GLSL 2D/3D/4D simplex +// Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm @@ -92,13 +92,13 @@ vec2 sphereCoords(vec2 _st, float _scale){ // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } -float snoise(vec3 v) { +float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); @@ -117,10 +117,10 @@ float snoise(vec3 v) { vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations - i = mod289(i); - vec4 p = permute( permute( permute( + i = mod289(i); + vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. @@ -162,7 +162,7 @@ float snoise(vec3 v) { // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), + return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } @@ -187,4 +187,4 @@ void main() { color *= step(0.001,radius); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/simplex-pattern-04.frag b/11/tmp/simplex-pattern-04.frag index f6d9e50..6644063 100644 --- a/11/tmp/simplex-pattern-04.frag +++ b/11/tmp/simplex-pattern-04.frag @@ -59,7 +59,7 @@ vec3 aastep(float threshold, vec3 value) { } // -// Description : Array and textureless GLSL 2D/3D/4D simplex +// Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm @@ -67,13 +67,13 @@ vec3 aastep(float threshold, vec3 value) { // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } -float snoise(vec3 v) { +float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); @@ -92,10 +92,10 @@ float snoise(vec3 v) { vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations - i = mod289(i); - vec4 p = permute( permute( permute( + i = mod289(i); + vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. @@ -137,7 +137,7 @@ float snoise(vec3 v) { // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), + return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } @@ -155,4 +155,4 @@ void main() { pct = S.r * S.g * S.b; color = vec3(pct); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/11/tmp/vortex.frag b/11/tmp/vortex.frag index e2f2550..fdff5cd 100644 --- a/11/tmp/vortex.frag +++ b/11/tmp/vortex.frag @@ -17,7 +17,7 @@ uniform float u_time; // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } diff --git a/11/tmp/warp-grid.frag b/11/tmp/warp-grid.frag index 067e684..29b3d8a 100644 --- a/11/tmp/warp-grid.frag +++ b/11/tmp/warp-grid.frag @@ -20,9 +20,9 @@ float noise(vec2 st) { vec2 u = f*f*(3.0-2.0*f); - return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), + return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), - mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), + mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); } @@ -43,7 +43,7 @@ float X(vec2 _st, float _width){ // -// Description : Array and textureless GLSL 2D/3D/4D simplex +// Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : ijm @@ -51,13 +51,13 @@ float X(vec2 _st, float _width){ // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } -float snoise(vec3 v) { +float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); @@ -76,10 +76,10 @@ float snoise(vec3 v) { vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations - i = mod289(i); - vec4 p = permute( permute( permute( + i = mod289(i); + vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) - + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. @@ -121,7 +121,7 @@ float snoise(vec3 v) { // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), + return 42.0 * dot( m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } @@ -132,4 +132,4 @@ void main() { float grid = 1.0-X(tile(st,15.+snoise(vec3(st,u_time*.1))),0.05); gl_FragColor = vec4(vec3(grid),1.0); -} \ No newline at end of file +} diff --git a/11/wood.frag b/11/wood.frag index 2afdf05..93554de 100644 --- a/11/wood.frag +++ b/11/wood.frag @@ -9,9 +9,9 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, - vec2(12.9898,78.233))) + vec2(12.9898,78.233))) * 43758.5453123); } @@ -21,9 +21,9 @@ float noise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); - return mix( mix( random( i + vec2(0.0,0.0) ), + return mix( mix( random( i + vec2(0.0,0.0) ), random( i + vec2(1.0,0.0) ), u.x), - mix( random( i + vec2(0.0,1.0) ), + mix( random( i + vec2(0.0,1.0) ), random( i + vec2(1.0,1.0) ), u.x), u.y); } @@ -50,9 +50,9 @@ void main() { // Add noise pos = rotate2d( noise(pos) ) * pos; - + // Draw lines pattern = lines(pos,.5); gl_FragColor = vec4(vec3(pattern),1.0); -} \ No newline at end of file +} diff --git a/12/2d-voronoi.frag b/12/2d-voronoi.frag index bb7a902..c47f16e 100644 --- a/12/2d-voronoi.frag +++ b/12/2d-voronoi.frag @@ -26,7 +26,7 @@ vec3 voronoi( in vec2 x ) { vec2 g = vec2(float(i),float(j)); vec2 o = random2( n + g ); o = 0.5 + 0.5*sin( u_time + 6.2831*o ); - + vec2 r = g + o - f; float d = dot(r,r); @@ -61,17 +61,17 @@ void main() { st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(0.); - // Scale + // Scale st *= 3.; vec3 c = voronoi(st); // isolines color = c.x*(0.5 + 0.5*sin(64.0*c.x))*vec3(1.0); - // borders + // borders color = mix( vec3(1.0), color, smoothstep( 0.01, 0.02, c.x ) ); // feature points float dd = length( c.yz ); color += vec3(1.)*(1.0-smoothstep( 0.0, 0.04, dd)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/2d-voronoise.frag b/12/2d-voronoise.frag index e06336e..2db2271 100644 --- a/12/2d-voronoise.frag +++ b/12/2d-voronoise.frag @@ -10,8 +10,8 @@ uniform float u_time; // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. // http://iquilezles.org/www/articles/voronoise/voronoise.htm vec3 hash3( vec2 p ) { - vec3 q = vec3( dot(p,vec2(127.1,311.7)), - dot(p,vec2(269.5,183.3)), + vec3 q = vec3( dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3)), dot(p,vec2(419.2,371.9)) ); return fract(sin(q)*43758.5453); } @@ -19,9 +19,9 @@ vec3 hash3( vec2 p ) { float iqnoise( in vec2 x, float u, float v ) { vec2 p = floor(x); vec2 f = fract(x); - + float k = 1.0+63.0*pow(1.0-v,4.0); - + float va = 0.0; float wt = 0.0; for (int j=-2; j<=2; j++) { @@ -35,7 +35,7 @@ float iqnoise( in vec2 x, float u, float v ) { wt += ww; } } - + return va/wt; } @@ -48,4 +48,4 @@ void main() { float n = iqnoise(st, u_mouse.x/u_resolution.x, u_mouse.y/u_resolution.y); gl_FragColor = vec4(vec3(n),1.0); -} \ No newline at end of file +} diff --git a/12/README-de.md b/12/README-de.md index 7ac6d85..7255f4e 100644 --- a/12/README-de.md +++ b/12/README-de.md @@ -10,7 +10,7 @@ Lass uns dazu am besten ein Beispiel anschauen. ### Punkte für ein Distanzfeld -Zelluläres Rauschen basiert auf Distanzfeldern, konkret auf der Berechnung der Entfernung zum nächstgelegenen Bezugspunkt aus einer gegebenen Menge von Punkten. Lass uns annehmen, wir wollten ein Distanzfeld aus vier Punkten erzeugen. Was benötigen wir dafür? Nun, **für jeden zu berechnenden Bildpunkt auf unserer Zeichenfläche wollen wir die Entfernung zum nächstgelegenen der vier Bezugspunkte berechnen **. Das bedeutet, dass wir alle vier Bezugspunkte durchlaufen, ihre Entfernung zum aktuell bearbeiteten Pixel berechnen und uns die kleinste dieser Entfernungen merken müssen. +Zelluläres Rauschen basiert auf Distanzfeldern, konkret auf der Berechnung der Entfernung zum nächstgelegenen Bezugspunkt aus einer gegebenen Menge von Punkten. Lass uns annehmen, wir wollten ein Distanzfeld aus vier Punkten erzeugen. Was benötigen wir dafür? Nun, **für jeden zu berechnenden Bildpunkt auf unserer Zeichenfläche wollen wir die Entfernung zum nächstgelegenen der vier Bezugspunkte berechnen **. Das bedeutet, dass wir alle vier Bezugspunkte durchlaufen, ihre Entfernung zum aktuell bearbeiteten Pixel berechnen und uns die kleinste dieser Entfernungen merken müssen. ```glsl float min_dist = 100.; // speichert die kleineste Entf. zu einem der 4 Bezugspunkte @@ -41,7 +41,7 @@ In dem obigen Shader wird einer der Bezugspunkte des Distanzfelds auf die Mauspo - Gelingt es Dir, die Position der anderen Bezugspunkte zu animieren? - Nachdem Du [das Kapitel über Formen](../07/?lan=de) ja vermutlich bereits gelesen hast, stelle Dir einen interessanten Weg vor, was man mit dem vorliegenden Distanzfeld anstellen könnte. -- Was muss man tun, um das Distanzfeld um weitere Bezugspunkte zu erweitern? Wie können wir dynamisch einzelne Bezugspunkte hinzufügen oder entfernen? +- Was muss man tun, um das Distanzfeld um weitere Bezugspunkte zu erweitern? Wie können wir dynamisch einzelne Bezugspunkte hinzufügen oder entfernen? ### Kachelung und Wiederholung @@ -53,16 +53,16 @@ Ein Ansatz, um sich dieser Herausforderung zu stellen, ist die Unterteilung der Weil die Farbe für jeden Pixel in einem eigenen Thread berechnet wird, können wir die Zeichenfläche in einzelne Zellen unterteilen - jede mit einem Bezugspunkt. -Um Anomalien an den Schnittflächen zwischen den Zellen zu vermeiden, müssen wir jeweils die Entfernung zum Bezugspunkt der benachbarten Zellen überprüfen. Das ist im Wesentlichen die brillante Idee hinter dem [Ansatz von Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf). +Um Anomalien an den Schnittflächen zwischen den Zellen zu vermeiden, müssen wir jeweils die Entfernung zum Bezugspunkt der benachbarten Zellen überprüfen. Das ist im Wesentlichen die brillante Idee hinter dem [Ansatz von Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Letztendlich muss jeder Pixel nur die Entfernung zu neun Bezugspunkten berechnen: Dem seiner eigenen Zelle und jene der acht umliegenden Zellen. Alle anderen Zellen sind zu weit entfernt. -Wir haben bereits in den Kapiteln über [Muster](../09/?lan=de), [Generative Designs](../10/?lan=de) und [Rauschen](../11/?lan=de) gesehen, wie man die Zeichenfläche in einzelne Zellen unterteilt, von daher bist Du mit diesem Prinzip wahrscheinlich schon vertraut. +Wir haben bereits in den Kapiteln über [Muster](../09/?lan=de), [Generative Designs](../10/?lan=de) und [Rauschen](../11/?lan=de) gesehen, wie man die Zeichenfläche in einzelne Zellen unterteilt, von daher bist Du mit diesem Prinzip wahrscheinlich schon vertraut. ```glsl // den Raum aufblaehen ... st *= 3.; - + // ... und in Zellen unterteilen vec2 i_st = floor(st); vec2 f_st = fract(st); @@ -83,7 +83,7 @@ Der jeweils zu zeichnende Bildpunkt innerhalb der Zelle (gespeichert in dem Flie Das Ergebnis sieht dann wie folgt aus: - + Aber wir wollen ja zusätzlich noch die Entfernung zu den Bezugspunkten in den umliegenden Zellen einbeziehen. Dafür müssen wir diese Zellen **durchlaufen**. Aber nicht alle, sondern nur die unmittelbar angrenzenden. Das heißt die Zellen mit den Abständen von ```-1``` (links) bis ```1``` (rechts) entlang der ```x```-Achse, sowie die Zellen mit den Abständen von ```-1``` (unten) bis ```1``` (oben) entlang der ```y```-Achse. Dieser Bereich von 3x3 Zellen lässt sich leicht mit Hilfe einer doppelten ```for```-Schleife abarbeiten, so wie im Folgenden gezeigt: @@ -103,7 +103,7 @@ Nun können wir die Bezugspunkte aus jeder der benachbarten Zellen in unserer do ```glsl ... - // Zufallsposition von der aktuellen + der benachbarten Zelle im Raster + // Zufallsposition von der aktuellen + der benachbarten Zelle im Raster vec2 point = random2(i_st + neighbor); ... ``` @@ -113,7 +113,7 @@ Dann bleibt nur noch, die Entfernung vom aktuell zu zeichnenden Punkt zu dem jew ```glsl ... vec2 diff = neighbor + point - f_st; - + // Entfernung zu diesem Punkt float dist = length(diff); @@ -126,7 +126,7 @@ Der obige Programmcode wurde durch einen [Artikel von Inigo Quilez](http://www.i „... es ist vielleicht interessant darauf hinzuweisen, dass in dem obigen Code ein netter Trick steckt. Die meisten Implementationen dieses Algorithmus leiden unter einer schlechten Präzision der Berechnungen, weil sie die zufälligen Bezugspunkte auf den gesamten Koordinatenraum beziehen, so dass die Koordinaten sehr weit vom Ursprung entfernt sind. Man kann dagegen ansteuern, indem man Variablentypen mit besonders hoher Genauigkeit verwendet, was sich jedoch negativ auf die Geschwindigkeit der Berechnungen auswirkt. Oder man macht es etwas cleverer, indem man die Koordinaten nicht auf den gesamten Koordinatenraum bezieht, sondern auf die Ebene der einzelnen Zellen: Sobald der ganzzahlige Teil und der Nachkommateil des zu zeichnenden Punktes berechnet sind und dadurch die Zelle feststeht, in der sich der Punkt befindet, beschäftigen wir uns nur noch damit, was um diese Zelle herum geschieht. Dadurch müssen wir uns nicht mehr um den ganzzahligen Teil der Koordinaten kümmern, wodurch man viele Bits bei den weiteren Berechnungen einspart. Tatsächlich steuern bei herkömmlichen Voronoi-Implementierungen die ganzzahligen Anteile der Punktkoordinaten ebenfalls dem Wert 0 entgegen, sobald die zufälligen Bezugspunkte der Zellen vom aktuell zu zeichnenden Punkt abgezogen werden. In der obigen Implementation lassen wir es gar nicht erst so weit kommen, weil wir alle Koordinatenberechnungen auf den Raum der Zellen beziehen. Mit diesem Trick kann man sogar einen ganzen Planeten mit derartig geformten Voronoi-Zellen überziehen, indem man die Punktkoordinaten einfach in doppelter Fließkommagenauigkeit darstellt, die Berechnungen von ```floor()``` und ```fract()``` durchführt, und dann mit einfacher Fließkommagenauigkeit fortfährt. So erspart man sich den (Zeit-) Aufwand, die gesamte Berechnung mit doppelter Fließkommagenauigkeit auszuführen. Natürlich kann man diesen Trick auch auf Perlins Noise-Algorithmus anwenden (allerdings habe ich noch nie ein solche Implementation gesehen). “ -Um es noch einmal zusammenzufassen: Wir unterteilen den Raum in einzelne Zellen. Für jeden zu zeichnenden Punkt berechnen wir die kleinste Entfernung zum Bezugspunkt seiner Zelle bzw. zu den Bezugspunkten der acht umliegenden Zellen. Als Ergebnis erhalten wir ein Distanzfeld, so wie in dem folgenden Beispiel: +Um es noch einmal zusammenzufassen: Wir unterteilen den Raum in einzelne Zellen. Für jeden zu zeichnenden Punkt berechnen wir die kleinste Entfernung zum Bezugspunkt seiner Zelle bzw. zu den Bezugspunkten der acht umliegenden Zellen. Als Ergebnis erhalten wir ein Distanzfeld, so wie in dem folgenden Beispiel:
@@ -155,19 +155,19 @@ Die Erzeugung von Voronoi-Diagrammen auf Basis von zellulärem Rauschen ist weni ... ``` -Bitte beachte, dass wir in dem folgenden Programmcode die geringste Entfernung nicht mehr mit Hilfe der ```min```-Funktion berechnen, sondern einen herkömmlichen ```if```-Befehl einsetzen. Warum wir das tun? Weil wir diesmal etwas mehr unternehmen wollen, sobald ein neuer näherliegender Punkt auftaucht, nämlich seine Position speichern (*Programmzeilen 32 bis 37*). +Bitte beachte, dass wir in dem folgenden Programmcode die geringste Entfernung nicht mehr mit Hilfe der ```min```-Funktion berechnen, sondern einen herkömmlichen ```if```-Befehl einsetzen. Warum wir das tun? Weil wir diesmal etwas mehr unternehmen wollen, sobald ein neuer näherliegender Punkt auftaucht, nämlich seine Position speichern (*Programmzeilen 32 bis 37*).
Du wirst sehen, dass die Farbe der beweglichen Zelle (die dem Mauszeiger folgt) auf Basis ihrer Position wechselt. Die Ursache dafür ist, dass hier die Farbe aufgrund des Wertes (der Position) des nächstgelegenen Bezugspunktes zugewiesen wird. -Genau wie zuvor ist es nun an der Zeit, das Ganze zu erweitern, indem wir zu dem Algorithmus aus dem [Papier von Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf) übergehen. Versuche doch einmal selbst, diesen Algorithmus zu implementieren. Du kannst dabei auf das folgende Beispiel zurückgreifen, indem Du darauf klickst. +Genau wie zuvor ist es nun an der Zeit, das Ganze zu erweitern, indem wir zu dem Algorithmus aus dem [Papier von Steven Worley](http://www.rhythmiccanvas.com/research/papers/worley.pdf) übergehen. Versuche doch einmal selbst, diesen Algorithmus zu implementieren. Du kannst dabei auf das folgende Beispiel zurückgreifen, indem Du darauf klickst. -Bitte beachte, dass der ursprüngliche Ansatz von Steven Worley eine variable Anzahl von Bezugspunkten für jede Zelle vorsieht. In seiner Implementation des Algorithmus in C nutzt er dies für einen zeitigen Abbruch der Schleife. Schleifen in GLSL erlauben jedoch keinen vorzeitigen Ausstieg oder eine variable Anzahl von Schleifendurchläufen, deshalb wirst Du vielleicht besser bei einem Bezugspunkt pro Zelle bleiben. +Bitte beachte, dass der ursprüngliche Ansatz von Steven Worley eine variable Anzahl von Bezugspunkten für jede Zelle vorsieht. In seiner Implementation des Algorithmus in C nutzt er dies für einen zeitigen Abbruch der Schleife. Schleifen in GLSL erlauben jedoch keinen vorzeitigen Ausstieg oder eine variable Anzahl von Schleifendurchläufen, deshalb wirst Du vielleicht besser bei einem Bezugspunkt pro Zelle bleiben. -Sobald Du die Funktionsweise dieses Algorithmus verstanden hast, kannst Du über interessante und kreative Einsatzmöglichkeiten nachdenken. +Sobald Du die Funktionsweise dieses Algorithmus verstanden hast, kannst Du über interessante und kreative Einsatzmöglichkeiten nachdenken. ![Extended Voronoi - Leo Solaas (2011)](solas.png) @@ -187,16 +187,15 @@ Im Jahre 2011 hat [Stefan Gustavson eine Optimierung von Steven Worleys Algorith Im Jahre 2012 präsentierte [Inigo Quilez einen interessanten Artikel über die Erzeugung präziser Voronoi-Abgrenzungen](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm). - + Inigos Experimente zu diesem Thema hörten damit nicht auf. Im Jahr 2014 verfasste er einen schönen Beitrag über das, was er als [Voro-Noise, dt. „Voro-Rauschen“](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm) bezeichnet - eine Funktion, die einen graduellen Übergang zwischen normalem Rauschen und Voronoi-Rauschen ermöglicht. Er schrieb: „Abgesehen von ihrer Ähnlichkeit ist es entscheidend, dass das Raster aus Zellen in beiden Mustern unterschiedlich verwendet wird. Interpoliertes Rauschen mit Zufallswerten (wie bei Value-Noise) oder mit Gradienten (wie bei Gradient-Noise) unterscheidet sich von Voronoi, wo es auf die Entfernung zum nächstgelegenen Bezugspunkt ankommt. Schließlich sind die bilineare Interpolation und die Minima-Berechnung zwei ganz unterschiedliche Operationen, nicht wahr? Doch vielleicht kann man sie in einem größeren Rahmen vereinigen? Sollte das möglich sein, könnte man sowohl Rauschmuster als auch Voronoi-Muster als Spezialfälle eines allgemeineren rasterbasierten Mustergenerators betrachten.“ - + Nun ist die Zeit gekommen, dass Du Dir die Dinge genau anschaust, Dich von der Natur inspirieren lässt und Deine eigene Nutzungsmöglichkeiten dieser Techniken entdeckst! ![Deyrolle glass film - 1831](DeyrolleFilm.png)
- diff --git a/12/README-fr.md b/12/README-fr.md index dc1cdca..73b12f8 100644 --- a/12/README-fr.md +++ b/12/README-fr.md @@ -190,13 +190,13 @@ Cela amoindrit la charge de manière significative mais peut créer des artefact Plus tard, en 2012 [Inigo Quilez a écrit un article expliquant comment trouver des frontières précises](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm). - + Inigio ne s'est pas arrété là et en 2014, il a écrit un article sur ce qu'il a appelé le [voro-noise](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm) ; une exploration combinant bruit et cellules de Voronoi. Je cite: *"Despite this similarity, the fact is that the way the grid is used in both patterns is different. Noise interpolates/averages random values (as in value noise) or gradients (as in gradient noise), while Voronoi computes the distance to the closest feature point. Now, smooth-bilinear interpolation and minimum evaluation are two very different operations, or... are they? Can they perhaps be combined in a more general metric? If that was so, then both Noise and Voronoi patterns could be seen as particular cases of a more general grid-based pattern generator?"* - + Il est temps de revenir à la nature, d'être inspiré par elle et de trouver votre propre voie au travers de cette technique. diff --git a/12/README.md b/12/README.md index 8f85ad2..0832294 100644 --- a/12/README.md +++ b/12/README.md @@ -52,9 +52,9 @@ You probably notice that ```for``` loops and *arrays* are not very good friends One way to approach this problem is to divide the space into tiles. Not every pixel needs to check the distance to every single point, right? Given the fact that each pixel runs in its own thread, we can subdivide the space into cells, each one with one unique point to watch. Also, to avoid aberrations at the edges between cells we need to check for the distances to the points on the neighboring cells. That's the main brillant idea of [Steven Worley's paper](http://www.rhythmiccanvas.com/research/papers/worley.pdf). At the end, each pixel needs to check only nine positions: their own cell's point and the points in the 8 cells around it. We already subdivide the space into cells in the chapters about: [patterns](../09/), [random](../10/) and [noise](../11/), so hopefully you are familiar with this technique by now. ```glsl - // Scale + // Scale st *= 3.; - + // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); @@ -66,7 +66,7 @@ So, what's the plan? We will use the tile coordinates (stored in the integer coo vec2 point = random2(i_st); ``` -Each pixel inside that tile (stored in the float coordinate, ```f_st```) will check their distance to that random point. +Each pixel inside that tile (stored in the float coordinate, ```f_st```) will check their distance to that random point. ```glsl vec2 diff = point - f_st; @@ -75,7 +75,7 @@ Each pixel inside that tile (stored in the float coordinate, ```f_st```) will ch The result will look like this: - + We still need to check the distances to the points in the surrounding tiles, not just the one in the current tile. For that we need to **iterate** through the neighbor tiles. Not all tiles, just the ones immediately around the current one. That means from ```-1``` (left) to ```1``` (right) tile in ```x``` axis and ```-1``` (bottom) to ```1``` (top) in ```y``` axis. A 3x3 region of 9 tiles can be iterated through using a double ```for``` loop like this one: @@ -105,7 +105,7 @@ The rest is all about calculating the distance to that point and store the close ```glsl ... vec2 diff = neighbor + point - f_st; - + // Distance to the point float dist = length(diff); @@ -147,11 +147,11 @@ Constructing Voronoi diagrams from cellular noise is less hard that what it migh ... ``` -Note that in the following code that we are not longer using ```min``` to calculate the closest distance, but a regular ```if``` statement. Why? Because we actually want to do something more every time a new closer point appears, namely store its position (lines 32 to 37). +Note that in the following code that we are not longer using ```min``` to calculate the closest distance, but a regular ```if``` statement. Why? Because we actually want to do something more every time a new closer point appears, namely store its position (lines 32 to 37).
-Note how the color of the moving cell (bound to the mouse position) changes color according to its position. That's because the color is assigned using the value (position) of the closest point. +Note how the color of the moving cell (bound to the mouse position) changes color according to its position. That's because the color is assigned using the value (position) of the closest point. Like we did before, now is the time to scale this up, switching to [Steven Worley's paper approach](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Try implementing it yourself. You can use the help of the following example by clicking on it. Note that Steven Worley's original approach uses a variable number of feature points for each tile, more than one in most tiles. In his software implementation in C, this is used to speed up the loop by making early exits. GLSL loops don't allow variable number of iterations, so you probably want to stick to one feature point per tile. @@ -176,12 +176,12 @@ In 2011, [Stefan Gustavson optimized Steven Worley's algorithm to GPU](http://we Later in 2012 [Inigo Quilez wrote an article on how to make precise Voronoi borders](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm). - + Inigo's experiments with Voronoi didn't stop there. In 2014 he wrote this nice article about what he calls [voro-noise](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm), an function that allows a gradual blend between regular noise and voronoi. In his words: *"Despite this similarity, the fact is that the way the grid is used in both patterns is different. Noise interpolates/averages random values (as in value noise) or gradients (as in gradient noise), while Voronoi computes the distance to the closest feature point. Now, smooth-bilinear interpolation and minimum evaluation are two very different operations, or... are they? Can they perhaps be combined in a more general metric? If that was so, then both Noise and Voronoi patterns could be seen as particular cases of a more general grid-based pattern generator?"* - + Now it's time for you to look closely at things, be inspired by nature and find your own take on this technique! diff --git a/12/TITLE.md b/12/TITLE.md index 9894e48..6e21476 100644 --- a/12/TITLE.md +++ b/12/TITLE.md @@ -1 +1 @@ -Cellular Noise \ No newline at end of file +Cellular Noise diff --git a/12/cellnoise-00.frag b/12/cellnoise-00.frag index fb93204..f835985 100644 --- a/12/cellnoise-00.frag +++ b/12/cellnoise-00.frag @@ -22,22 +22,22 @@ void main() { point[2] = vec2(0.28,0.64); point[3] = vec2(0.31,0.26); point[4] = u_mouse/u_resolution; - + float m_dist = 1.; // minimun distance // Iterate through the points positions for (int i = 0; i < 5; i++) { float dist = distance(st, point[i]); - + // Keep the closer distance m_dist = min(m_dist, dist); } - + // Draw the min distance (distance field) color += m_dist; // Show isolines // color -= step(.7,abs(sin(50.0*m_dist)))*.3; - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/cellnoise-01.frag b/12/cellnoise-01.frag index 4d19964..81b03fd 100644 --- a/12/cellnoise-01.frag +++ b/12/cellnoise-01.frag @@ -17,17 +17,17 @@ void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(.0); - - // Scale + + // Scale st *= 3.; - + // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); vec2 point = random2(i_st); vec2 diff = point - f_st; - + float dist = length(diff); // Draw the min distance (distance field) @@ -35,12 +35,12 @@ void main() { // Draw cell center color += 1.-step(.02, dist); - + // Draw grid color.r += step(.98, f_st.x) + step(.98, f_st.y); - + // Show isolines // color -= step(.7,abs(sin(27.0*dist)))*.5; - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/cellnoise-02.frag b/12/cellnoise-02.frag index 0ac68f6..cf79de2 100644 --- a/12/cellnoise-02.frag +++ b/12/cellnoise-02.frag @@ -17,30 +17,30 @@ void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(.0); - - // Scale + + // Scale st *= 3.; - + // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); float m_dist = 1.; // minimun distance - + for (int y= -1; y <= 1; y++) { for (int x= -1; x <= 1; x++) { // Neighbor place in the grid vec2 neighbor = vec2(float(x),float(y)); - + // Random position from current + neighbor place in the grid vec2 point = random2(i_st + neighbor); // Animate the point point = 0.5 + 0.5*sin(u_time + 6.2831*point); - + // Vector between the pixel and the point vec2 diff = neighbor + point - f_st; - + // Distance to the point float dist = length(diff); @@ -54,12 +54,12 @@ void main() { // Draw cell center color += 1.-step(.02, m_dist); - + // Draw grid color.r += step(.98, f_st.x) + step(.98, f_st.y); - + // Show isolines // color -= step(.7,abs(sin(27.0*m_dist)))*.5; - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/index.php b/12/index.php index bb36815..300bfee 100644 --- a/12/index.php +++ b/12/index.php @@ -1,4 +1,4 @@ -0.00001 ) @@ -72,15 +72,15 @@ void main() { st.x -= (u_resolution.x*.5-u_resolution.y*.5)/u_resolution.y; } vec3 color = vec3(0.0); - + float d = dot(st-.5,st-.5); vec3 c = voronoi( 20.*st, pow(d,.4) ); - // borders + // borders color = mix( vec3(1.0), color, smoothstep( 0.01, 0.02, c.x ) ); // feature points float dd = length( c.yz ); color += vec3(1.)*(1.0-smoothstep( 0.0, 0.1, dd)); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/tmp/particle-gradient.frag b/12/tmp/particle-gradient.frag index b922744..524e6d6 100755 --- a/12/tmp/particle-gradient.frag +++ b/12/tmp/particle-gradient.frag @@ -59,7 +59,7 @@ void main(void) { n = step(pct,F.x*2.); vec2 p = vec2(2./u_resolution.xy); - + float avg = 0.0; avg += getIntensity(st+vec2(p.x,0.0)); avg += getIntensity(st+vec2(-p.x,0.0)); diff --git a/12/vorono-00.frag b/12/vorono-00.frag index 4eea952..51df08b 100644 --- a/12/vorono-00.frag +++ b/12/vorono-00.frag @@ -22,7 +22,7 @@ void main() { point[2] = vec2(0.28,0.64); point[3] = vec2(0.31,0.26); point[4] = u_mouse/u_resolution; - + float m_dist = 1.; // minimun distance vec2 m_point; // minimum position @@ -38,17 +38,17 @@ void main() { } } - // Add distance field to closest point center + // Add distance field to closest point center color += m_dist*2.; // tint acording the closest point position color.rg = m_point; - + // Show isolines color -= abs(sin(80.0*m_dist))*0.07; - + // Draw point center color += 1.-step(.02, m_dist); - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/12/vorono-01.frag b/12/vorono-01.frag index 3fdd7fe..d6feb04 100644 --- a/12/vorono-01.frag +++ b/12/vorono-01.frag @@ -17,17 +17,17 @@ void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x/u_resolution.y; vec3 color = vec3(.0); - - // Scale + + // Scale st *= 5.; - + // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); float m_dist = 10.; // minimun distance vec2 m_point; // minimum point - + for (int j=-1; j<=1; j++ ) { for (int i=-1; i<=1; i++ ) { vec2 neighbor = vec2(float(i),float(j)); @@ -45,18 +45,18 @@ void main() { // Assign a color using the closest point position color += dot(m_point,vec2(.3,.6)); - - // Add distance field to closest point center + + // Add distance field to closest point center // color.g = m_dist; // Show isolines color -= abs(sin(40.0*m_dist))*0.07; - + // Draw cell center color += 1.-step(.05, m_dist); - + // Draw grid color.r += step(.98, f_st.x) + step(.98, f_st.y); - + gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/13/1d-fbm.frag b/13/1d-fbm.frag index f7606dc..add80b6 100644 --- a/13/1d-fbm.frag +++ b/13/1d-fbm.frag @@ -10,7 +10,7 @@ uniform vec2 u_mouse; uniform float u_time; float plot(vec2 st, float pct){ - return smoothstep( pct-0.01, pct, st.y) - + return smoothstep( pct-0.01, pct, st.y) - smoothstep( pct, pct+0.01, st.y); } @@ -56,4 +56,4 @@ void main() { color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/13/2d-fbm.frag b/13/2d-fbm.frag index 84efb7f..d4fdfca 100644 --- a/13/2d-fbm.frag +++ b/13/2d-fbm.frag @@ -9,9 +9,9 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, - vec2(12.9898,78.233)))* + vec2(12.9898,78.233)))* 43758.5453123); } @@ -29,8 +29,8 @@ float noise (in vec2 st) { vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + + return mix(a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } @@ -58,4 +58,4 @@ void main() { color += fbm(st*3.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/13/README-de.md b/13/README-de.md index 8c43783..c79a9ad 100644 --- a/13/README-de.md +++ b/13/README-de.md @@ -32,7 +32,7 @@ y += sin(x*frequenz*3.1122+ t*4.269)*2.5; y *= amplitude*0.06; ">
-* Experimentiere mit Veränderungen der Amplitude und der Frequenz bei den hinzuaddierten Wellen. +* Experimentiere mit Veränderungen der Amplitude und der Frequenz bei den hinzuaddierten Wellen. * Gelingt es Dir, zwei Wellen zu erschaffen, die sich gegenseitig aufheben? Wie würde das aussehen? * Ist es möglich, Wellen auf eine bestimmte Art und Weise zu addieren, so dass sie sich gegenseitig verstärken? @@ -70,15 +70,15 @@ Der folgende Programmcode liefert ein Beispiel dafür, wie man eine fBm in zwei
-* Reduziere die Anzahl der Oktaven, indem Du den Wert der Konstanten in *Zeile 37* änderst. +* Reduziere die Anzahl der Oktaven, indem Du den Wert der Konstanten in *Zeile 37* änderst. * Ändere die Porosität der fBm in *Zeile 47*. * Untersuche die Auswirkungen, wenn Du die Verstärkung in *Zeile 48* veränderst. -Diese Technik wird in der Computergrafik häufig angewandt, um auf prozedurale Weise künstliche Landschaften zu erzeugen. Die Selbstähnlichkeit als Merkmal einer fBm ist perfekt für die Erzeugung von Bergen, Bergketten und ihren Tälern geeignet. Schließlich erzeugt die Erosion, die diese Strukturen in der Natur hervorbringt, ebenfalls eine Selbstähnlichkeit in mehreren unterschiedlichen Größenordnungen – im Großen wie im Kleinen. Falls Dich das Thema interessiert, empfehle ich Dir diesen [hervorragenden Beitrag von Inigo Quiles über hochentwickeltes Rauschen](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm). +Diese Technik wird in der Computergrafik häufig angewandt, um auf prozedurale Weise künstliche Landschaften zu erzeugen. Die Selbstähnlichkeit als Merkmal einer fBm ist perfekt für die Erzeugung von Bergen, Bergketten und ihren Tälern geeignet. Schließlich erzeugt die Erosion, die diese Strukturen in der Natur hervorbringt, ebenfalls eine Selbstähnlichkeit in mehreren unterschiedlichen Größenordnungen – im Großen wie im Kleinen. Falls Dich das Thema interessiert, empfehle ich Dir diesen [hervorragenden Beitrag von Inigo Quiles über hochentwickeltes Rauschen](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm). ![Blackout - Dan Holdsworth (2010)](holdsworth.jpg) -Mit mehr oder weniger derselben Technik lassen sich auch andere Effekte nachahmen, beispielsweise **Turbulenzen**. Dies geschieht mit einer fBm, wobei allerdings der Absolutwert einer vorzeichenbehafteten Rauschfunktion genutzt wird, um starke Täler zu erzeugen. +Mit mehr oder weniger derselben Technik lassen sich auch andere Effekte nachahmen, beispielsweise **Turbulenzen**. Dies geschieht mit einer fBm, wobei allerdings der Absolutwert einer vorzeichenbehafteten Rauschfunktion genutzt wird, um starke Täler zu erzeugen. ```glsl for (int i = 0; i < OKTAVEN; i++) { @@ -88,7 +88,7 @@ for (int i = 0; i < OKTAVEN; i++) { } ``` - + Ein weiteres Mitglied aus dieser Familie von Funktionen ist der **Bergrücken**, bei dem die tiefen Täler nach oben gekehrt werden, um scharfe Bergrücken bzw. Bergkämme zu erzeugen: @@ -98,15 +98,15 @@ Ein weiteres Mitglied aus dieser Familie von Funktionen ist der **Bergrücken**, n = n * n; // intensiviere die Ausbuchtung ``` - + Eine andere Variante dieses Verfahrens mit interessanten Ergebnissen besteht in der Multiplikation der einzelnen Rauschelemente anstelle der Addition. Man kann außerdem die Skalierung nicht gleichförmig mit jeder Detailebene (jedem Schleifendurchlauf) fortsetzen, sondern von den Ergebnissen vorheriger Schleifendurchläufe abhängig machen. Damit verlässt man allerdings die Welt klassischer Fraktale und dringt in das noch wenig erforschte Feld der „Multifraktale“ vor. Diese sind mathematisch nicht streng definiert, aber das macht sie für die Computergrafik nicht weniger nützlich. Tatsächlich werden Multifraktale bereits vielfältig in Software für die künstliche Erzeugung von Landschaftsstrukturen eingesetzt. -Falls Dich dieses Thema interessiert, kannst Du darüber z.B. in Kapitel 16 des Buches „Texturing and Modeling: a Procedural Approach“ (dritte Auflage) von Kenton Musgrave, mehr erfahren. Leider ist das Buch seit einigen Jahren vergriffen, aber man findet es noch in Bibliotheken und auf dem Gebrauchtmarkt. (Eine PDF-Version der ersten Auflage wird im Internet verkauft, aber die stammt von 1994 und enthält leider noch nicht die hier empfohlenen Kapitel.) +Falls Dich dieses Thema interessiert, kannst Du darüber z.B. in Kapitel 16 des Buches „Texturing and Modeling: a Procedural Approach“ (dritte Auflage) von Kenton Musgrave, mehr erfahren. Leider ist das Buch seit einigen Jahren vergriffen, aber man findet es noch in Bibliotheken und auf dem Gebrauchtmarkt. (Eine PDF-Version der ersten Auflage wird im Internet verkauft, aber die stammt von 1994 und enthält leider noch nicht die hier empfohlenen Kapitel.) ### Raumkrümmung -[Inigo Quiles hat einen weiteren faszinierenden Artikel](http://www.iquilezles.org/www/articles/warp/warp.htm) darüber verfasst, wie man ein fBm einsetzen kann, um einen Raum aus fBm zu verzerren. Abgefahren, nicht wahr? Das ist wie ein Traum über einen Traum, in dem es richtig rundgeht. +[Inigo Quiles hat einen weiteren faszinierenden Artikel](http://www.iquilezles.org/www/articles/warp/warp.htm) darüber verfasst, wie man ein fBm einsetzen kann, um einen Raum aus fBm zu verzerren. Abgefahren, nicht wahr? Das ist wie ein Traum über einen Traum, in dem es richtig rundgeht. ![ f(p) = fbm( p + fbm( p + fbm( p ) ) ) - Inigo Quiles (2002)](quiles.jpg) diff --git a/13/README-fr.md b/13/README-fr.md index 0224bec..4a3e393 100644 --- a/13/README-fr.md +++ b/13/README-fr.md @@ -114,7 +114,7 @@ for (int i = 0; i < OCTAVES; i++) { } ``` - + Une seconde variante dite *ridge noise* (bruit de *crête* ou d'*arête*) consiste à inverser les vallées: @@ -124,7 +124,7 @@ Une seconde variante dite *ridge noise* (bruit de *crête* ou d'*arête*) consis n = n * n; // sharpen creases ``` - + Une autre variante consiste à multiplier les valeurs de bruit au lieu de les additionner. Il est intéressant de modifier l'échelle d'une itération de bruit en fonction du bruit de l'itération precédente. diff --git a/13/README.md b/13/README.md index f639111..aad318c 100644 --- a/13/README.md +++ b/13/README.md @@ -32,7 +32,7 @@ y *= amplitude*0.06; * Experiment by changing the frequency and amplitude for the additional waves. * Is it possible to make two waves cancel each other out? What will that look like? -* Is it possible to add waves in such a way that they will amplify each other? +* Is it possible to add waves in such a way that they will amplify each other? In music, each note is associated with a specific frequency. The frequencies for these notes follow a pattern which we call a scale, where a doubling or halving of the frequency corresponds to a jump of one octave. @@ -70,7 +70,7 @@ The following code is an example of how fBm could be implemented in two dimensio * Modify the lacunarity of the fBm on line 47 * Explore by changing the gain on line 48 -This technique is commonly used to construct procedural landscapes. The self-similarity of the fBm is perfect for mountains, because the erosion processes that create mountains work in a manner that yields this kind of self-similarity across a large range of scales. If you are interested in this, use you should definitly read [this great article by Inigo Quiles about advance noise](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm). +This technique is commonly used to construct procedural landscapes. The self-similarity of the fBm is perfect for mountains, because the erosion processes that create mountains work in a manner that yields this kind of self-similarity across a large range of scales. If you are interested in this, use you should definitly read [this great article by Inigo Quiles about advance noise](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm). ![Blackout - Dan Holdsworth (2010)](holdsworth.jpg) @@ -84,7 +84,7 @@ for (int i = 0; i < OCTAVES; i++) { } ``` - + Another member of this family of algorithms is the **ridge**, where the sharp valleys are turned upside down to create sharp ridges instead: @@ -94,13 +94,13 @@ Another member of this family of algorithms is the **ridge**, where the sharp va n = n * n; // sharpen creases ``` - + Another variant which can create useful variations is to multiply the noise components together instead of adding them. It's also interesting to scale subsequent noise functions with something that depends on the previous terms in the loop. When we do things like that, we are moving away from the strict definition of a fractal and into the relatively unknown field of "multifractals". Multifractals are not as strictly defined mathematically, but that doesn't make them less useful for graphics. In fact, multifractal simulations are very common in modern commercial software for terrain generation. For further reading, you could read chapter 16 of the book "Texturing and Modeling: a Procedural Approach" (3rd edition), by Kenton Musgrave. Sadly, that book is out of print since a few years back, but you can still find it in libraries and on the second hand market. (There's a PDF version of the 1st edition available for purchase online, but don't buy that - it's a waste of money. It's from 1994, and it doesn't contain any of the terrain modeling stuff from the 3rd edition.) ### Domain Warping -[Inigo Quiles wrote this other fascinating article](http://www.iquilezles.org/www/articles/warp/warp.htm) about how it's possible to use fBm to warp a space of a fBm. Mind blowing, Right? It's like the dream inside the dream of Inception. +[Inigo Quiles wrote this other fascinating article](http://www.iquilezles.org/www/articles/warp/warp.htm) about how it's possible to use fBm to warp a space of a fBm. Mind blowing, Right? It's like the dream inside the dream of Inception. ![ f(p) = fbm( p + fbm( p + fbm( p ) ) ) - Inigo Quiles (2002)](quiles.jpg) diff --git a/13/clouds.frag b/13/clouds.frag index 68a6701..ee1cdde 100644 --- a/13/clouds.frag +++ b/13/clouds.frag @@ -9,9 +9,9 @@ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; -float random (in vec2 _st) { +float random (in vec2 _st) { return fract(sin(dot(_st.xy, - vec2(12.9898,78.233)))* + vec2(12.9898,78.233)))* 43758.5453123); } @@ -29,8 +29,8 @@ float noise (in vec2 _st) { vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + + return mix(a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } @@ -41,7 +41,7 @@ float fbm ( in vec2 _st) { float a = 0.5; vec2 shift = vec2(100.0); // Rotate to reduce axial bias - mat2 rot = mat2(cos(0.5), sin(0.5), + mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50)); for (int i = 0; i < NUM_OCTAVES; ++i) { v += a * noise(_st); @@ -79,4 +79,4 @@ void main() { clamp(length(r.x),0.0,1.0)); gl_FragColor = vec4((f*f*f+.6*f*f+.5*f)*color,1.); -} \ No newline at end of file +} diff --git a/13/index.php b/13/index.php index 31d9d3e..79d6056 100644 --- a/13/index.php +++ b/13/index.php @@ -1,4 +1,4 @@ - Home '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/13/noise.frag b/13/noise.frag index f73dafe..1538b4d 100644 --- a/13/noise.frag +++ b/13/noise.frag @@ -15,9 +15,9 @@ float random (in float x) { return fract(sin(x)*1e4); } -float random (in vec2 _st) { +float random (in vec2 _st) { // return fract(sin(dot(_st.xy ,vec2(12.9898,78.233))) * 43758.5453123); - return fract( 1e4 * sin(17.0 * _st.x + _st.y * 0.1) * (0.1 + abs(sin(_st.y * 13.0 + _st.x)))); + return fract( 1e4 * sin(17.0 * _st.x + _st.y * 0.1) * (0.1 + abs(sin(_st.y * 13.0 + _st.x)))); } float noise (in float x) { @@ -53,8 +53,8 @@ float noise (in vec3 _p) { vec3 i = floor(_p); vec3 f = fract(_p); - - // For performance, compute the base input to a 1D random from the integer part of the argument and the + + // For performance, compute the base input to a 1D random from the integer part of the argument and the // incremental change to the 1D based on the 3D -> 1D wrapping float n = dot(i, step); @@ -114,4 +114,4 @@ void main() { color = vec3( fbm(vec3(st*10.,u_time*0.1)) ); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/13/ridge.frag b/13/ridge.frag index 4734277..1ef7980 100644 --- a/13/ridge.frag +++ b/13/ridge.frag @@ -19,21 +19,21 @@ vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } // Author : Ian McEwan, Ashima Arts // Maintainer : ijm // Lastmod : 20110822 (ijm) -// License : +// License : // Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// float snoise(vec2 v) { // Precompute values for skewed triangular grid const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 - 0.366025403784439, + 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) - -0.577350269189626, + -0.577350269189626, // -1.0 + 2.0 * C.x - 0.024390243902439); + 0.024390243902439); // 1.0 / 41.0 // First corner (x0) @@ -54,17 +54,17 @@ float snoise(vec2 v) { + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3( - dot(x0,x0), - dot(x1,x1), + dot(x0,x0), + dot(x1,x1), dot(x2,x2) ), 0.0); m = m*m ; m = m*m ; - // Gradients: + // Gradients: // 41 pts uniformly over a line, mapped onto a diamond - // The ring size 17*17 = 289 is close to a multiple + // The ring size 17*17 = 289 is close to a multiple // of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; @@ -98,7 +98,7 @@ float ridgedMF(vec2 p) { float lacunarity = 2.0; float gain = 0.5; float offset = 0.9; - + float sum = 0.0; float freq = 1.0, amp = 0.5; float prev = 1.0; @@ -121,4 +121,4 @@ void main() { color += ridgedMF(st*3.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/13/turbulence.frag b/13/turbulence.frag index 2f52167..7478a56 100644 --- a/13/turbulence.frag +++ b/13/turbulence.frag @@ -19,21 +19,21 @@ vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } // Author : Ian McEwan, Ashima Arts // Maintainer : ijm // Lastmod : 20110822 (ijm) -// License : +// License : // Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise -// +// float snoise(vec2 v) { // Precompute values for skewed triangular grid const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 - 0.366025403784439, + 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) - -0.577350269189626, + -0.577350269189626, // -1.0 + 2.0 * C.x - 0.024390243902439); + 0.024390243902439); // 1.0 / 41.0 // First corner (x0) @@ -54,17 +54,17 @@ float snoise(vec2 v) { + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3( - dot(x0,x0), - dot(x1,x1), + dot(x0,x0), + dot(x1,x1), dot(x2,x2) ), 0.0); m = m*m ; m = m*m ; - // Gradients: + // Gradients: // 41 pts uniformly over a line, mapped onto a diamond - // The ring size 17*17 = 289 is close to a multiple + // The ring size 17*17 = 289 is close to a multiple // of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; @@ -107,4 +107,4 @@ void main() { color += turbulence(st*3.0); gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +} diff --git a/14/README.md b/14/README.md index 591d31e..be1f73f 100644 --- a/14/README.md +++ b/14/README.md @@ -24,4 +24,4 @@ https://www.shadertoy.com/view/XdBSWw https://www.shadertoy.com/view/llfGD2 -https://www.shadertoy.com/view/Mlf3RX \ No newline at end of file +https://www.shadertoy.com/view/Mlf3RX diff --git a/14/fractal-tile.frag b/14/fractal-tile.frag index 2d183b2..ec16081 100644 --- a/14/fractal-tile.frag +++ b/14/fractal-tile.frag @@ -54,7 +54,7 @@ void main() { vec3 color = vec3(0.0); st = tileFractal(st,3,2); - + float pct = 0.; pct = circle(st,.999); // pct = box(st,vec2(.95)); @@ -64,4 +64,4 @@ void main() { color.rgb += vec3(1.)*pct; gl_FragColor = vec4(color,1.); -} \ No newline at end of file +} diff --git a/14/index.php b/14/index.php index 09345b5..d17c39c 100644 --- a/14/index.php +++ b/14/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/15/NOTES.md b/15/NOTES.md index 9c3fe4e..f96b683 100644 --- a/15/NOTES.md +++ b/15/NOTES.md @@ -2,4 +2,3 @@ No tile images https://www.shadertoy.com/view/4tsGzf https://www.shadertoy.com/view/lt2GDd - diff --git a/15/README.md b/15/README.md index cd21648..3f0b0be 100644 --- a/15/README.md +++ b/15/README.md @@ -6,7 +6,7 @@ Graphic cards (GPUs) have special memory types for images. Usually on CPUs images are stores as arrays of bites but on GPUs store images as ```sampler2D``` which is more like a table (or matrix) of floating point vectors. More interestingly is that the values of this *table* of vectors are continously. That means that value between pixels are interpolated in a low level. -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. +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) usin the [```texture2D()```](index.html#texture2D.md) function which will return a color formated on a [```vec4```](index.html#vec4.md) variable. @@ -18,7 +18,7 @@ Check the following code where we load Hokusai's Wave (1830) as ```uniform sampl
-If you pay attention you will note that the coordinates for the texture are normalized! What a surprise right? Textures coordenates are consisten with the rest of the things we had saw and their coordenates are between 0.0 and 1.0 whitch match perfectly with the normalized space coordinates we have been using. +If you pay attention you will note that the coordinates for the texture are normalized! What a surprise right? Textures coordenates are consisten with the rest of the things we had saw and their coordenates are between 0.0 and 1.0 whitch match perfectly with the normalized space coordinates we have been using. Now that you have seen how we load correctly a texture is time to experiment to discover what we can do with it, by trying: @@ -26,9 +26,9 @@ Now that you have seen how we load correctly a texture is time to experiment to * Rotating the previus texture 90 degrees. * Hooking the mouse position to the coordenates to move it. -Why you should be excited about textures? Well first of all forget about the sad 255 values for channel, once your image is trasformed into a ```uniform sampler2D``` you have all the values between 0.0 and 1.0 (depending on what you set the ```precision``` to ). That's why shaders can make really beatiful post-processing effects. +Why you should be excited about textures? Well first of all forget about the sad 255 values for channel, once your image is trasformed into a ```uniform sampler2D``` you have all the values between 0.0 and 1.0 (depending on what you set the ```precision``` to ). That's why shaders can make really beatiful post-processing effects. -Second, the [```vec2()```](index.html#vec2.md) means you can get values even between pixels. As we said before the textures are a continum. This means that if you set up your texture correctly you can ask for values all arround the surface of your image and the values will smoothly vary from pixel to pixel with no jumps! +Second, the [```vec2()```](index.html#vec2.md) means you can get values even between pixels. As we said before the textures are a continum. This means that if you set up your texture correctly you can ask for values all arround the surface of your image and the values will smoothly vary from pixel to pixel with no jumps! Finnally, you can setup your image to repeat in the edges, so if you give values over or lower of the normalized 0.0 and 1.0, the values will wrap around starting over. @@ -54,7 +54,7 @@ Uncomment line 21 of the following code to see this in action. ![](03.jpg) -You may be thinking that this is unnesesary complicated... and you are probably right. Also this way of working with images leave a enought room to different hacks and creative tricks. Try to imagine that you are an upholster and by streaching and folding a fabric over a structure you can create better and new patterns and techniques. +You may be thinking that this is unnesesary complicated... and you are probably right. Also this way of working with images leave a enought room to different hacks and creative tricks. Try to imagine that you are an upholster and by streaching and folding a fabric over a structure you can create better and new patterns and techniques. ![Eadweard's Muybridge study of motion](muybridge.jpg) @@ -75,4 +75,4 @@ Now is your turn: * What other optical toys can you re-create using textures? -In the next chapters we will learn how to do some image processing using shaders. You will note that finnaly the complexity of shader makes sense, because was in a big sense designed to do this type of process. We will start doing some image operations! \ No newline at end of file +In the next chapters we will learn how to do some image processing using shaders. You will note that finnaly the complexity of shader makes sense, because was in a big sense designed to do this type of process. We will start doing some image operations! diff --git a/15/index.php b/15/index.php index 5a557ab..3ee01f6 100644 --- a/15/index.php +++ b/15/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/15/texture-kaleidoscope.frag b/15/texture-kaleidoscope.frag index 5186445..50680a7 100644 --- a/15/texture-kaleidoscope.frag +++ b/15/texture-kaleidoscope.frag @@ -41,4 +41,4 @@ void main () { color = texture2D(u_tex0,st); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/15/texture-noise.frag b/15/texture-noise.frag index da14a38..81870bd 100644 --- a/15/texture-noise.frag +++ b/15/texture-noise.frag @@ -16,9 +16,9 @@ uniform float u_time; // Based on Morgan // https://www.shadertoy.com/view/4dS3Wd -float random (in vec2 st) { +float random (in vec2 st) { return fract(sin(dot(st.xy, - vec2(12.9898,78.233)))* + vec2(12.9898,78.233)))* 43758.5453123); } @@ -34,8 +34,8 @@ float noise (in vec2 st) { vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + + return mix(a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } @@ -44,7 +44,7 @@ void main () { float scale = 2.0; float offset = 0.5; - + float angle = noise( st + u_time * 0.1 )*PI; float radius = offset; @@ -54,4 +54,4 @@ void main () { vec4 color = texture2D(u_tex0,st); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/15/texture-resolution.frag b/15/texture-resolution.frag index 3a59b95..9a151b5 100644 --- a/15/texture-resolution.frag +++ b/15/texture-resolution.frag @@ -23,4 +23,4 @@ void main () { color = texture2D(u_tex0,st); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/15/texture-sprite.frag b/15/texture-sprite.frag index 24e7fed..8d884cb 100644 --- a/15/texture-sprite.frag +++ b/15/texture-sprite.frag @@ -22,20 +22,20 @@ void main () { // Resolution of one frame vec2 fRes = u_tex0Resolution/vec2(float(col),float(row)); - // Normalize value of the frame resolution + // Normalize value of the frame resolution vec2 nRes = u_tex0Resolution/fRes; // Scale the coordenates to a single frame st = st/nRes; // Calculate the offset in cols and rows - float timeX = u_time*15.; + float timeX = u_time*15.; float timeY = floor(timeX/float(col)); - vec2 offset = vec2( floor(timeX)/nRes.x, + vec2 offset = vec2( floor(timeX)/nRes.x, 1.0-(floor(timeY)/nRes.y) ); st = fract(st+offset); color = texture2D(u_tex0,st); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/15/texture-stereo.frag b/15/texture-stereo.frag index ddc0820..9bf9cda 100644 --- a/15/texture-stereo.frag +++ b/15/texture-stereo.frag @@ -28,4 +28,4 @@ void main () { color = mix(A, B, abs(sin(t))); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/15/texture.frag b/15/texture.frag index 29c4c3c..81a8dd9 100644 --- a/15/texture.frag +++ b/15/texture.frag @@ -19,4 +19,4 @@ void main () { color = texture2D(u_tex0,st); gl_FragColor = color; -} \ No newline at end of file +} diff --git a/16/README.md b/16/README.md index d225217..622ed23 100644 --- a/16/README.md +++ b/16/README.md @@ -15,4 +15,4 @@ ![](03.jpg) -
\ No newline at end of file +
diff --git a/16/add.frag b/16/add.frag index 261f7fc..5fbd9f9 100644 --- a/16/add.frag +++ b/16/add.frag @@ -14,7 +14,7 @@ uniform vec2 u_resolution; void main (void) { vec2 st = gl_FragCoord.xy/u_resolution.xy; - + vec3 colorA = texture2D(u_tex0,st).rgb; vec3 colorB = texture2D(u_tex1,st).rgb; diff --git a/16/diff.frag b/16/diff.frag index c91c9b6..5d3d700 100644 --- a/16/diff.frag +++ b/16/diff.frag @@ -19,6 +19,6 @@ void main (void) { vec3 colorB = texture2D(u_tex1,st).rgb; vec3 color = abs(colorA-colorB); - + gl_FragColor = vec4(color,1.0); } diff --git a/16/div.frag b/16/div.frag index 79e9e00..52fa7d7 100644 --- a/16/div.frag +++ b/16/div.frag @@ -14,7 +14,7 @@ uniform vec2 u_resolution; void main (void) { vec2 st = gl_FragCoord.xy/u_resolution.xy; - + vec3 colorA = texture2D(u_tex0,st).rgb; vec3 colorB = texture2D(u_tex1,st).rgb; diff --git a/16/index.php b/16/index.php index 5a557ab..3ee01f6 100644 --- a/16/index.php +++ b/16/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/16/inv.frag b/16/inv.frag index 1fc3200..fcc9c8e 100644 --- a/16/inv.frag +++ b/16/inv.frag @@ -14,7 +14,7 @@ uniform vec2 u_resolution; void main (void) { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = texture2D(u_tex0,st).rgb; - + // color = 1.0-color; gl_FragColor = vec4(color,1.0); diff --git a/16/sub.frag b/16/sub.frag index 9f2f4cf..dce07b4 100644 --- a/16/sub.frag +++ b/16/sub.frag @@ -19,6 +19,6 @@ void main (void) { vec3 colorB = texture2D(u_tex1,st).rgb; vec3 color = colorA*colorB; - + gl_FragColor = vec4(color,1.0); } diff --git a/17/index.php b/17/index.php index 5a557ab..3ee01f6 100644 --- a/17/index.php +++ b/17/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/18/grain.frag b/18/grain.frag index 522b407..1098c04 100644 --- a/18/grain.frag +++ b/18/grain.frag @@ -78,8 +78,8 @@ float luma(vec4 color) { // https://github.com/mattdesl/glsl-blend-soft-light/blob/master/index.glsl vec3 blendSoftLight(vec3 base, vec3 blend) { return mix( - sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend), - 2.0 * base * blend + base * base * (1.0 - 2.0 * blend), + sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend), + 2.0 * base * blend + base * base * (1.0 - 2.0 * blend), step(base, vec3(0.5)) ); } @@ -88,7 +88,7 @@ void main (void) { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = texture2D(u_tex0,st).rgb; vec3 grain = vec3( grain(st,u_resolution/7.) ); - + color = blendSoftLight(color,grain); float luminance = luma(color); diff --git a/18/hatch.frag b/18/hatch.frag index 4f9c0a5..b7165fb 100644 --- a/18/hatch.frag +++ b/18/hatch.frag @@ -1,7 +1,7 @@ #ifdef GL_ES precision highp float; #endif - + uniform sampler2D u_tex0; uniform vec2 u_tex0Resolution; @@ -21,4 +21,4 @@ void main(){ vec3 color = vec3(1.0); color -= hatch(u_tex0,st,b).a; gl_FragColor = vec4(color,1.); -} \ No newline at end of file +} diff --git a/18/index.php b/18/index.php index 5a557ab..3ee01f6 100644 --- a/18/index.php +++ b/18/index.php @@ -1,4 +1,4 @@ -Next > > '; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/18/lut-plain.frag b/18/lut-plain.frag index 73be2ef..362325a 100644 --- a/18/lut-plain.frag +++ b/18/lut-plain.frag @@ -1,7 +1,7 @@ #ifdef GL_ES precision highp float; #endif - + uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; @@ -11,7 +11,7 @@ const float size = 8.0; void main(){ vec2 st = gl_FragCoord.st/u_resolution.xy; vec3 color = vec3(.0); - + float red = fract(st.x*size); float green = fract((1.-st.y)*size); float blue = floor((1.-st.y)*size)/size; @@ -19,4 +19,4 @@ void main(){ color = vec3(red,green,blue); gl_FragColor = vec4( color , 1.0); -} \ No newline at end of file +} diff --git a/18/lut.frag b/18/lut.frag index 923d209..b3a135f 100644 --- a/18/lut.frag +++ b/18/lut.frag @@ -1,7 +1,7 @@ #ifdef GL_ES precision highp float; #endif - + uniform sampler2D u_tex0; uniform sampler2D u_tex1; @@ -15,7 +15,7 @@ uniform float u_time; #define LUT_NO_CLAMP #define LUT_FLIP_Y -vec4 lookup(in vec4 textureColor, in sampler2D lookupTable) { +vec4 lookup(in vec4 textureColor, in sampler2D lookupTable) { #ifndef LUT_NO_CLAMP textureColor = clamp(textureColor, 0.0, 1.0); #endif @@ -57,6 +57,6 @@ void main(){ vec2 st = gl_FragCoord.st/u_resolution.xy; vec4 srcColor = texture2D(u_tex0, st); vec3 dstcolor = lookup(srcColor,u_tex1).rgb; - + gl_FragColor = vec4( dstcolor , 1.0); -} \ No newline at end of file +} diff --git a/makefile b/Makefile similarity index 92% rename from makefile rename to Makefile index e04bae6..36354b6 100644 --- a/makefile +++ b/Makefile @@ -1,6 +1,6 @@ default: clean all -clean: +clean: rm -rf */tmp.md rm -rf */tmp*.png rm -rf book.* diff --git a/README-de.md b/README-de.md index a5bef8c..a05b965 100644 --- a/README-de.md +++ b/README-de.md @@ -88,7 +88,7 @@ Dank an [Tong Li](https://www.facebook.com/tong.lee.9484) und [Yi Zhang](https:/ Dank an [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) für die [koreanische Übersetzung des Textes (한국어)](?lan=kr) -Dank an [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) für die +Dank an [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) für die [spanische Übersetzung des Textes (español)](?lan=es) Dank an [Nicolas Barradeau](https://twitter.com/nicoptere) und [Karim Naaji](http://karim.naaji.fr/) für die [französische Übersetzung des Textes (français)](?lan=fr) @@ -104,4 +104,3 @@ Und natürlich Danke an alle, die an dieses Projekt geglaubt, dafür gespendet o Melde Dich für den Newsletter an oder [folge uns auf Twitter](https://twitter.com/bookofshaders)

- diff --git a/README-it.md b/README-it.md index c55965f..b9007a1 100644 --- a/README-it.md +++ b/README-it.md @@ -70,7 +70,7 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentina) è un artista e sviluppatore con sede a New York. Esplora lo spazio interstiziale fra organico e sintetico, analogico e digitale, individuale e collettivo. Nel suo lavoro usa il codice come un linguaggio espressivo con l'intenzione di creare un migliore vivere insieme. -Patricio studiò e praticò la psicoterapia e l'arteterapia. Ha conseguito un MFA in Design e Tecnologia alla Parsons The New School dove ora insegna. Attualmente lavora come Ingegnere Grafico alla Mapzen realizzando strumenti cartografici openSource. +Patricio studiò e praticò la psicoterapia e l'arteterapia. Ha conseguito un MFA in Design e Tecnologia alla Parsons The New School dove ora insegna. Attualmente lavora come Ingegnere Grafico alla Mapzen realizzando strumenti cartografici openSource.
WebSite - Twitter - GitHub - Vimeo - Flickr
diff --git a/README-kr.md b/README-kr.md index 55806d7..a24cca8 100644 --- a/README-kr.md +++ b/README-kr.md @@ -3,7 +3,7 @@ # The Book of Shaders *by [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)* -이것은 황량하게 넓고 복잡한 Fragment Shader의 세계를 한단계씩 살펴보는 지침서입니다. +이것은 황량하게 넓고 복잡한 Fragment Shader의 세계를 한단계씩 살펴보는 지침서입니다. ## 번역에 대하여 diff --git a/appendix/00/README-de.md b/appendix/00/README-de.md index 31832b8..2e75a14 100644 --- a/appendix/00/README-de.md +++ b/appendix/00/README-de.md @@ -9,7 +9,7 @@ Unter **MacOSX** benötigst Du dafür [homebrew](http://brew.sh/). Sobald das Pa ```bash brew update brew upgrade -brew install git +brew install git ``` Auf einem **RaspberryPi** gibst Du folgendes ein: diff --git a/appendix/01/README-de.md b/appendix/01/README-de.md index 93824be..b669a5c 100644 --- a/appendix/01/README-de.md +++ b/appendix/01/README-de.md @@ -1,8 +1,8 @@ ## Wie kann ich die Beispielprogramme auf einem RaspberryPi ausführen? -Vor wenigen Jahren konnte man noch nicht davon ausgehen, dass jedermann über einen Computer mit einer GPU verfügt. Heutzutage gilt das nicht mehr. Doch im Bereich von Schulen, Universitäten und anderen Weiterbildungseichrichtungen ist dies immer noch eine hohe Anforderung. +Vor wenigen Jahren konnte man noch nicht davon ausgehen, dass jedermann über einen Computer mit einer GPU verfügt. Heutzutage gilt das nicht mehr. Doch im Bereich von Schulen, Universitäten und anderen Weiterbildungseichrichtungen ist dies immer noch eine hohe Anforderung. -Durch das [Raspberry Projekt](http://www.raspberrypi.org/) hat mittlerweile eine neue Generation kleiner und billiger Computer (das Stück ab ca. 40 Euro) ihren Weg in viele Klassenzimmer gefunden. Vor allem verfügt der [RaspberryPi](http://www.raspberrypi.org/) über einen ansehnlichen Grafikchip mit GPU, der direkt aus der Kommandozeile angesprochen werden kann. +Durch das [Raspberry Projekt](http://www.raspberrypi.org/) hat mittlerweile eine neue Generation kleiner und billiger Computer (das Stück ab ca. 40 Euro) ihren Weg in viele Klassenzimmer gefunden. Vor allem verfügt der [RaspberryPi](http://www.raspberrypi.org/) über einen ansehnlichen Grafikchip mit GPU, der direkt aus der Kommandozeile angesprochen werden kann. Ich habe ein flexibles Werkzeug für die Programmierung von GLSL-Shadern entwickelt, den [**glslViewer**](https://github.com/patriciogonzalezvivo/glslViewer). Damit können alle Beispiele aus diesem Buch ausgeführt werden. Sobald man Veränderungen am aktuellen Shader-Programmcode abspeichert, kompiliert das Programm den Shader erneut und bringt ihn zur Ausführung. Auf dem Bildschirm erscheint daraufhin die aktualisierte Anzeige des Shaders. diff --git a/appendix/01/README-it.md b/appendix/01/README-it.md index 65eca12..ced8d55 100644 --- a/appendix/01/README-it.md +++ b/appendix/01/README-it.md @@ -6,7 +6,7 @@ Grazie al [progetto Raspberry Pi](http://www.raspberrypi.org/) una nuova generaz Facendo una copia locale del repository di questo libro (vedi paragrafo precedente) e con [```glslViewer``` installato](https://github.com/patriciogonzalezvivo/glslViewer), gli utenti possono eseguire gli esempi con ```glslviewer```. Inoltre usando il flag ```-l``` si può visualiizare l'esempio in un angolo dello schermo mentre lo si modifica con un qualsiasi editor di testo (come ```nano```, ```pico```, ```vi```, ```vim``` or ```emacs```). Questo funziona anche quando l'utente è collegato tramite ssh/sftp. -Per installare e configurare tutto ciò sul Raspberry Pi, dopo l'installazione del sistema operativo e il login, digitate i seguenti comandi: +Per installare e configurare tutto ciò sul Raspberry Pi, dopo l'installazione del sistema operativo e il login, digitate i seguenti comandi: ```bash sudo apt-get update @@ -15,4 +15,4 @@ sudo apt-get install git-core glslviewer cd ~ git clone https://github.com/patriciogonzalezvivo/thebookofshaders.git cd thebookofshaders -``` \ No newline at end of file +``` diff --git a/appendix/01/README.md b/appendix/01/README.md index 3a7bf20..04d41c2 100644 --- a/appendix/01/README.md +++ b/appendix/01/README.md @@ -1,6 +1,6 @@ ## How to run the examples on a Raspberry Pi? -A few years ago, assuming that everybody has a computer with a graphical processing unit was a long shot. Now, most computers have a GPU, but it's still a high bar for a requirement in a workshop or class, for example. +A few years ago, assuming that everybody has a computer with a graphical processing unit was a long shot. Now, most computers have a GPU, but it's still a high bar for a requirement in a workshop or class, for example. Thanks to the [Raspberry Pi Foundation](http://www.raspberrypi.org/) a new type of small and cheap generation of computers (around $35 each) has found its way into classrooms. More importantly for the purposes of this book, the [Raspberry Pi](http://www.raspberrypi.org/) comes with a decent Broadcom GPU that can be accessed directly from the console. I made a [flexible GLSL live coding tool call **glslViewer**](https://github.com/patriciogonzalezvivo/glslViewer) that runs all the examples in this book. This program also has the ability to update automatically when the user saves a change to their code. What does this mean? You can edit the shader and every time you save it, the shader will be re-compile and render for you. diff --git a/appendix/02/README-de.md b/appendix/02/README-de.md index d83043b..4fc4332 100644 --- a/appendix/02/README-de.md +++ b/appendix/02/README-de.md @@ -1,7 +1,7 @@ ## Wie kann ich dieses Buch ausdrucken? Nehmen wir einmal an, Du willst gar nicht mit den Beispielprogrammen in diesem Buch interagieren, sondern den Text wie ein gutes altes Buch im Urlaub oder auf dem täglichen Weg zur Arbeit lesen. In diesem Fall kannst Du Dir den Text einfach ausdrucken. - + #### Installation des glslViewer @@ -14,7 +14,7 @@ brew update brew upgrade brew tap homebrew/versions brew install glfw3 -cd ~ +cd ~ git clone http://github.com/patriciogonzalezvivo/glslViewer.git cd glslViewer make @@ -36,7 +36,7 @@ Für den Ausdruck müssen die einzelnen Kapitel zunächst aus dem vorliegenden T Unter **MacOSX**: Lade und installiere zunächst [basictex inkl. der MacTeX-Erweiterungen](http://www.tug.org/mactex/morepackages.html) und installiere anschließend [Pandoc](http://johnmacfarlane.net/pandoc/), indem Du folgende Kommandos eingibst: - + ```bash brew install pandoc ``` @@ -61,4 +61,3 @@ make ``` Wenn alles funktioniert hat, findest Du anschließend die Datei ```book.pdf``` vor, die Du auf Deinem bevorzugten Gerät lesen oder ausdrucken kannst. - diff --git a/appendix/02/README-fr.md b/appendix/02/README-fr.md index c726397..30b0a3f 100644 --- a/appendix/02/README-fr.md +++ b/appendix/02/README-fr.md @@ -13,7 +13,7 @@ brew update brew upgrade brew tap homebrew/versions brew install glfw3 -cd ~ +cd ~ git clone http://github.com/patriciogonzalezvivo/glslViewer.git cd glslViewer make @@ -35,7 +35,7 @@ Pour analyser les chapitres Markdown dans Latex, puis dans un fichier PDF, nous Sous **MacOSX**: Téléchargez et installez [basictex & MacTeX-Additions](http://www.tug.org/mactex/morepackages.html), puis installez [Pandoc](http://johnmacfarlane.net/pandoc/) et Python avec : - + ```bash brew install pandoc python2.7 ``` diff --git a/appendix/02/README-it.md b/appendix/02/README-it.md index 5772b93..c5f0cc9 100644 --- a/appendix/02/README-it.md +++ b/appendix/02/README-it.md @@ -1,7 +1,7 @@ ## Come posso stampare questo libro? Diciamo che non si vuole navigare o interagire con gli esempi e si desidera solo un buon vecchio libro di testo che si può leggere sulla spiaggia o sul vostro tragitto verso la città. In questo caso è possibile stampare questo libro. - + #### Installare glslViewer Per la stampa di questo libro è necessario in primo luogo trasformarlo. Per questo è necessario [```glslViewer```](https://github.com/patriciogonzalezvivo/glslViewer) uno strumento console per gli shader che compilerà e trasformare gli esempi in immagini. @@ -13,7 +13,7 @@ brew update brew upgrade brew tap homebrew/versions brew install glfw3 -cd ~ +cd ~ git clone http://github.com/patriciogonzalezvivo/glslViewer.git cd glslViewer make @@ -35,7 +35,7 @@ Per trasformare i capitoli Markdown in Latex e poi in un file PDF useremo Xetex Su **MacOSX**: Scarica e Installa [basictex & MacTeX-Additions](http://www.tug.org/mactex/morepackages.html) e poi installa [Pandoc](http://johnmacfarlane.net/pandoc/) facendo: - + ```bash brew install pandoc ``` diff --git a/appendix/02/README.md b/appendix/02/README.md index 175bd05..c030b16 100644 --- a/appendix/02/README.md +++ b/appendix/02/README.md @@ -1,7 +1,7 @@ ## How to print this book? Let’s say you don’t want to navigate or interact with the examples and you just want a good old fashion text book which you can read on the beach or on your commute to the city. In that case you can print this book. - + #### Installing glslViewer @@ -14,7 +14,7 @@ brew update brew upgrade brew tap homebrew/versions brew install glfw3 -cd ~ +cd ~ git clone http://github.com/patriciogonzalezvivo/glslViewer.git cd glslViewer make @@ -36,7 +36,7 @@ For parsing the Markdown chapters into Latex and then into a PDF file we will us In **MacOSX**: Download and Install [basictex & MacTeX-Additions](http://www.tug.org/mactex/morepackages.html) and then install [Pandoc](http://johnmacfarlane.net/pandoc/) and Python by: - + ```bash brew install pandoc python2.7 ``` @@ -60,4 +60,4 @@ cd thebookofshaders make ``` -If everything goes well, you will see a `book.pdf` file which you can read on your favorite device or print. +If everything goes well, you will see a `book.pdf` file which you can read on your favorite device or print. diff --git a/appendix/03/README-de.md b/appendix/03/README-de.md index 37d5954..db77048 100644 --- a/appendix/03/README-de.md +++ b/appendix/03/README-de.md @@ -45,7 +45,7 @@ Starte auf Deinem lokalen Rechner einen PHP-Server innerhalb des Verzeichnisses, php -S localhost:8000 ``` -Rufe dann in Deinem Internet-Browser die URL ```localhost:8000``` auf. Klicke Dich bis zu dem Kapitel durch, an dem Du gerade arbeitest. Füge der angezeigten URL in der Adresszeile des Browsers den Zusatz ```?lan=``` hinzu, gefolgt von dem Sprachenkürzel, das Du bei der Benennung der jeweiligen Datei verwendet hast. +Rufe dann in Deinem Internet-Browser die URL ```localhost:8000``` auf. Klicke Dich bis zu dem Kapitel durch, an dem Du gerade arbeitest. Füge der angezeigten URL in der Adresszeile des Browsers den Zusatz ```?lan=``` hinzu, gefolgt von dem Sprachenkürzel, das Du bei der Benennung der jeweiligen Datei verwendet hast. Um ein Beispiel zu nennen: Wenn Du gerade das Kapitel ```03``` ins Französische übersetzt und dabei mit der Datei ```03/README-fr.md``` arbeitest, kannst Du diese Datei anzeigen, indem Du folgende URL eingibst: ```http://localhost:8000/03/?lan=fr``` @@ -59,7 +59,5 @@ Irren ist menschlich! Wenn Dir ein Fehler auffällt, bereinige die Stelle und se ### Teile Deine Shader mit Anderen -Du wirst im Quelltext des Buches bei den Beispielen viele Verweise auf den [Online-Editor](http://editor.thebookofshaders.com/) sehen. +Du wirst im Quelltext des Buches bei den Beispielen viele Verweise auf den [Online-Editor](http://editor.thebookofshaders.com/) sehen. Sobald Du einen Shader entwickelt hast, auf den Du stolz bist, klicke auf die „Export“-Schaltfläche (bzw. das ```⇪```-Symbol) und kopiere anschließend die im Editor angezeigte „URL to code...“. Sende diese URL an [@bookofshaders](https://twitter.com/bookofshaders) oder an [@kyndinfo](https://twitter.com/kyndinfo). Wir freuen uns auf tolle Shader und werden diese gerne unserer [Galerie mit Beispielen](https://thebookofshaders.com/examples/) hinzufügen. - - diff --git a/appendix/03/README-it.md b/appendix/03/README-it.md index 2aff529..3ad3c89 100644 --- a/appendix/03/README-it.md +++ b/appendix/03/README-it.md @@ -60,4 +60,4 @@ Siamo tutti esseri umani. Se vedete qualcosa, ditelo e fate un Pull Request oppu ### Condividete i vostri esempi di shaders Vedrete un sacco di link verso [l'editor on-line](http://editor.thebookofshaders.com/) e verso delle sue istanze integrate alla pagina. -Una volta che si scrive un codice che vi rende orgoglioso, fate clic su "Esporta" (o sull' icona ```⇪```) e quindi copiate l' "URL verso il codice..." ("URL to code..."). Inviatelo a [@bookofshaders](https://twitter.com/bookofshaders) o a [@kyndinfo](https://twitter.com/kyndinfo). Non vediamo l'ora di vederlo e aggiungerlo alla [sezione galleria di esempi](https://thebookofshaders.com/examples/). \ No newline at end of file +Una volta che si scrive un codice che vi rende orgoglioso, fate clic su "Esporta" (o sull' icona ```⇪```) e quindi copiate l' "URL verso il codice..." ("URL to code..."). Inviatelo a [@bookofshaders](https://twitter.com/bookofshaders) o a [@kyndinfo](https://twitter.com/kyndinfo). Non vediamo l'ora di vederlo e aggiungerlo alla [sezione galleria di esempi](https://thebookofshaders.com/examples/). diff --git a/appendix/03/README.md b/appendix/03/README.md index 2cb03a0..4bfc65d 100644 --- a/appendix/03/README.md +++ b/appendix/03/README.md @@ -5,17 +5,17 @@ Thanks for being willing to collaborate! There are plenty of ways you can: - Translating content - Improving the [```glossary/``` section](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/glossary) - Editing content -- Sharing your shaders examples through [the on-line editor](http://editor.thebookofshaders.com/) to +- Sharing your shaders examples through [the on-line editor](http://editor.thebookofshaders.com/) to ### Translating content -This book is written in [Markdown language](https://daringfireball.net/projects/markdown/syntax) so it's very easy to edit and work on it. +This book is written in [Markdown language](https://daringfireball.net/projects/markdown/syntax) so it's very easy to edit and work on it. 1. Start by going to [github's repository at ```github.com/patriciogonzalezvivo/thebookofshaders```](https://github.com/patriciogonzalezvivo/thebookofshaders). Take a look at the files and folders inside it. You will note that the content is in the ```README.md``` and other files with capital letters like: ```TITLE.md```, ```SUMMARY.md```, etc. Also note that translations are hosted in files with names ending in two letters referencing the language they are for, ex.: ```README-jp.md```, ```README-es.md```, etc. 2. Fork the repository and clone it in your computer. -3. Duplicate the content of the files want to translate. Remember to add to the two letters that makes reference to the language you are translating to the files you will work on. +3. Duplicate the content of the files want to translate. Remember to add to the two letters that makes reference to the language you are translating to the files you will work on. 4. Translate the content line by line (see **Translation notes**). @@ -45,7 +45,7 @@ Start running a local PHP server inside the local repository folder: php -S localhost:8000 ``` -Then in your browser search for ```localhost:8000``` go to the chapter you are translating and add ```?lan=``` followed by the two letters you used to mark the language you are translating to. +Then in your browser search for ```localhost:8000``` go to the chapter you are translating and add ```?lan=``` followed by the two letters you used to mark the language you are translating to. For example, if you are translating the chapter ```03``` to french you had been working with the file ```03/README-fr.md``` and you can test it by going to: ```http://localhost:8000/03/?lan=fr``` @@ -61,4 +61,3 @@ We are all humans. If you see something say something and make a Pull Request or You will see a lot of links to [the on-line editor](http://editor.thebookofshaders.com/) and embedded instances of it. Once you code something that makes you proud, click the "Export" (or the ```⇪``` icon) and then copy the "URL to code...". Send it to [@bookofshaders](https://twitter.com/bookofshaders) or [@kyndinfo](https://twitter.com/kyndinfo). We are looking forward to see it and add it to [the example gallery section](https://thebookofshaders.com/examples/). - diff --git a/appendix/README.md b/appendix/README.md index 0db3025..0a0bed5 100644 --- a/appendix/README.md +++ b/appendix/README.md @@ -12,4 +12,4 @@ 6. [An introduction for vectors](05/) by ... -7. [An introduction to interpolation](06) by ... \ No newline at end of file +7. [An introduction to interpolation](06) by ... diff --git a/edit.php b/edit.php index 845e6fe..903c8ca 100644 --- a/edit.php +++ b/edit.php @@ -74,7 +74,7 @@ - diff --git a/glossary/README.md b/glossary/README.md index 4499de5..3e4f96f 100644 --- a/glossary/README.md +++ b/glossary/README.md @@ -160,13 +160,13 @@ [distance()](./?search=distance) [dot()](./?search=dot) -* E +* E [equal()](./?search=equal) [exp()](./?search=exp) [exp2()](./?search=exp2) -* F +* F [faceforward()](./?search=faceforward) [float](./?search=float) @@ -214,7 +214,7 @@ [log2()](./?search=log2) [lowp](./?search=lowp) -* M +* M [matrixCompMult()](./?search=matrixCompMult) [mat2](./?search=mat2) diff --git a/glossary/abs/README.md b/glossary/abs/README.md index 775bffe..90e1068 100644 --- a/glossary/abs/README.md +++ b/glossary/abs/README.md @@ -18,4 +18,4 @@ vec4 abs(vec4 x)
### See Also -[sign()](/glossary/?search=sign), [min()](/glossary/?search=min), [max()](/glossary/?search=max), [Chapter 05: Shaping Functions](../05/) \ No newline at end of file +[sign()](/glossary/?search=sign), [min()](/glossary/?search=min), [max()](/glossary/?search=max), [Chapter 05: Shaping Functions](../05/) diff --git a/glossary/acos/README.md b/glossary/acos/README.md index 84f11e0..3128024 100644 --- a/glossary/acos/README.md +++ b/glossary/acos/README.md @@ -18,4 +18,4 @@ vec4 acos(vec4 x)
### See Also -[cos()](/glossary/?search=cos), [sin()](/glossary/?search=sin), [asin()](/glossary/?search=asin), [tan()](/glossary/?search=tan), [atan()](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[cos()](/glossary/?search=cos), [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/asin/README.md b/glossary/asin/README.md index 837e02a..00f064d 100644 --- a/glossary/asin/README.md +++ b/glossary/asin/README.md @@ -18,4 +18,4 @@ vec4 asin(vec4 x)
### See Also -[cos](/glossary/?search=cos), [sin](/glossary/?search=sin), [acos](/glossary/?search=acos), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[cos](/glossary/?search=cos), [sin](/glossary/?search=sin), [acos](/glossary/?search=acos), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/attribute/README.md b/glossary/attribute/README.md index 7201158..10e93fe 100644 --- a/glossary/attribute/README.md +++ b/glossary/attribute/README.md @@ -12,4 +12,4 @@ attribute vec4 v_color; Because the vertex shader is executed one time for each vertex, attributes are specify per vertex data typically with information such as: space position, color, normal direction and texture coordinates of a vertex. ### See Also -[const](/glossary/?search=const), [uniform](/glossary/?search=uniform), [varying](/glossary/?search=varying), [Chapter 03: Uniforms](/03/) \ No newline at end of file +[const](/glossary/?search=const), [uniform](/glossary/?search=uniform), [varying](/glossary/?search=varying), [Chapter 03: Uniforms](/03/) diff --git a/glossary/bool/README.md b/glossary/bool/README.md index 9b8411e..8bc630a 100644 --- a/glossary/bool/README.md +++ b/glossary/bool/README.md @@ -12,4 +12,4 @@ bool cBool = bool(aFloat); ```bool``` data type is either true or false. ### See Also -[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [struct](/glossary/?search=struct) \ No newline at end of file +[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [struct](/glossary/?search=struct) diff --git a/glossary/ceil/README.md b/glossary/ceil/README.md index cbebb1d..affed94 100644 --- a/glossary/ceil/README.md +++ b/glossary/ceil/README.md @@ -18,4 +18,4 @@ vec4 ceil(vec4 x)
### See Also -[floor](/glossary/?search=floor), [fract](/glossary/?search=fract), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[floor](/glossary/?search=floor), [fract](/glossary/?search=fract), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/clamp/README.md b/glossary/clamp/README.md index f6d9fb6..32013ae 100644 --- a/glossary/clamp/README.md +++ b/glossary/clamp/README.md @@ -10,7 +10,7 @@ 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) +vec4 clamp(vec4 x, float minVal, float maxVal) ``` ### Parameters @@ -26,4 +26,4 @@ vec4 clamp(vec4 x, float minVal, float maxVal)
### See Also -[min](/glossary/?search=min), [abs](/glossary/?search=abs), [max](/glossary/?search=max) \ No newline at end of file +[min](/glossary/?search=min), [abs](/glossary/?search=abs), [max](/glossary/?search=max) diff --git a/glossary/const/README.md b/glossary/const/README.md index ccf1a2a..3cb0c57 100644 --- a/glossary/const/README.md +++ b/glossary/const/README.md @@ -10,4 +10,4 @@ const float PI = 3.14159265359; ```const``` qualifier can be applied to the declaration of any variable to specify that its value will not be changed. ### See also -[attribute](/glossary/?search=attribute), [uniform](/glossary/?search=uniform), [varying](/glossary/?search=varying) \ No newline at end of file +[attribute](/glossary/?search=attribute), [uniform](/glossary/?search=uniform), [varying](/glossary/?search=varying) diff --git a/glossary/cos/README.md b/glossary/cos/README.md index 2545ce1..dffaed2 100644 --- a/glossary/cos/README.md +++ b/glossary/cos/README.md @@ -18,4 +18,4 @@ vec4 cos(vec4 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/) \ No newline at end of file +[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/cross/README.md b/glossary/cross/README.md index 9022878..e57353f 100644 --- a/glossary/cross/README.md +++ b/glossary/cross/README.md @@ -16,4 +16,4 @@ vec3 cross(vec3 x, vec3 y) ### See Also -[dot()](/glossary/?search=dot) \ No newline at end of file +[dot()](/glossary/?search=dot) diff --git a/glossary/dFdx/README.md b/glossary/dFdx/README.md index 2621568..80a1c18 100644 --- a/glossary/dFdx/README.md +++ b/glossary/dFdx/README.md @@ -13,4 +13,4 @@ genType dFdx(float x); Available only in the fragment shader, ```dFdx``` return the partial derivative of expression ```p``` in ```x```. Deviatives are calculated using local differencing. Expressions that imply higher order derivatives such as ```dFdx(dFdx(n))``` have undefined results, as do mixed-order derivatives such as ```dFdx(dFdy(n))```. It is assumed that the expression ```p``` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined. ### See Also -[dFdy()](/glossary/?search=dFdy) \ No newline at end of file +[dFdy()](/glossary/?search=dFdy) diff --git a/glossary/dFdy/README.md b/glossary/dFdy/README.md index e58c6f0..1edb54d 100644 --- a/glossary/dFdy/README.md +++ b/glossary/dFdy/README.md @@ -13,4 +13,4 @@ genType dFdy(float y); Available only in the fragment shader, ```dFdy``` return the partial derivative of expression ```p``` in ```y```. Deviatives are calculated using local differencing. Expressions that imply higher order derivatives such as ```dFdy(dFdy(n))``` have undefined results, as do mixed-order derivatives such as ```dFdy(dFdx(n))```. It is assumed that the expression ```p``` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined. ### See Also -[dFdx()](/glossary/?search=dFdx) \ No newline at end of file +[dFdx()](/glossary/?search=dFdx) diff --git a/glossary/degrees/README.md b/glossary/degrees/README.md index de4048c..a782b2b 100644 --- a/glossary/degrees/README.md +++ b/glossary/degrees/README.md @@ -8,7 +8,7 @@ vec2 degrees(vec2 radians) vec3 degrees(vec3 radians) vec4 degrees(vec4 radians) ``` - + ### Parameters ```radians``` specify the quantity, in radians, to be converted to degrees. @@ -16,4 +16,4 @@ vec4 degrees(vec4 radians) ```degrees()``` converts a quantity, specified in radians into degrees. That is, the return value is ```(180.0*radians)/PI``` ### See Also -[radians](/glossary/?search=radians) \ No newline at end of file +[radians](/glossary/?search=radians) diff --git a/glossary/distance/README.md b/glossary/distance/README.md index 7c83a81..84e4b81 100644 --- a/glossary/distance/README.md +++ b/glossary/distance/README.md @@ -21,4 +21,4 @@ float distance(vec4 p0, vec4 p1) ### See Also -[length()](/glossary/?search=length), [normalize()](/glossary/?search=normalize), [Chapter 07: Shapes](/07/) \ No newline at end of file +[length()](/glossary/?search=length), [normalize()](/glossary/?search=normalize), [Chapter 07: Shapes](/07/) diff --git a/glossary/dot/README.md b/glossary/dot/README.md index af44c3a..7dc06b2 100644 --- a/glossary/dot/README.md +++ b/glossary/dot/README.md @@ -15,11 +15,11 @@ float dot(vec4 x, vec4 y) ```y``` specifies the second of two vectors ### Description -```dot()``` returns the dot product of two vectors, ```x``` and ```y```. i.e., ```x[0]⋅y[0]+x[1]⋅y[1]+...``` +```dot()``` returns the dot product of two vectors, ```x``` and ```y```. i.e., ```x[0]⋅y[0]+x[1]⋅y[1]+...``` If ```x``` and ```y``` are the same the square root of the dot product is equivalent to the length of the vector. The input parameters can be floating scalars or float vectors. In case of floating scalars the dot function is trivial and returns the product of x and y.
### See Also -[cross()](/glossary/?search=cross), [Chapter 07: Shapes](/07/) \ No newline at end of file +[cross()](/glossary/?search=cross), [Chapter 07: Shapes](/07/) diff --git a/glossary/exp/README.md b/glossary/exp/README.md index c7bd819..2f6d42d 100644 --- a/glossary/exp/README.md +++ b/glossary/exp/README.md @@ -19,4 +19,4 @@ vec4 exp(vec4 x) ### See Also -[log](/glossary/?search=log), [log2](/glossary/?search=log2), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[log](/glossary/?search=log), [log2](/glossary/?search=log2), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/exp2/README.md b/glossary/exp2/README.md index 98433f9..1c508dc 100644 --- a/glossary/exp2/README.md +++ b/glossary/exp2/README.md @@ -19,4 +19,4 @@ vec4 exp2(vec4 x) ### See Also -[log](/glossary/?search=log), [log2](/glossary/?search=log2), [exp](/glossary/?search=exp), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[log](/glossary/?search=log), [log2](/glossary/?search=log2), [exp](/glossary/?search=exp), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/faceforward/README.md b/glossary/faceforward/README.md index 8a721af..766062a 100644 --- a/glossary/faceforward/README.md +++ b/glossary/faceforward/README.md @@ -20,4 +20,4 @@ vec4 faceforward(vec4 N, vec4 I, vec4 Nref) ```faceforward()``` orients a vector to point away from a surface as defined by its normal. ```If dot(Nref, I) < 0``` faceforward returns ```N```, otherwise it returns ```-N```. ### See Also -[reflect()](/glossary/?search=reflect), [refract()](/glossary/?search=refract) \ No newline at end of file +[reflect()](/glossary/?search=reflect), [refract()](/glossary/?search=refract) diff --git a/glossary/float/README.md b/glossary/float/README.md index cf88ac0..d9dd6bf 100644 --- a/glossary/float/README.md +++ b/glossary/float/README.md @@ -8,8 +8,8 @@ float bFloat = float(aBool); float cFloat = float(aInt); ``` -### Description +### Description ```float``` is used for floating point values. ### See Also -[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [struct](/glossary/?search=struct) \ No newline at end of file +[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [struct](/glossary/?search=struct) diff --git a/glossary/floor/README.md b/glossary/floor/README.md index 9b39cc2..8b496d0 100644 --- a/glossary/floor/README.md +++ b/glossary/floor/README.md @@ -18,4 +18,4 @@ vec4 floor(vec4 x)
### See Also -[ceil](/glossary/?search=ceil), [fract](/glossary/?search=fract), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[ceil](/glossary/?search=ceil), [fract](/glossary/?search=fract), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/fract/README.md b/glossary/fract/README.md index 6f6783d..68fd266 100644 --- a/glossary/fract/README.md +++ b/glossary/fract/README.md @@ -18,4 +18,4 @@ vec4 fract(vec4 x)
### See Also -[floor](/glossary/?search=floor), [ceil](/glossary/?search=ceil), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[floor](/glossary/?search=floor), [ceil](/glossary/?search=ceil), [mod](/glossary/?search=mod), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/gl_FragCoord/README.md b/glossary/gl_FragCoord/README.md index e4b5b8f..8aac4f7 100644 --- a/glossary/gl_FragCoord/README.md +++ b/glossary/gl_FragCoord/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_FrontFacing/README.md b/glossary/gl_FrontFacing/README.md index 10d0fbc..0abc889 100644 --- a/glossary/gl_FrontFacing/README.md +++ b/glossary/gl_FrontFacing/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxCombinedTextureImageUnits/README.md b/glossary/gl_MaxCombinedTextureImageUnits/README.md index 1441068..377bffe 100644 --- a/glossary/gl_MaxCombinedTextureImageUnits/README.md +++ b/glossary/gl_MaxCombinedTextureImageUnits/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxDrawBuffers/README.md b/glossary/gl_MaxDrawBuffers/README.md index ce9c2f6..2552884 100644 --- a/glossary/gl_MaxDrawBuffers/README.md +++ b/glossary/gl_MaxDrawBuffers/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxFragmentUniformVectors/README.md b/glossary/gl_MaxFragmentUniformVectors/README.md index 6c53e1d..b4be9bb 100644 --- a/glossary/gl_MaxFragmentUniformVectors/README.md +++ b/glossary/gl_MaxFragmentUniformVectors/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxTextureImageUnits/README.md b/glossary/gl_MaxTextureImageUnits/README.md index cef4274..5a20830 100644 --- a/glossary/gl_MaxTextureImageUnits/README.md +++ b/glossary/gl_MaxTextureImageUnits/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxVaryingVectors/README.md b/glossary/gl_MaxVaryingVectors/README.md index ce55e01..542161c 100644 --- a/glossary/gl_MaxVaryingVectors/README.md +++ b/glossary/gl_MaxVaryingVectors/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxVertexAttribs/README.md b/glossary/gl_MaxVertexAttribs/README.md index f9ed58d..2f0c679 100644 --- a/glossary/gl_MaxVertexAttribs/README.md +++ b/glossary/gl_MaxVertexAttribs/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_MaxVertexTextureImageUnits/README.md b/glossary/gl_MaxVertexTextureImageUnits/README.md index 6e665af..2e6552b 100644 --- a/glossary/gl_MaxVertexTextureImageUnits/README.md +++ b/glossary/gl_MaxVertexTextureImageUnits/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_PointCoord/README.md b/glossary/gl_PointCoord/README.md index ed280da..27444dd 100644 --- a/glossary/gl_PointCoord/README.md +++ b/glossary/gl_PointCoord/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_PointSize/README.md b/glossary/gl_PointSize/README.md index af47b5d..85b4826 100644 --- a/glossary/gl_PointSize/README.md +++ b/glossary/gl_PointSize/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/gl_Position/README.md b/glossary/gl_Position/README.md index 7724015..6bdf503 100644 --- a/glossary/gl_Position/README.md +++ b/glossary/gl_Position/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/highp/README.md b/glossary/highp/README.md index 21c004e..5e47762 100644 --- a/glossary/highp/README.md +++ b/glossary/highp/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/in/README.md b/glossary/in/README.md index 9f60041..68f7db8 100644 --- a/glossary/in/README.md +++ b/glossary/in/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/index.php b/glossary/index.php index 02ecfd1..505fa6b 100644 --- a/glossary/index.php +++ b/glossary/index.php @@ -1,7 +1,7 @@ -
-text(file_get_contents ('README.md')); - else + else echo $Parsedown->text(file_get_contents ( $_GET['search'].'/README.md' )); echo '

'; - include($path."/footer.php"); + include($path."/footer.php"); ?> diff --git a/glossary/inout/README.md b/glossary/inout/README.md index c6b5205..7917016 100644 --- a/glossary/inout/README.md +++ b/glossary/inout/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/int/README.md b/glossary/int/README.md index b65de5e..298a33c 100644 --- a/glossary/int/README.md +++ b/glossary/int/README.md @@ -12,4 +12,4 @@ int cInt = int(aFloat); ```int``` is used for integer values. ### See Also -[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4) \ No newline at end of file +[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4) diff --git a/glossary/inversesqrt/README.md b/glossary/inversesqrt/README.md index 6cb20c5..676278a 100644 --- a/glossary/inversesqrt/README.md +++ b/glossary/inversesqrt/README.md @@ -1,4 +1,4 @@ -## Inversesqrt +## Inversesqrt Return the inverse of the square root of the parameter ### Declaration @@ -19,4 +19,4 @@ vec4 inversesqrt(vec4 x) ### See Also -[pow](/glossary/?search=pow), [sqrt](/glossary/?search=sqrt), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[pow](/glossary/?search=pow), [sqrt](/glossary/?search=sqrt), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/ivec2/README.md b/glossary/ivec2/README.md index 3a12688..bd3727f 100644 --- a/glossary/ivec2/README.md +++ b/glossary/ivec2/README.md @@ -18,4 +18,4 @@ bvec2 dIvec2 = ivec2(aIvec3.x, aIvec3.y); - Providing a vector of higher dimension. The respective values are used to initialize the components. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/ivec3/README.md b/glossary/ivec3/README.md index 9333f89..3fc54db 100644 --- a/glossary/ivec3/README.md +++ b/glossary/ivec3/README.md @@ -22,4 +22,4 @@ vec3 fIvec3 = ivec3(aIvec2.x, aIvec2.y, aInt); - Providing a combination of vectors and/or scalars. The respective values are used to initialize the vector. The arguments of the constructor must have at least as many components as the vector that is initialized. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/ivec4/README.md b/glossary/ivec4/README.md index f4bec82..9abeb7f 100644 --- a/glossary/ivec4/README.md +++ b/glossary/ivec4/README.md @@ -18,4 +18,4 @@ vec4 dIvec4 = ivec4(aIvec2.x, aIvec2.y, aInt, aIvec3.x); - Providing a combination of vectors and/or scalars. The respective values are used to initialize the vector. The arguments of the constructor must have at least as many components as the vector that is initialized. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/length/README.md b/glossary/length/README.md index f1284e9..e7a77e8 100644 --- a/glossary/length/README.md +++ b/glossary/length/README.md @@ -19,4 +19,4 @@ float length(vec4 x) ### See Also -[distance()](/glossary/?search=distance), [normalize()](/glossary/?search=normalize), [Chapter 07: Shapes](/07/) \ No newline at end of file +[distance()](/glossary/?search=distance), [normalize()](/glossary/?search=normalize), [Chapter 07: Shapes](/07/) diff --git a/glossary/log/README.md b/glossary/log/README.md index 8ce2c42..4ee7916 100644 --- a/glossary/log/README.md +++ b/glossary/log/README.md @@ -19,4 +19,4 @@ vec4 log(vec4 x) ### See Also -[log2](/glossary/?search=log2), [exp](/glossary/?search=exp), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[log2](/glossary/?search=log2), [exp](/glossary/?search=exp), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/log2/README.md b/glossary/log2/README.md index af8c6da..72856b9 100644 --- a/glossary/log2/README.md +++ b/glossary/log2/README.md @@ -19,4 +19,4 @@ vec4 log2(vec4 x) ### See Also -[log](/glossary/?search=log), [exp](/glossary/?search=exp), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[log](/glossary/?search=log), [exp](/glossary/?search=exp), [exp2](/glossary/?search=exp2), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/lowp/README.md b/glossary/lowp/README.md index 23c6e29..a72b8d3 100644 --- a/glossary/lowp/README.md +++ b/glossary/lowp/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/main/README.md b/glossary/main/README.md index 974fa90..0e8ff74 100644 --- a/glossary/main/README.md +++ b/glossary/main/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/mat3/README.md b/glossary/mat3/README.md index 2c5ba4f..361d3a9 100644 --- a/glossary/mat3/README.md +++ b/glossary/mat3/README.md @@ -34,4 +34,4 @@ vec3 aVec3 = aMat3[0]; ``` ### See Also -[mat2](/glossary/?search=mat2), [mat4](/glossary/?search=mat4), [matrixCompMult()](/glossary/?search=matrixCompMult) \ No newline at end of file +[mat2](/glossary/?search=mat2), [mat4](/glossary/?search=mat4), [matrixCompMult()](/glossary/?search=matrixCompMult) diff --git a/glossary/mat4/README.md b/glossary/mat4/README.md index 07ba0e7..43812f9 100644 --- a/glossary/mat4/README.md +++ b/glossary/mat4/README.md @@ -33,4 +33,4 @@ vec4 aVec4 = aMat4[0]; ``` ### See Also -[mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [matrixCompMult()](/glossary/?search=matrixCompMult) \ No newline at end of file +[mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [matrixCompMult()](/glossary/?search=matrixCompMult) diff --git a/glossary/matrixCompMult/README.md b/glossary/matrixCompMult/README.md index 0d5b882..3fdd71d 100644 --- a/glossary/matrixCompMult/README.md +++ b/glossary/matrixCompMult/README.md @@ -17,4 +17,4 @@ mat4 matrixCompMult(mat4 x, mat4 y) ```matrixCompMult()``` performs a component-wise multiplication of two matrices, yielding a result matrix where each component, ```result[i][j]``` is computed as the scalar product of ```x[i][j]``` and ```y[i][j]```. ### See Also -[Chapter 08: Matrix](../08/) \ No newline at end of file +[Chapter 08: Matrix](../08/) diff --git a/glossary/max/README.md b/glossary/max/README.md index 770ec31..56f4da3 100644 --- a/glossary/max/README.md +++ b/glossary/max/README.md @@ -24,4 +24,4 @@ vec4 max(vec4 x, float y)
### See Also -[min](/glossary/?search=min), [abs](/glossary/?search=abs), [clamp](/glossary/?search=clamp), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[min](/glossary/?search=min), [abs](/glossary/?search=abs), [clamp](/glossary/?search=clamp), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/mediump/README.md b/glossary/mediump/README.md index 1129e2f..c049fda 100644 --- a/glossary/mediump/README.md +++ b/glossary/mediump/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/min/README.md b/glossary/min/README.md index 8310a6d..298e5ad 100644 --- a/glossary/min/README.md +++ b/glossary/min/README.md @@ -24,4 +24,4 @@ vec4 min(vec4 x, float y)
### See Also -[max](/glossary/?search=max), [abs](/glossary/?search=abs), [clamp](/glossary/?search=clamp), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[max](/glossary/?search=max), [abs](/glossary/?search=abs), [clamp](/glossary/?search=clamp), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/mod/README.md b/glossary/mod/README.md index d0d0a27..69fdf5a 100644 --- a/glossary/mod/README.md +++ b/glossary/mod/README.md @@ -23,4 +23,4 @@ vec4 mod(vec4 x, float y)
### See Also -[floor](/glossary/?search=floor), [fract](/glossary/?search=fract), [ceil](/glossary/?search=ceil), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[floor](/glossary/?search=floor), [fract](/glossary/?search=fract), [ceil](/glossary/?search=ceil), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/normalize/README.md b/glossary/normalize/README.md index 03ed151..7a27999 100644 --- a/glossary/normalize/README.md +++ b/glossary/normalize/README.md @@ -17,4 +17,4 @@ vec4 normalize(vec4 x) ### See Also -[length()](/glossary/?search=length) \ No newline at end of file +[length()](/glossary/?search=length) diff --git a/glossary/out/README.md b/glossary/out/README.md index 54c833f..dd85d89 100644 --- a/glossary/out/README.md +++ b/glossary/out/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/pow/README.md b/glossary/pow/README.md index 65fc714..b7fc9fb 100644 --- a/glossary/pow/README.md +++ b/glossary/pow/README.md @@ -21,4 +21,4 @@ vec4 pow(vec4 x, vec4 y) ### See Also -[inversesqrt](/glossary/?search=inversesqrt), [sqrt](/glossary/?search=sqrt), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[inversesqrt](/glossary/?search=inversesqrt), [sqrt](/glossary/?search=sqrt), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/precision/README.md b/glossary/precision/README.md index 0343239..f810251 100644 --- a/glossary/precision/README.md +++ b/glossary/precision/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/radians/README.md b/glossary/radians/README.md index 6ecbaac..bf29e72 100644 --- a/glossary/radians/README.md +++ b/glossary/radians/README.md @@ -8,7 +8,7 @@ vec2 radians(vec2 degrees) vec3 radians(vec3 degrees) vec4 radians(vec4 degrees) ``` - + ### Parameters ```degrees``` specify the quantity, in degrees, to be converted to radians. @@ -16,4 +16,4 @@ vec4 radians(vec4 degrees) ```radians()``` converts a quantity, specified in degrees into radians. That is, the return value is ```(PI * degrees)/180```. ### See Also -[degrees](/glossary/?search=degrees) \ No newline at end of file +[degrees](/glossary/?search=degrees) diff --git a/glossary/reflect/README.md b/glossary/reflect/README.md index be0d8ae..4455e22 100644 --- a/glossary/reflect/README.md +++ b/glossary/reflect/README.md @@ -21,4 +21,4 @@ For a given incident vector ```I``` and surface normal ```N``` reflect returns t ### See Also -[dot()](/glossary/?search=dot), [refract()](/glossary/?search=refract) \ No newline at end of file +[dot()](/glossary/?search=dot), [refract()](/glossary/?search=refract) diff --git a/glossary/refract/README.md b/glossary/refract/README.md index a1414b2..b428545 100644 --- a/glossary/refract/README.md +++ b/glossary/refract/README.md @@ -31,4 +31,4 @@ The input parameters ```I``` and ```N``` should be normalized in order to achiev ### See Also -[dot()](/glossary/?search=dot), [reflect()](/glossary/?search=reflect) \ No newline at end of file +[dot()](/glossary/?search=dot), [reflect()](/glossary/?search=reflect) diff --git a/glossary/return/README.md b/glossary/return/README.md index e252b86..76ab6b0 100644 --- a/glossary/return/README.md +++ b/glossary/return/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/sampler2D/README.md b/glossary/sampler2D/README.md index 76c7110..40622ed 100644 --- a/glossary/sampler2D/README.md +++ b/glossary/sampler2D/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/samplerCube/README.md b/glossary/samplerCube/README.md index 46c9505..ba0e7c8 100644 --- a/glossary/samplerCube/README.md +++ b/glossary/samplerCube/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/sign/README.md b/glossary/sign/README.md index d54a69e..656f2c4 100644 --- a/glossary/sign/README.md +++ b/glossary/sign/README.md @@ -18,4 +18,4 @@ vec4 sign(vec4 x)
### See Also -[abs](/glossary/?search=abs), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[abs](/glossary/?search=abs), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/sin/README.md b/glossary/sin/README.md index 59b5174..fb0c2e9 100644 --- a/glossary/sin/README.md +++ b/glossary/sin/README.md @@ -18,4 +18,4 @@ vec4 sin(vec4 angle)
### See Also -[acos](/glossary/?search=acos), [cos](/glossary/?search=cos), [asin](/glossary/?search=asin), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[acos](/glossary/?search=acos), [cos](/glossary/?search=cos), [asin](/glossary/?search=asin), [tan](/glossary/?search=tan), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/sqrt/README.md b/glossary/sqrt/README.md index 741fce3..8895ba3 100644 --- a/glossary/sqrt/README.md +++ b/glossary/sqrt/README.md @@ -20,4 +20,4 @@ vec4 sqrt(vec4 x)
### See Also -[inversesqrt](/glossary/?search=inversesqrt), [pow](/glossary/?search=pow), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[inversesqrt](/glossary/?search=inversesqrt), [pow](/glossary/?search=pow), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/step/README.md b/glossary/step/README.md index 42e9558..baf78f5 100644 --- a/glossary/step/README.md +++ b/glossary/step/README.md @@ -28,4 +28,4 @@ For element ```i``` of the return value, ```0.0``` is returned ```if x[i] < edge
### See Also -[mix](/glossary/?search=mix), [smoothstep](/glossary/?search=smoothstep), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[mix](/glossary/?search=mix), [smoothstep](/glossary/?search=smoothstep), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/struct/README.md b/glossary/struct/README.md index 2782bfc..6338481 100644 --- a/glossary/struct/README.md +++ b/glossary/struct/README.md @@ -4,7 +4,7 @@ Structure variable type ### Example ```glsl struct matStruct { - vec4 ambientColor; + vec4 ambientColor; vec4 diffuseColor; vec4 specularColor; float specularExponent; @@ -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. \ No newline at end of file +```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. diff --git a/glossary/tan/README.md b/glossary/tan/README.md index 13b2bb8..0430a8c 100644 --- a/glossary/tan/README.md +++ b/glossary/tan/README.md @@ -18,4 +18,4 @@ vec4 tan(vec4 angle)
### See Also -[cos](/glossary/?search=cos), [acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) \ No newline at end of file +[cos](/glossary/?search=cos), [acos](/glossary/?search=acos), [sin](/glossary/?search=sin), [asin](/glossary/?search=asin), [atan](/glossary/?search=atan), [Chapter 05: Shaping Functions](/05/) diff --git a/glossary/texture2D/README.md b/glossary/texture2D/README.md index 964e74c..667010c 100644 --- a/glossary/texture2D/README.md +++ b/glossary/texture2D/README.md @@ -22,4 +22,4 @@ There is an optional third input parameter of the type float: bias. After calcul Side note: On iOS devices texture lookup functionality is only available in the fragment shader. ### See Also -[textureCube](/glossary/?search=textureCube) \ No newline at end of file +[textureCube](/glossary/?search=textureCube) diff --git a/glossary/textureCube/README.md b/glossary/textureCube/README.md index 4c20412..ee196a9 100644 --- a/glossary/textureCube/README.md +++ b/glossary/textureCube/README.md @@ -22,4 +22,4 @@ There is an optional third input parameter of the type float: bias. After calcul Side note: On iOS devices texture lookup functionality is only available in the fragment shader. ### See Also -[texture2D](/glossary/?search=texture2D) \ No newline at end of file +[texture2D](/glossary/?search=texture2D) diff --git a/glossary/uniform/README.md b/glossary/uniform/README.md index 1f88d12..04b632f 100644 --- a/glossary/uniform/README.md +++ b/glossary/uniform/README.md @@ -7,4 +7,4 @@ ### Description ### See Also -[Chapter 03: Uniforms](../05/) \ No newline at end of file +[Chapter 03: Uniforms](../05/) diff --git a/glossary/varying/README.md b/glossary/varying/README.md index 0a8da52..95fadcb 100644 --- a/glossary/varying/README.md +++ b/glossary/varying/README.md @@ -6,4 +6,4 @@ ### Description -### See Also \ No newline at end of file +### See Also diff --git a/glossary/vec2/README.md b/glossary/vec2/README.md index d768255..480703e 100644 --- a/glossary/vec2/README.md +++ b/glossary/vec2/README.md @@ -18,4 +18,4 @@ vec2 dVec2 = vec2(aVec3.x, aVec3.y); - Providing a vector of higher dimension. The respective values are used to initialize the components. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/vec3/README.md b/glossary/vec3/README.md index 573d646..aa207cc 100644 --- a/glossary/vec3/README.md +++ b/glossary/vec3/README.md @@ -22,4 +22,4 @@ vec3 fVec3 = vec3(aVec2.x, aVec2.y, aFloat); - Providing a combination of vectors and/or scalars. The respective values are used to initialize the vector. The arguments of the constructor must have at least as many components as the vector that is initialized. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/vec4/README.md b/glossary/vec4/README.md index d1bbfad..3947b2b 100644 --- a/glossary/vec4/README.md +++ b/glossary/vec4/README.md @@ -18,4 +18,4 @@ vec4 dBvec4 = bvec4(aBvec2.x, aBvec2.y, aBool, aBvec3.x); - Providing a combination of vectors and scalars. The respective values are used to initialize the components. The arguments of the constructor must have at least as many components as the vector that is initialized. ### See Also -[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) \ No newline at end of file +[bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float), [bvec2](/glossary/?search=bvec2), [bvec3](/glossary/?search=bvec3), [bvec4](/glossary/?search=bvec4), [ivec2](/glossary/?search=ivec2), [ivec3](/glossary/?search=ivec3), [ivec4](/glossary/?search=ivec4), [vec2](/glossary/?search=vec2), [vec3](/glossary/?search=vec3), [vec4](/glossary/?search=vec4), [mat2](/glossary/?search=mat2), [mat3](/glossary/?search=mat3), [mat4](/glossary/?search=mat4) diff --git a/glossary/void/README.md b/glossary/void/README.md index 87168f3..558de4e 100644 --- a/glossary/void/README.md +++ b/glossary/void/README.md @@ -11,4 +11,4 @@ void bFunction(float); ```void``` is used when a function have no parameters or when a function does not return a value. ### See Also -[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float) \ No newline at end of file +[void](/glossary/?search=void), [bool](/glossary/?search=bool), [int](/glossary/?search=int), [float](/glossary/?search=float) diff --git a/graph.html b/graph.html index 105dfa1..9637ff9 100644 --- a/graph.html +++ b/graph.html @@ -9,7 +9,7 @@ - + ",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}); \ No newline at end of file +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return w(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(w(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){f+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function h(){if(!k.k)return n(M);var e="",t=0;k.lR.lastIndex=0;for(var r=k.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(k,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=k.lR.lastIndex,r=k.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof k.sL;if(e&&!R[k.sL])return n(M);var t=e?f(k.sL,M,!0,y[k.sL]):l(M,k.sL.length?k.sL:void 0);return k.r>0&&(B+=t.r),e&&(y[k.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=void 0!==k.sL?d():h(),M=""}function v(e,n){L+=e.cN?p(e.cN,"",!0):"",k=Object.create(e,{parent:{value:k}})}function m(e,n){if(M+=e,void 0===n)return b(),0;var t=o(n,k);if(t)return t.skip?M+=n:(t.eB&&(M+=n),b(),t.rB||t.eB||(M=n)),v(t,n),t.rB?0:n.length;var r=u(k,n);if(r){var a=k;a.skip?M+=n:(a.rE||a.eE||(M+=n),b(),a.eE&&(M=n));do k.cN&&(L+=""),k.skip||(B+=k.r),k=k.parent;while(k!=r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,k))throw new Error('Illegal lexeme "'+n+'" for mode "'+(k.cN||"")+'"');return M+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var x,k=i||N,y={},L="";for(x=k;x!=N;x=x.parent)x.cN&&(L=p(x.cN,"",!0)+L);var M="",B=0;try{for(var C,j,I=0;;){if(k.t.lastIndex=I,C=k.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),x=k;x.parent;x=x.parent)x.cN&&(L+="");return{r:B,value:L,language:e,top:k}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(w(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function p(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n=i(e);if(!a(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var h=document.createElementNS("http://www.w3.org/1999/xhtml","div");h.innerHTML=o.value,o.value=c(s,u(h),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=p(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,h)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function N(){return Object.keys(R)}function w(e){return e=(e||"").toLowerCase(),R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=h,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},a={cN:"meta",b:/<\?(php)?|\?>/},i={cN:"string",c:[e.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},t={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[a]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},a,c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,i,t]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,t]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl"],k:t,c:o}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+"(\\s*,\\s*"+e.UIR+")*>)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",r="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:r,r:0};return{aliases:["jsp"],k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI|XC)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},n=/[a-zA-Z@][a-zA-Z0-9_]*/,o="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:i,l:n,i:""}]}]},{cN:"class",b:"("+o.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:o,l:n,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("cs",function(e){var t="abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",r=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:t,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+r+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"section",b:/^[\w]+:\s*$/},{cN:"meta",b:/^\.PHONY:/,e:/$/,k:{"meta-keyword":".PHONY"},l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke",e:/;/,eW:!0,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("javascript",function(e){return{aliases:["js","jsx"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b://,sL:"xml",c:[{b:/<\w+\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:["self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},i={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:t.CNR}],r:0},s={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"}]},r,t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"};return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,i]},t.CLCM,t.CBCM,s]}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",c="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",r={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[r]}),e.C("^\\=begin","^\\=end",{c:[r],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:c},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:c},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var o="[>?]>",l="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+o+"|"+l+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:c,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("dts",function(e){var a={cN:"string",v:[e.inherit(e.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[e.BE]},{b:"'\\\\?.",e:"'",i:"."}]},c={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:e.CNR}],r:0},b={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef ifdef ifndef"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[e.inherit(a,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"}]},a,e.CLCM,e.CBCM]},i={cN:"variable",b:"\\&[a-z\\d_]*\\b"},r={cN:"meta-keyword",b:"/[a-z][a-z\\d-]*/"},d={cN:"symbol",b:"^\\s*[a-zA-Z_][a-zA-Z\\d_]*:"},n={cN:"params",b:"<",e:">",c:[c,i]},s={cN:"class",b:/[a-zA-Z_][a-zA-Z\d_@]*\s{/,e:/[{;=]/,rB:!0,eE:!0},t={cN:"class",b:"/\\s*{",e:"};",r:10,c:[i,r,d,s,n,e.CLCM,e.CBCM,c,a]};return{k:"",c:[t,i,r,d,s,n,e.CLCM,e.CBCM,c,a,b,{b:e.IR+"::",k:""}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},s=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];r.c=s;var i=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(s)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:s.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("glsl",function(e){return{k:{keyword:"break continue discard do else for if return whileattribute binding buffer ccw centroid centroid varying coherent column_major const cw depth_any depth_greater depth_less depth_unchanged early_fragment_tests equal_spacing flat fractional_even_spacing fractional_odd_spacing highp in index inout invariant invocations isolines layout line_strip lines lines_adjacency local_size_x local_size_y local_size_z location lowp max_vertices mediump noperspective offset origin_upper_left out packed patch pixel_center_integer point_mode points precise precision quads r11f_g11f_b10f r16 r16_snorm r16f r16i r16ui r32f r32i r32ui r8 r8_snorm r8i r8ui readonly restrict rg16 rg16_snorm rg16f rg16i rg16ui rg32f rg32i rg32ui rg8 rg8_snorm rg8i rg8ui rgb10_a2 rgb10_a2ui rgba16 rgba16_snorm rgba16f rgba16i rgba16ui rgba32f rgba32i rgba32ui rgba8 rgba8_snorm rgba8i rgba8ui row_major sample shared smooth std140 std430 stream triangle_strip triangles triangles_adjacency uniform varying vertices volatile writeonly",type:"atomic_uint bool bvec2 bvec3 bvec4 dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 double dvec2 dvec3 dvec4 float iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBufferiimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray int isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow image1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D samplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 vec2 vec3 vec4 void",built_in:"gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxComputeAtomicCounterBuffers gl_MaxComputeAtomicCounters gl_MaxComputeImageUniforms gl_MaxComputeTextureImageUnits gl_MaxComputeUniformComponents gl_MaxComputeWorkGroupCount gl_MaxComputeWorkGroupSize gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentInputVectors gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexOutputVectors gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffset gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_GlobalInvocationID gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_LocalInvocationID gl_LocalInvocationIndex gl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_NumSamples gl_NumWorkGroups gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrix gl_TextureMatrixInverse gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_WorkGroupID gl_WorkGroupSize gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicAdd atomicAnd atomicCompSwap atomicCounter atomicCounterDecrement atomicCounterIncrement atomicExchange atomicMax atomicMin atomicOr atomicXor barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual groupMemoryBarrier imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageSize imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier memoryBarrierAtomicCounter memoryBarrierBuffer memoryBarrierImage memoryBarrierShared min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLevels textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow",literal:"true false"},i:'"',c:[e.CLCM,e.CBCM,e.CNM,{cN:"meta",b:"#",e:"$"}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"symbol",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link",e:"$"}}]}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}); diff --git a/src/main.js b/src/main.js index 7257047..70ed519 100644 --- a/src/main.js +++ b/src/main.js @@ -137,12 +137,12 @@ function loadGlslElements() { for(var i = 0; i < ccList.length; i++){ if (ccList[i].hasAttribute("data")){ var srcFile = ccList[i].getAttribute("data"); - var editor = new GlslEditor(ccList[i], { - canvas_size: 250, + var editor = new GlslEditor(ccList[i], { + canvas_size: 250, canvas_follow: true, canvas_float: 'right', - tooltips: true, - exportIcon: true + tooltips: true, + exportIcon: true }); editor.open(srcFile); glslEditors.push(editor); @@ -154,15 +154,15 @@ function loadGlslElements() { for(var i = 0; i < sfList.length; i++){ if (sfList[i].hasAttribute("data")){ var srcFile = sfList[i].getAttribute("data"); - glslGraphs.push(new GlslEditor(sfList[i], { - canvas_width: 800, - lineNumbers: false, - canvas_height: 250, + glslGraphs.push(new GlslEditor(sfList[i], { + canvas_width: 800, + lineNumbers: false, + canvas_height: 250, canvas_follow: true, canvas_float: false, - frag_header: preFunction, - frag_footer: postFunction, - tooltips: true + frag_header: preFunction, + frag_footer: postFunction, + tooltips: true }).open(srcFile)); } } diff --git a/src/moon/moon.frag b/src/moon/moon.frag index 4943a82..11c7988 100644 --- a/src/moon/moon.frag +++ b/src/moon/moon.frag @@ -18,11 +18,11 @@ float speedMoon = 0.01; float speedSun = 0.25; vec3 sphereNormals(in vec2 uv) { - uv = fract(uv)*2.0-1.0; + uv = fract(uv)*2.0-1.0; vec3 ret; ret.xy = sqrt(uv * uv) * sign(uv); ret.z = sqrt(abs(1.0 - dot(ret.xy,ret.xy))); - ret = ret * 0.5 + 0.5; + ret = ret * 0.5 + 0.5; return mix(vec3(0.0), ret, smoothstep(1.0,0.98,dot(uv,uv)) ); } @@ -57,13 +57,13 @@ vec4 sphereTexture(in sampler2D _tex, in vec2 _uv) { void main(){ vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(1.0); - + color *= sphereTexture(u_tex0, st).rgb; // Calculate sun direction vec3 sunPos = normalize(vec3(cos(u_time*speedSun-HALF_PI),0.0,sin(speedSun*u_time-HALF_PI))); vec3 surface = normalize(sphereNormals(st)*2.0-1.0); - + // Add Shadows color *= dot(sunPos,surface); @@ -74,4 +74,4 @@ void main(){ color = 1.0-color; gl_FragColor = vec4(color,1.0); -} \ No newline at end of file +}