Merge branch 'master' into translation-jp

pull/39/head
Patricio Gonzalez Vivo 9 years ago
commit 188fb4023c

@ -0,0 +1,48 @@
# Introduction
<canvas id="custom" class="canvas" data-fragment-url="cmyk-halftone.frag" data-textures="vangogh.jpg" width="700px" height="320px"></canvas>
위에 두 이미지는 다른 방법을 통해 만들어졌다. 첫번째것은 반 고흐가 직접 레이어 위에 레이어를 쌓는 방식으로 만들어졌다. 제법 시간이 걸렸을것이다. 두번째것은 몇초 안되는 시간안에 픽셀들의 행렬연산 4개를 통해 만들어 졌다: 한개는 cyan색, 다른 한개는 magenta색, 또 다른 한개는 yellow, 그리고 마지막것은 black. 중요한점은 두번째 이미지는 그림을 부분마다 따로 그려나가게 아니라 그림의 다른 모든 부분이 한번에 그려졌다는 것이다.
이 책은, *fragment shaders*, 라는 디지털 그림 제작과정을 다음 레벨로 이끌어낼 혁신적인 컴퓨팅 기술에 대한 것이다. 바로 그래픽 인더스트리의 구텐베르크 인쇄술인것이다.
![Gutenberg's press](gutenpress.jpg)
Fragment shader는 매우 빠른 속도로 스크린에 렌더되는 픽셀들을 완전히 컨트롤 할수 있는 능력을 준다. 핸드폰의 비디오 필터나, AAA 3D 비디오 같은 미디어에서 쓰이는 이유도 이것때문이다.
![Journey by That Game Company](journey.jpg)
앞으로 맞이할 챕터들은 독자가 이 강력하고 바른 기술을 스스로 습득하고, 자신의 작업에 적용할수 있는 길을 보여줄것이다.
## 누구를 위한 책인가?
이 책은 삼각함수와 선형대수학에 대한 기본이해가 있고 작업에 있어 그래픽 요소를 극대화 시키려는 creative coder, 게임 개발자, 그래픽 엔지니어들을 위한 책이다. (만약 본인이 코딩입문자라면 이 링크를 보고, [Processing](https://processing.org/) 코딩이 익숙해졌을때쯤 다시 돌아와 이책을 보길 권한다.)
이책은 독자들에게 쉐이더를 프로젝트에 어떻게 쓰는지와, 이를 통한 퍼포먼스 향상과 퀄리티를 높이는 방법들을 보여줄것이다. GLSL (OpenGL Shading Language) 쉐이더들은 OpenGL, OpenGL ES 혹은 WebGL을 가진 환경에서 컴파일되고 실행될것이다. 한마디로, 이것에 대한 기술을 [Processing](https://processing.org/) 스켓치파일들, [openFrameworks](http://openframeworks.cc/) 어플들, [Cinder](http://libcinder.org/) 설치미술들, [Three.js](http://threejs.org/) 웹사이트들 또는 iOS/Android 게임들에 적용할수 있다는 것이다.
## 어떤 내용들을 다루나?
이책은 GLSL pixel shader를 메인으로 다룬다. 먼저, 쉐이더가 무엇인지 알아보고, 절차적(procedural) 모양, 패턴, 텍스쳐, 애니메이션등에 응용해볼것이다. 쉐이딩 랭기지의 기본에 대해 다지게 되고, 여러 분야에 적용해볼수 있도록 유도하는데 예를들면: 이미지 처리(이미지 여산, 메트릭스 회선, blurs, color filters, 룩업테이블과 기타 효과들)와 시뮬레이션 (Conway's game of life, Gray-Scott's reaction-diffusion, water ripples, 물감 효과, Voronoi cells등등)이 그 좋은 예이다. 책의 막바지에는 Ray Marching과 같은 고급기술도 소개를 한다.
*각 챕터는 인터엑티브한 예제들로 구성되어 있다.* 예제들의 코드를 변경하면, 바로 그에 대한 결과를 볼수 있다. 컨셉자체가 추상적이거나 난해할수도 있기에, 이런 인터엑티브 예제가 이해하는데 큰 도움이 될거라고 믿는다. 컨셉에 대한 예제를 많이 가지고 놀아볼수록 그에 대한 이해역시 빨리 될거라고 생각한다.
이책이 다루지 않는 부분:
* 이책은 openGL이나 webGL서적이 아니다. openGL/webGL은 GLSL이나 fragment shader보다 훨씬 더 큰 주제이다. 그런것들에 대해 좀더 싶히 공부하고 싶다면: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (빨간책이라고도 알려진) 이나 [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) 등을 추천한다.
* 이책은 수학색이 아니라. 물론 여러 종류의 알고리즘과 대수학과, 삼각함수에 기댄 수학수식이 많이 이용되지만, 그런것들에 대해 자세히 설명하지는 않을 것이다. 수학에 대한 질문은 : [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) 를 보거나, [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers) 등을 참고하기 바란다.
## 시작하기 위해 무엇을 해야하나?
필요한것은 따로 없다! 근대 브라우져를 이용하고 있다면, WebGL이 서포트 될것이고 (구글 크롬이나 파이어폭스, 사파리), 인터넷만 있으면 된다! (지금 보고 있지만) 페이지 최하단에 있는 "Next"버튼을 눌러 다음챕터로 가면 시작이다.
아니면 , 다음과 같은 방법으로도 이 책을 접할수 있다:
- [이책의 오프라인 버젼](http://thebookofshaders.com/appendix/)
- [RaspberryPi에서 브라우져 없이 예제들 돌리기](http://thebookofshaders.com/appendix/)
- [이책의 PDF버젼 만들기](http://thebookofshaders.com/appendix/)
- 또는 [온라인 리포](https://github.com/patriciogonzalezvivo/thebookofshaders) 이슈들을 답하거나, 올려주세요.

@ -0,0 +1,142 @@
# 算法绘画
## 造型函数
这一章应该叫做 Mr. Miyagi 的栅栏课。之前我们给规范化的 x,y 坐标和红、绿通道建立了映射map。本质上说我们是建造了这样一个函数输入一个二维向量xy)然后返回一个四维向量rgba。但在我们跨维度转换数据之前我们先从更加…更加简单的开始。我们来建一个只有一维变量的函数。你花越多的时间和精力在这上面你的 shader 功夫就越厉害。
![The Karate Kid (1984)](mr_miyagi.jpg)
接下来的代码构造就是我们的「栅栏」。在它之中我们把规范化的 x 坐标(```st.x```)可视化。有两种途径:一种是用亮度(度量从黑色到白色的渐变过程),另一种是在顶部绘制一条绿色的线(在这种情况下 x 被直接赋值给 y。不用过分在意绘制函数我们马上会更加详细地解释它。
<div class="codeAndCanvas" data="linear.frag"></div>
**简注** ```vec3``` 类型构造器“明白”你想要把颜色的三个通道赋值到一个值里,就像 ```vec4``` 明白你想要构建一个四维向量,三维向量加上第四个值(比如颜色的三个值加上透明度)。请参照上面示例的第 20 到 26 行。
这些代码就是你的栅栏;遵守和理解它非常重要。你将会一遍又一遍地回到 0.0 到 1.0 这个区间。你将会掌握融合与构建这些代码的艺术。
这些 x 与 y或亮度之间一对一的关系称作**线性插值**linear interpolation。现在起我们可以用一些数学函数来改造这些代码行。比如说我们可以把 x 升到 5 来做一个曲线。
<div class="codeAndCanvas" data="expo.frag"></div>
很有趣,对吧?试试看把第 19 行的指数改为不同的值比如20.02.01.00.00.2 或 0.02。理解值和指数之间的关系非常重要。这些数学函数可以让你灵动地控制你的代码,就像是给数据做针灸一样。
[```pow()```](../glossary/?search=pow) 是 GLSL 的一个原生/内建函数GLSL 有很多原生函数。大多数原生函数都是硬件加速的,也就是说如果你正确使用这些函数,你的代码就会跑得更快。
换掉第 19 行的幂函数,试试看[```exp()```](../glossary/?search=exp)[```log()```](../glossary/?search=log) 和 [```sqrt()```](../glossary/?search=sqrt)。当你用 Pi 来玩的时候有些方程会变得更有趣。在第 5 行我定义了一个宏,使得每当程序调用 ```PI``` 的时候就用 ```3.14159265359``` 来替换它。
### Step 和 Smoothstep
GLSL 还有一些独特的原生插值函数可以被硬件加速。
[```step()```](../glossary/?search=step) 插值接收两个参数。第一个是极限或阀值,第二个是我们想要检测或传递的值。对任何小于阀值的值,返回 ```0.0```,大于阀值,则返回 ```1.0```。
试试看改变下述代码中第 20 行的值。
<div class="codeAndCanvas" data="step.frag"></div>
另一个 GLSL 的特殊函数是 [```smoothstep()```](../glossary/?search=smoothstep)。当给定一个范围的上下限和一个数值,这个函数会在已有的范围内给出插值。前两个参数规定转换的开始和结束点,第三个是给出一个值用来插值。
<div class="codeAndCanvas" data="smoothstep.frag"></div>
在之前的例子中,注意第 12 行,我们用到 smoothstep 在 ```plot()``` 函数中画了一条绿色的线。这个函数会对给出的 x 轴上的每个值,在特定的 y 值处制造一个凹凸形变。如何做到呢?通过把两个 [```smoothstep()```](../glossary/?search=smoothstep) 连接到一起。来看看下面这个函数,用它替换上面的第 20 行,把它想成是一个垂直切割。背景看起来很像一条线,不是吗?
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
```
### 正弦和余弦函数
当你想用数学来制造动效形态或混合数值sin 和 cos 就是你的最佳伙伴。
这两个基础的三角函数是构造圆的极佳工具,就像张小泉的剪刀一样称手。很重要的一点是你需要知道它们是如何运转的,还有如何把它们结合起来。简单来说,当我们给出一个角度(这里采用弧度制),它就会返回半径为一的圆上一个点的 x 坐标([cos](../glossary/?search=cos))和 y 坐标([sin](../glossary/?search=sin))。正因为 sin 和 cos 返回的是规范化的值(即值域在 -1 和 1 之间),且如此流畅,这就使得它成为一个极其强大的工具。
![](sincos.gif)
尽管描述三角函数和圆的关系是一件蛮困难的事情,上图动画很棒地做到了这一点,视觉化展现了它们之间的关系。
<div class="simpleFunction" data="y = sin(x);"></div>
仔细看 sin 曲线。观察 y 值是如何平滑地在 +1 和 -1 之间变化。就像之前章节关于的 time 的例子中,你可以用 [```sin()```](../glossary/?search=sin) 的有节奏的变动给其他东西加动效。如果你是在用浏览器阅读的话你可以改动上述公式,看看曲线会如何变动。(注:不要忘记每行最后要加分号!)
试试下面的小练习,看看会发生什么:
* 在 ```sin``` 里让 x 加上时间(```u_time```。让sin 曲线随 x 轴**动起来**。
* 在 ```sin``` 里用 ```PI``` 乘以 x。注意 sin 曲线上下波动的两部分如何**收缩**了,现在 sin 曲线每两个整数循环一次。
* 在 ```sin``` 里用时间( ```u_time```)乘以 x。观察各阶段的循环如何变得越来越**频繁**。注意 u_time 可能已经变得非常大,使得图像难以辨认。
* 给 [```sin(x)```](../glossary/?search=sin)(注意不是 sin 里的 x加 1.0。观察曲线是如何向上**移动**的,现在值域变成了 0.0 到 2.0。
* 给 [```sin(x)```](../glossary/?search=sin) 乘以 2.0。观察曲线大小如何**增大**两倍。
* 计算 ```sin(x)``` 的绝对值([```abs()```](../glossary/?search=abs))。现在它看起来就像一个**弹力球**的轨迹。
* 只选取 ```sin(x)``` 的小数部分([```fract()```](../glossary/?search=fract))。
* 使用向正无穷取整([```ceil()```](../glossary/?search=ceil))和向负无穷取整([```floor()```](../glossary/?search=floor)),使得 sin 曲线变成只有 1 和 -1 的电子波。
### 其他有用的函数
最后一个练习中我们介绍了一些新函数。现在我们来一个一个试一遍。依次取消注释下列各行理解这些函数观察它们是如何运作的。你一定在奇怪……为什么要这么做呢Google 一下“generative art”生成艺术你就知道了。要知道这些函数就是我们的栅栏。我们现在控制的是它在一维中的移动上上下下。很快我们就可以尝试二维、三维甚至四维了
![Anthony Mattox (2009)](anthony-mattox-ribbon.jpg)
<div class="simpleFunction" data="y = mod(x,0.5); // x 0.5
//y = fract(x); // 仅仅返回数的小数部分
//y = ceil(x); // 向正无穷取整
//y = floor(x); // 向负无穷取整
//y = sign(x); // 提取 x 的正负号
//y = abs(x); // 返回 x 的绝对值
//y = clamp(x,0.0,1.0); // 把 x 的值限制在 0.0 到 1.0
//y = min(0.0,x); // 返回 x 和 0.0 中的较小值
//y = max(0.0,x); // 返回 x 和 0.0 中的较大值 "></div>
### 造型函数进阶
[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/)
* [指数造型函数Exponential Shaping Functions: www.flong.com/texts/code/shapers_exp](http://www.flong.com/texts/code/shapers_exp/)
* [圆与椭圆的造型函数Circular & Elliptical Shaping Functions: www.flong.com/texts/code/shapers_circ](http://www.flong.com/texts/code/shapers_circ/)
* [贝塞尔和其他参数化造型函数Bezier and Other Parametric Shaping Functions: www.flong.com/texts/code/shapers_bez](http://www.flong.com/texts/code/shapers_bez/)
就像厨师自主选择辣椒和各种原料,数字艺术家和创意编程者往往钟情于使用他们自己的造型函数。
[Iñigo Quiles](http://www.iquilezles.org/) 收集了一套[有用的函数](http://www.iquilezles.org/www/articles/functions/functions.htm)。在看过[这篇文章](http://www.iquilezles.org/www/articles/functions/functions.htm)后,看看下列函数转换到 GLSL 的样子。注意那些细小的改变比如给浮点数float)加小数点“.”给“C 系函数”换成它们在 GLSL 里的名字,比如不是用 ```powf()``` 而是用 ```pow()```
* [Impulse](../edit.html#05/impulse.frag)
* [Cubic Pulse](../edit.html#05/cubicpulse.frag)
* [Exponential Step](../edit.html#05/expstep.frag)
* [Parabola](../edit.html#05/parabola.frag)
* [Power Curve](../edit.html#05/pcurve.frag)
给你们看些东西刺激一下斗志,这里有一个非常优雅的例子(作者是 [Danguafer](https://www.shadertoy.com/user/Danguafer),造型函数的空手道黑带)。
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/XsXXDn?gui=true&t=10&paused=true" allowfullscreen></iframe>
在下一章我们会有一些新的进展。我们会先混合各种颜色,然后画些形状。
#### 练习
来看看 [Kynd](http://www.kynd.info/log/) 帮大家制作的公式表。看他如何结合各种函数及它们的属性,始终控制值的范围在 0.0 到 1.0。好了,现在是你自己练习的时候了!来试试这些函数,记住:熟能生巧。
![Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)](kynd.png)
#### 填充你的工具箱
这里有一些工具可以帮你更轻松地可视化这些函数。
* Grapher如果你是用 MacOS 系统,用 spotlight 搜 ```grapher``` 就会看到这个超级方便的工具了。
![OS X Grapher (2004)](grapher.png)
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/):仍然是 [Iñigo Quilez](http://www.iquilezles.org) 为大家做的工具,用于在 WebGL 中可视化 GLSL 函数。
![Iñigo Quilez - GraphToy (2010)](graphtoy.png)
* [Shadershop](http://tobyschachman.com/Shadershop/):这个超级棒的工具是 [Toby Schachman](http://tobyschachman.com/) 的作品。它会以一种极其视觉化和直观的方式教你如何建造复杂的函数。
![Toby Schachman - Shadershop (2014)](shadershop.png)

@ -27,7 +27,7 @@ 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.
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 call *swizzle*.
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;

@ -0,0 +1,121 @@
## Patterns 图案
因为着色器按一个个像素执行,那么无论你重复一个图形多少次,计算的数量仍然是个常数。
[ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.html#09/dots5.frag)
本章中我们将综合我们目前所学的并应用在画布上。和前几章一样我们的策略依然基于乘以空间坐标0到1之间这样我们的画的在0到1之间的图形就会重复地形成网格。
*"网格提供一种基于人的直觉发明事物的框架,并且可以颠覆。自然的混沌肌理提供一种对比和秩序的迹象。从早期罗马浴场里的陶瓷图案到几何镶嵌,人们那时候就习惯用网格来点缀他们的生活。"*[*10 PRINT*, Mit Press, (2013)](http://10print.org/)
首先让我们记住 [```fract()```](../glossary/?search=fract) 函数。它返回一个数的分数部分本质上是除1的余数[```mod(x,1.0)```](../glossary/?search=mod))。换句话说, [```fract()```](../glossary/?search=fract) 返回小数点后的数。 我们单位化的坐标系变量 (```st```) 已经是 0.0 到 1.0 之间的了。所以像下面这么做并没有必要:
```glsl
void main(){
vec2 st = gl_FragCoord.xy/u_resolution;
vec3 color = vec3(0.0);
st = fract(st);
color = vec3(st,0.0);
gl_FragColor = vec4(color,1.0);
}
```
但如果我们放大单位化坐标系 — 比如说3倍 — 我们会得到三组 0 到 1 的线性插值的数列:第一组在 0-1 之间,第二组浮点数在 1-2 之间以及第三组在 2-3 之间的浮点数。
<div class="codeAndCanvas" data="grid-making.frag"></div>
现在是时候在子空间网格单元的空间里画点什么了。取消27行的注释。因为我们等比例放大了x和y坐标所以不会改变坐标的比例图形会和预期的一样。
试试下面的练习来深入理解:
* 把空间乘以不同的数。试试用浮点数还有分别给x和y不同的系数。
* 把这个平铺技巧做成一个可以反复使用的函数。
* 把画布分成 3 行 3 列。 指出如何定义行和列的线程的,并用这种方式改变显示着的图形。试着做一个井字棋。
### 在图案内部应用矩阵
鉴于每个细分或者说单元都是我们正在使用的单位化坐标系的小单元,我们可以对每个内部空间施以矩阵变换来平移,旋转和缩放。
<div class="codeAndCanvas" data="checks.frag"></div>
* 想想怎么让这些图案有趣的动起来。考虑颜色,形状,运动的变换。做三种动画。
* 通过组合不同的形状重新创造更复杂的图案。
<a href="../edit.html#09/diamondtiles.frag"><canvas id="custom" class="canvas" data-fragment-url="diamondtiles.frag" width="520px" height="200px"></canvas></a>
* 结合多层图案来制作你自己的 [Scottish Tartan Patterns](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns).
[ ![Vector Pattern Scottish Tartan By Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076)
### 偏移图案
So let's say we want to imitate a brick wall. Looking at the wall, you can see a half brick offset on x in every other row. How we can do that?
假如我们想要模仿砖墙。看下面的墙你是不是看到一半的砖在x方向上偏移了一半砖的长度没隔一行偏移一次。我们如何实现
![](brick.jpg)
第一步我们需要知道某行的线程是奇数还是偶数以为我们可以通过奇偶来决定是否要在x方向上偏移那一行。
____我们需要两段来解决这个问题____
要判断我们的线程是一个奇数行或者偶数行,我们要用 ```2.0``` 的 [```mod()```](../glossary/?search=mod) 。 然后根据结果是否大于 ```1.0``` 来判断。看一下下面的函数,取消最后两行的注释。
<div class="simpleFunction" data="y = mod(x,2.0);
// y = mod(x,2.0) < 1.0 ? 0. : 1. ;
// y = step(1.0,mod(x,2.0));"></div>
正如你所见,我们可以用一个 [三元算符号](https://en.wikipedia.org/wiki/%3F:) (第二行)来检查 ```2.0``` 的[```mod()```](../glossary/?search=mod)(余数)小于 ```1.0``` 或者类似地,我们用 [```step()```](../glossary/?search=step) 函数做相同的操作,但(其实)更快。为什么呢? 因为虽然要知道每个显卡如何优化和编译代码并不容易,但是可以安全地假设内置函数总比非内置的函数快。任何时候你都以调用内置函数,干嘛不用呢!
现在我们有这些找出奇数的方程,这样我们就可以给奇数行一个偏移量,然后就可以把 *砖块* 做出拼砖的效果。下面代码的第14行便是我们用来“侦测”奇数行并予之半个单位在x上的偏移的。注意到对偶数行函数的返回值是 ```0.0``` ```0.0``` 乘以 ```0.5``` 得到一个 ```0.0``` 的偏移。 但是奇数行我们用函数的返回值, ```1.0``` 乘以偏移量 ```0.5```,这样便向坐标系的 ```x``` 轴偏移了 ```0.5```。
现在试着取消32行的注释 — 拉伸长宽比来模仿“现代砖块”的长宽比。通过取消第40行的的代码你可以注意到坐标系统是如何看起来映射到红绿色的。
<div class="codeAndCanvas" data="bricks.frag"></div>
* 试着根据时间变化对偏移量做动画。
* 另做一个动画,让偶数行向左移,奇数行向右移动。
* 能不能根据列重复这样的效果?
* 试着结合 ```x``` 和 ```y``` 轴的偏移来得到下面这样的效果:
<a href="../edit.html#09/marching_dots.frag"><canvas id="custom" class="canvas" data-fragment-url="marching_dots.frag" width="520px" height="200px"></canvas></a>
## Truchet 瓷砖
目前我们学了如何区分奇数行/列或偶数行/列,(类似的),(我们也)可能再用(这个技巧)根据位置来设计元素。 考虑到 [Truchet Tiles](http://en.wikipedia.org/wiki/Truchet_tiles) 的例子,即一个单一设计元素可以以四种不同的方式呈现:
![](truchet-00.png)
通过改变对角瓷砖的图案,便可能组成无限种复杂设计的可能。
![](truchet-01.png)
仔细观察 ```rotateTilePattern()``` 函数, 它把坐标空间细分成四个单元并赋予每一个旋转值。
<div class="codeAndCanvas" data="truchet.frag"></div>
* 注释取消注释以及复制第69到72行来创作新的设计。
* 把黑白三角变成其他元素,例如:半圆,旋转的方形或直线。
* 编写根据元素自身位置旋转的图形代码。
* 创作一个根据其位置改变其他属性的图案。
* 想想其他能用这章原理的案例,不一定是图案. (例: 易经卦)
<a href="../edit.html#09/iching-01.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-01.frag" width="520px" height="200px"></canvas></a>
## 制定自己的规则
制作程序图案是种寻找最小可重复元素的古老练习(灵修)。我们作为长时间使用网格和图案来装饰织物、地面和物品的镶边物种:从古希腊的弯曲图案,到中国的窗栅设计,重复和变化的愉悦吸引我们的想象。花些时间浏览 [decorative](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [patterns](https://www.pinterest.com/patriciogonzv/paterns/) 并看看在漫长的历史里,艺术家和设计师是如何寻找在秩序的预测性和(由)混沌和衍变(产生)的惊奇之间的边界的。从阿拉伯几何图案,到斑斓的非洲编制艺术,这里有一整个图案的宇宙要学习。
![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png)
这章我们就结束算法绘图部分了。在接下来的章节,我们会学习如何把熵(其实就是混乱和随机的意思)加入到我们的着色器中来产生生成设计。

@ -0,0 +1,93 @@
# 生成设计
It is not a surprise that after so much repetition and order the author is forced to bring some chaos.
## 随机
[![Ryoji Ikeda - test pattern (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set)
Randomness is a maximal expression of entropy. How can we generate randomness inside the seemingly predictable and rigid code environment?
让我们从分析下面的函数着手:
<div class="simpleFunction" data="y = fract(sin(x)*1.0);"></div>
以上我们提取sin函数其波形的分数部分。[```sin()```](../glossary/?search=sin) 函数值在 ```-1.0``` 到 ```1.0``` 之间浮点分布,返回作业在 ```0.0``` 到 ```1.0``` 间的正值。(这里翻译有些奇怪)我们可以用这种效果通过把 [```sin(x)```](../glossary/?search=sin) 打散成小片段来得到一些伪随机数。如何实现乘以大些的sin值。在上面函数的相应位置加些0.
当你加到 ```100000.0``` (方程看起来是这样的:```y = fract(sin(x)*100000.0)``` 你再也区分不出sin波了。小数部分的粒度将sine的循环变成了伪随机的混沌。
## 控制混沌
使用随机会很难;它不是太混沌难测就是有时又不够混乱。看看下面的图例。要实现这样的效果,我们像之前描述的那样应用用 ```rand()``` 函数。
细看,你可以看到 [```sin()```](../glossary/?search=sin) 在 ```-1.5707``` 和 ```1.5707``` 到拐点。我打赌一定理解为什么——那就是sin最大值和最小值的地方。
如果你仔细观察随机分布,你会注意到相比边缘,中部更集中。
<div class="simpleFunction" data="y = rand(x);
//y = rand(x)*rand(x);
//y = sqrt(rand(x));
//y = pow(rand(x),5.);"></div>
不久前 [Pixelero](https://pixelero.wordpress.com) 出版了 [interesting article about random distribution](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/)。 我添加了些前几张图所有的函数来供你试验,看看如何改变分布。取消函数的注释,看看发生什么变化。
如果你读下 [Pixelero's article](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/),一定谨记我们用的 ```rand()``` 是确定性随机,也被称作是伪随机。这就意味着, 就 ```rand(1.)``` 为例,总会返回相同的值。[Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) 用 ActionSript 函数做了些参考,```Math.random()```,一个非确定性随机;每次调用都返回不同的值。
## 2D 随机
现在我们对随机有了深入的理解,是时候将它应用到二维,```x``` 轴和 ```y``` 轴。为此我们需要将一个二维向量转化为一维浮点数。这里有几种不同的方法来实现,但 [```dot()```](../glossary/?search=dot) 函数在这个例子中尤其有用。它根据两个向量的方向返回一个 ```0.0``` 到 ```1.0``` 之间的值。
<div class="codeAndCanvas" data="2d-random.frag"></div>
看下第13行和15行注意我们如何将 ```vec2 st``` 和另一个二维向量 ```vec2(12.9898,78.233)```)。
* 试着改变14和15行的值。看看随机图案的变化想想从中我们能学到什么。
* 好好用鼠标(```u_mouse```)和时间(```u_time```)调戏这个随机函数,更好的理解它如何工作。
## 使用混沌
二维的随机看起来是不是像电视的噪点?对组成图像来说,随机是个难用的原始素材。让我们来学着如何来利用它。
我们的第一步是在网格上的应用;用 [```floor()```](../glossary/?search=floor) 函数我们将会产生一个单元整数列表。看下下面的代码尤其是22行和23行。
<div class="codeAndCanvas" data="2d-random-mosaic.frag"></div>
在缩放空间10倍后在21行我们将坐标系统的整数和小数部分分离。我们对最后一步操作不陌生因为我们曾经用这种方法来将空间细分成 ```0.0``` 到 ```1.0``` 的小单元。我们根据得到坐标的整数部分作为一个通用值来隔离一个区域的像素,让它看起来像个单独的单元。然后我们可以用这个通用值来为这个区域得到一个随机值。因为我们的随机函数是伪随机,在那个单元内的所有像素返回的随机值都是一个常量。
取消第29行保留我们坐标的小数部分这样我们仍旧可以将其用作一个坐标系统来在单元内部画图形。
结合这两个量 — 坐标的整数部分和小数部分 — 将使你可以结合变化和秩序。
看下这个著名的 ```10 PRINT CHR$(205.5+RND(1)); : GOTO 10```迷宫生成器的GLSL代码块。
<div class="codeAndCanvas" data="2d-random-truchet.frag"></div>
这里我用前一章的 ```truchetPattern()``` 函数根据单元产生的随机值来随机画一个方向的对角线。
你可以通过取消50到53行的代码块的注释得到其他有趣的图案或者通过取消35和36行来得到图案的动画。
## 掌握随机
[Ryoji Ikeda](http://www.ryojiikeda.com/),日本电子作曲家、视觉艺术家,是运用随机的大师;他的作品是如此的富有感染力而难忘。他在音乐和视觉媒介中随机的运用,不再是混乱无序,反而以假乱真地折射出我们技术文化的复杂性。
<iframe src="https://player.vimeo.com/video/76813693?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
看看 [Ikeda](http://www.ryojiikeda.com/) 的作品并试试看下面的练习:
* 做按行随机移动的单元(以相反方向)。只显示亮一些的单元。让各行的速度随时间变化。
<a href="../edit.html#10/ikeda-00.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-00.frag" width="520px" height="200px"></canvas></a>
* 同样地,让某几行以不同的速度和方向。用鼠标位置关联显示单元的阀值。
<a href="../edit.html#10/ikeda-03.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-03.frag" width="520px" height="200px"></canvas></a>
* 创早其他有趣的效果。
<a href="../edit.html#10/ikeda-04.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-04.frag" width="520px" height="200px"></canvas></a>
优雅的使用随机是困难的,尤其是你希望创作自然的模拟。随机仅仅是过于混乱了,真实生活中很少有东西看上去如此 ```random()```。如果观察(玻璃床上)雨滴的肌理或是股票的曲线 — 这两个都挺随机的 — 但是他们和我们在章开始的随机图案看起来不是同一对爹妈生的。原因?嗯,随机值是没有因果关系的,而大多数自然图案(肌理)都对前一个状态有所记忆(基于前一个状态)。
下一章我们将学习噪波,一种光滑 和 *自然的* 创作计算机混沌的方式。

@ -1,2 +1,4 @@
https://docs.google.com/spreadsheets/d/194IVZR_xLVsw5H0zJZ7CWuimOQA_n8KU2eeIZBDwIH0/edit#gid=0
http://heman.readthedocs.org/en/latest/generate.html#archipelagos

@ -67,6 +67,12 @@ This could seam simple but the posibilities of modifing textures coordinates is
Now is your turn:
* Can you make a kaleidoscope using what we have learn?
* Way before Oculus or google cardboard, stereoscopic photography was a big thing. Could code a simple shader to re-use this beautiful images?
<a href=“../edit.html#10/ikeda-03.frag”><canvas id=“custom” class=“canvas” data-fragment-url=“ikeda-03.frag” width=“520px” height=“200px”></canvas></a>
* 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!

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

@ -0,0 +1,31 @@
// Author @patriciogv - 2015
// http://patriciogonzalezvivo.com
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D u_tex0;
uniform vec2 u_tex0Resolution;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
void main () {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec4 color = vec4(vec3(0.0),1.);
st *= vec2(.5,1.);
// st.x *= u_resolution.x/u_resolution.y;
float t = u_time*24.;
float pct = step(.75,abs(sin((st.x+t)*3.1415*10.)));
vec4 A = texture2D(u_tex0,st);
vec4 B = texture2D(u_tex0,st+vec2(.5,.0));
color = mix(A, B, abs(sin(t)));
gl_FragColor = color;
}

@ -3,8 +3,6 @@
# The Book of Shaders
*by [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)*
This is a gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.
这是一本关于 Fragment Shaders片段着色器的入门指南它将一步一步地带你领略其中的纷繁与抽象。
<div class="header">

@ -0,0 +1,98 @@
<canvas id="custom" class="canvas" data-fragment-url="examples/moon.frag" data-textures="examples/images/moon-texture.jpg" width="350px" height="350px"></canvas>
# The Book of Shaders
*by [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)*
이것은 황량하게 넓고 복잡한 Fragment Shader의 세계를 한단계씩 살펴보는 지침서입니다.
## 번역에 대하여
이 문서는 Patricio Gonzalez Vivo의 The Book of Shader의 한국어 번역입니다.
<div class="header">
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=B5FSVSHGEATCG" style="float: right;"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" alt=""></a>
</div>
## 차례
* [이 책에 대하여](00/)
* 시작하기 앞서
* [쉐이더란 무엇인가?](01/)
* [“헬로 월드!”](02/)
* [유니폼](03/)
* [쉐이더 실행하기](04/)
* Algorithmic drawing
* [모양 그리기](05/)
* [색에 대해](06/)
* [형태에 대해](07/)
* [행렬](08/)
* [패턴](09/)
* Generative designs
* [랜덤](10/)
* [노이즈](11/)
* Fractional brownian motion
* Fractals
* Image processing:
* Textures
* Image operations
* Kernel convolutions
* Filters
* Others effects
* Simulation
* Pingpong
* Conway
* Ripples
* Water color
* Reaction diffusion
* 3D graphics
* Lights
* Normal-maps
* Bump-maps
* Ray marching
* Environmental-maps (spherical and cube)
* Reflect and refract
* [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/)
* [How to run the examples on a RaspberryPi?](appendix/)
* [How to print this book?](appendix/)
* [Examples Gallery](examples/)
* [Glossary](glossary/)
## About the Author
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, 부에노스 아이레스, 아르헨티나) 는 뉴욕 기반의 아티스트 겸 개발자이다. 그는 유기적요소와 인공적요소, 아날로그와 디지털, 단일적요소와 집단적요소 사이를 탐험한다. 그는 사람들과 함께 개발하기위해 코드를 표현요소로 사용해 작업을 한다.
Patricio는 심리치료 및 표현예술을 공부했다. 그는 파슨스대학에서 디자인 및 기술 석사학위를 보유하고 있고 그곳에서 학생을 가르치고 있다. 또한 그는 현재 Mapzen에서 그래픽스 엔지니어로 맵을 만드는 오픈소스툴을 개발중에 있다.
<div class="header"><a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
## 감사의 표시
아내[Jen Lowe](http://www.datatelling.com/)의 끊임없는 격려과 이책에 대한 애정에 감사를 드립니다.
영감과 격려를 아끼지 않는 [Scott Murray](http://alignedleft.com/)에게 감사를 표합니다.
일본어 번역을 맡고 있는 [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) 와 [Sawako](https://twitter.com/sawakohome) 에게 감사를 표합니다. [Japanese translation (日本語訳)](?lan=jp)
중국어 번역을 맡고 있는 [Tong Li](https://www.facebook.com/tong.lee.9484) 와 [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) 에게 감사를 표합니다. [Chinese translation (中国的翻译)](?lan=ch)
한국어 번역을 맡고 있는 [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) 에게 감사를 표합니다. [Korean translation (한국어)](?lan=kr)
좋은 아이디어와 코드를 제공해주는 [Karim Naaji](http://karim.naaji.fr/) 에게 감사를 표합니다.
이 프로젝트를 격려해주시고 기부해주신 모든 분들께 감사를 드립니다. [contributed with fixes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors)
## 새로운 챕터 업데이트 받기
뉴스 업데이트를 위해 팔로우 해주세요. [follow it on Twitter](https://twitter.com/bookofshaders)
<form style="border:1px solid #ccc;padding:3px;text-align:center;" action="https://tinyletter.com/thebookofshaders" method="post" target="popupwindow" onsubmit="window.open('https://tinyletter.com/thebookofshaders', 'popupwindow', 'scrollbars=yes,width=800,height=600');return true"><a href="https://tinyletter.com/thebookofshaders"><p><label for="tlemail">Enter your email address</label></p></a><p><input type="text" style="width:140px" name="email" id="tlemail" /></p><input type="hidden" value="1" name="embed"/><input type="submit" value="Subscribe" /><p><a href="https://tinyletter.com" target="_blank"></a></p></form>

@ -79,7 +79,9 @@ Thanks [Scott Murray](http://alignedleft.com/) for the inspiration and advice.
Thanks [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) and [Sawako](https://twitter.com/sawakohome) for the [Japanese translation (日本語訳)](?lan=jp)
Thanks [Tong Li](https://www.facebook.com/tong.lee.9484) and [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) for the [Chinese translation (中国的翻译)](?lan=ch)
Thanks [Tong Li](https://www.facebook.com/tong.lee.9484) and [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) for the [Chinese translation (中文版)](?lan=ch)
Thanks [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) for the Korean [translation (한국어)](?lan=kr)
Thanks [Karim Naaji](http://karim.naaji.fr/) for contributing with support, good ideas and code.

@ -3,7 +3,7 @@
echo '
<div class="header">
<p><a href="http://thebookofshaders.com/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a> </p>
<p><a href=".">English</a> - <a href="?lan=jp">日本</a></p>
<p><a href=".">English</a> - <a href="?lan=jp">日本</a> - <a href="?lan=ch">中文版</a> - <a href="?lan=kr">한국어</a> </p>
</div>
<hr>
';

@ -2,218 +2,36 @@
<html>
<head>
<meta charset="utf-8">
<title>GLSL Shader Code Editor</title>
<!-- CodeMirror -->
<link type='text/css' rel='stylesheet' href="src/codemirror/css/codemirror.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/fold/foldgutter.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/dialog/dialog.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/hint/show-hint.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/theme/monokai.css">
<script type="text/javascript" src="src/codemirror.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/searchcursor.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/search.js"></script>
<script type="text/javascript" src="src/codemirror/addon/dialog/dialog.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/matchbrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/comment/comment.js"></script>
<script type="text/javascript" src="src/codemirror/addon/wrap/hardwrap.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/foldcode.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/brace-fold.js"></script>
<script type="text/javascript" src="src/codemirror/keymap/sublime.js"></script>
<script type="text/javascript" src="src/codemirror/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
<title>GLSL Editor</title>
<!-- GLSL Canvas -->
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
<style>
body {
height: 100%;
margin: 0;
background: #272822;
}
h1 {
color: white;
font-family: Courier, Arial;
}
pre {
font-size: 130%;
#glsl_editor {
height: 100%;
}
canvas.right {
position: fixed;
right: 10px;
top: 10px;
background-color: #fff;
border-radius: 15px;
overflow: hidden;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
.CodeMirror {
font-size: 110%;
line-height: 1.3;
right: 10px;
height: 100%;
}
.CodeMirror-linenumbers {
padding: 0 8px;
}
</style>
</head>
<body>
<h1 id="title" >FILE NAME.frag</h1>
<div id="editor"></div>
<canvas id="canvas" class="right" width="500" height="500"></canvas>
<script type="text/javascript">
window.addEventListener("hashchange", function () {
loadTag()
}, false);
var editor;
var billboard;
var imgs = [];
function fetchHTTP(url, methood){
var request = new XMLHttpRequest(), response;
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
response = request.responseText;
}
}
request.open(methood ? methood : 'GET', url, false);
request.overrideMimeType("text/plain");
request.send(null);
return response;
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
function loadTag(){
var fragShader = "";
var fragFile = "";
while(imgs.length > 0) {
imgs.pop();
}
removeElementsByClass("CodeMirror");
if( window.location.hash === "" ){
fragShader = "#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
\n\
uniform vec2 u_resolution;\n\
uniform vec2 u_mouse;\n\
uniform float u_time;\n\
\n\
void main(){\n\
vec2 st = gl_FragCoord.xy/u_resolution.xy;\n\
gl_FragColor = vec4(st.x,st.y,0.0,1.0);\n\
}";
} else {
var hashes = location.hash.split('&');
for(i in hashes){
var ext = hashes[i].substr(hashes[i].lastIndexOf('.') + 1);
var name = hashes[i];
// Extract hash if is present
if(name.search("#") === 0){
name = name.substr(1);
}
if(ext == "frag"){
fragFile = name;
fragShader = fetchHTTP(fragFile);
} else if (ext == "png" || ext == "jpg" || ext == "PNG" || ext == "JPG" ){
imgs.push(hashes[i]);
}
}
}
var demoTitle = document.getElementById("title");
if(demoTitle){
demoTitle.innerText = fragFile;
}
var demoCanvas = document.getElementById("canvas");
if (demoCanvas && fragShader !== "") {
demoCanvas.setAttribute("data-fragment-url", fragFile);
if (imgs.length > 0) {
var textureList = "";
for (i in imgs) {
textureList += imgs[i];
textureList += (i < imgs.length-1)?",":"";
}
demoCanvas.setAttribute("data-textures",textureList);
console.log("data-textures: " + textureList);
}
billboard = new GlslCanvas(demoCanvas);
}
var demoEditor = document.getElementById("editor");
if (demoEditor) {
editor = CodeMirror(demoEditor,{
value: fragShader,
lineNumbers: true,
matchBrackets: true,
mode: "x-shader/x-fragment",
keyMap: "sublime",
autoCloseBrackets: true,
extraKeys: {"Ctrl-Space": "autocomplete"},
showCursorWhenSelecting: true,
theme: "monokai",
indentUnit: 4
});
editor.on("change", function() {
demoCanvas.setAttribute("data-fragment", editor.getValue());
billboard.load(editor.getValue());
});
}
}
window.onload = function () {
loadTag();
render();
};
function render() {
billboard.setMouse(mouse)
billboard.render()
window.requestAnimFrame(render);
}
</script>
<div id="glsl_editor"></div>
</body>
<link type="text/css" rel="stylesheet" href="https://rawgit.com/patriciogonzalezvivo/glslEditor/gh-pages/build/css/main.css">
<script type="application/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslEditor/gh-pages/build/js/glslEditor.js"></script>
<script type="text/javascript">
window.glslEditor = new GlslEditor('#glsl_editor', {
viewSize: 500,
theme: 'monokai',
multipleBuffers: true,
watchHash: true,
fileDrops: true,
menu: true
});
</script>
</html>

@ -156,21 +156,14 @@ void main(){\n\
};
})();
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
window.addEventListener("hashchange", function () {
loadFunction()
}, false);
// window.onresize = function(event) {
// if (typeof window.innerWidth != 'undefined') {
// billboard. = window.innerWidth
// };
window.onresize = function(event) {
if (typeof window.innerWidth != 'undefined') {
billboard. = window.innerWidth
};
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
@ -231,15 +224,8 @@ float function(in float x) {\n\
}
}
function render() {
billboard.setMouse(mouse)
billboard.render()
window.requestAnimFrame(render);
}
window.onload = function () {
loadFunction();
render();
};
</script>
</body>

@ -1,5 +1,6 @@
<?php
$path = ".";
$subtitle = "";
$README = "README";
$language = "";

@ -280,15 +280,6 @@ function loadCanvas() {
}
}
function renderCanvas() {
var IDs = Object.keys(billboards);
for(var i = 0; i < IDs.length; i++){
billboards[IDs[i]].setMouse(mouse);
billboards[IDs[i]].render();
}
window.requestAnimFrame(renderCanvas);
}
function insertAfter(newElement,targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
@ -403,13 +394,6 @@ function translate() {
}
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
/**
* Provides requestAnimationFrame in a cross browser way.
*/
@ -441,5 +425,4 @@ window.onload = function(){
captionizeImages();
loadCanvas();
renderCanvas();
};

Loading…
Cancel
Save