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 ); } -