├── README.md ├── Shader ├── 001_helloWorld │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 002_gradual │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 003_line │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 004_square │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 005_circle │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 006_drawGraph │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 007_SharpEdgesAura │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 008_fancyGraph │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 009_fancyGear │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 010_matrix │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 011_splitGrid │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 012_splitGrid_animation │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 013_noise │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 014_ripple │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 015_floridRipple │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 016_cell │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 017_distanceField_2D │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 018_rayMarching │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 019_sea2D │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs └── common │ ├── head.html │ └── head.js ├── ShaderToyCollect ├── 001_coloursWave │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs ├── 002_HappyJumping │ ├── fragmentShader.fs │ ├── index.html │ └── vertexShader.vs └── common │ ├── head.html │ └── head.js ├── index.html └── js ├── ShaderMgr.js ├── stats.min.js └── three.min.js /README.md: -------------------------------------------------------------------------------- 1 | # ThreeJS-Shader 2 | 基于WebGL的Three.js 的Shader,记录学习GLSL过程中的一些特效demo. 3 | 4 | 可以直接阅读源码, 里面有详细注释, 从最简单的绘制线条到各种炫酷的特效,逐渐深入学习Shader! 5 | 6 | 如果直接运行index.html 文件出现跨域问题需自行处理。 7 | 8 | ## 001_Hello World:第一个shader程序! 9 | 10 | 第一个WebGL shader程序!使用three.js简单构建了一个基于WebGL的shader程序, 可以直接在浏览器运行预览,可以看到整个屏幕呈现红色的闪烁效果。 11 | 12 | ![quicker_d7956ac8-594d-4935-80e8-7090a90bb0b4.png](https://i.loli.net/2020/08/21/ktAd6waycTUnQvD.png) 13 | 14 | ## 002_gradual:渐变色 15 | 16 | 在开始这个程序之前,我封装了一个Shader Manager模块用来管理Shader,以便于后续的Shader编写。 17 | 这个shader也比较简单,根据uv坐标显示不同的颜色,来达到渐变效果。 18 | 19 | ![quicker_fc0e319b-cf1b-4fe3-8e95-ef01746d79d9.png](https://i.loli.net/2020/08/21/T7VYXe6CGQrNijW.png) 20 | 21 | ## 003_line:绘制了直线,曲线。 22 | 该shader展示了如何绘制线条,如直线、smoothstep曲线、正弦曲线等等。 23 | 24 | ![quicker_52ea6fa3-c3e5-42d9-a1c0-310482407753.png](https://i.loli.net/2020/08/21/rJAUwdcmvEi4VSP.png) 25 | 26 | ## 004_square:绘制正方形。 27 | 该shader展示了如何绘制一个彩色正方形。 28 | 29 | ![quicker_71aaa85e-2de8-4c95-970d-f246de9b7bdf.png](https://i.loli.net/2020/08/21/WDe2RHh5NLvjwiC.png) 30 | 31 | ## 005_circle:绘制圆形。 32 | 该shader展示了如何绘制圆形,并且通过不同的方式叠加造成一些奇特的特效。例如:绘制多个圆,两个圆相吸、融合效果,两圆相交(可以用该思路实现遮罩效果)等效果。 33 | 34 | ![quicker_d5a3c346-c76d-43d0-a30a-71391b9791ff.png](https://i.loli.net/2020/08/21/NpAlj8ukFJi5tdT.png) 35 | 36 | ## 006_drawGraph:绘制各种图案。 37 | 结合不同的【造型函数】绘制各式各样的图案,这里展示了圆、圆环、花瓣、齿轮、风车、水滴等图形,并且可以结合时间变量【u_time】使其运动。 38 | 可以自己拓展【造型函数】来绘制自己想要的图案。 39 | 40 | ![graph.gif](https://i.loli.net/2020/08/21/7ELziWqHIgTwuOm.gif) 41 | 42 | ## 007_SharpEdgesAura:尖刃光环 43 | 44 | ![quicker_862bb5a4-16de-4c32-ae6a-fd2ec345238b.png](https://i.loli.net/2020/08/21/Zv3D6hJXQPzTKM1.png) 45 | 46 | ## 008_fancyGraph:结合自定义造型函数绘制炫丽的图形。 47 | 一个小练习,绘制了一个不断变换的图形. 48 | 49 | ![fancy.gif](https://i.loli.net/2020/08/21/khzuIastUYMZgDp.gif) 50 | 51 | ## 009_fancyGear:炫丽的小齿轮。 52 | 一个小练习,绘制了一些不断变换运动的彩色小齿轮. 53 | 54 | ![gear.gif](https://i.loli.net/2020/08/21/gyp4CfoLOSjxsvH.gif) 55 | 56 | ## 010_matrix: 变换矩阵的运用 57 | 58 | 旋转: 59 | 60 | ![matrix.gif](https://i.loli.net/2020/08/21/fKBnOmXSNchxlGu.gif) 61 | 62 | ## 011_splitGrid:切割/平铺图案。 63 | 64 | ![quicker_a61af6d8-a3eb-4869-b2d9-88a39129f950.png](https://i.loli.net/2020/08/21/TejqSrUxHb5QI3D.png) 65 | 66 | ## 012_splitGrid_animation:平铺图案一个动画demo。 67 | 68 | ![splitGrid.gif](https://i.loli.net/2020/08/21/tRlQMgvDbcpBdez.gif) 69 | 70 | ## 013_noise: 噪声的应用。 71 | 72 | ![noise.gif](https://i.loli.net/2020/08/21/8vglD4UNtfoBSTJ.gif) 73 | 74 | ## 014_ripple:波纹动画 75 | 76 | ![ripple.gif](https://i.loli.net/2020/08/21/htmTLBDz3ZwAoej.gif) 77 | 78 | ## 015_floridRipple: 炫丽的波纹 + 噪声 79 | 80 | ![florid.gif](https://i.loli.net/2020/08/21/bQAqHBows7ykDVv.gif) 81 | 82 | ## 016_cell: 细胞(距离场的运用) 83 | 84 | ![cell.gif](https://i.loli.net/2020/08/21/5wYfmljr3yuMndI.gif) 85 | 86 | ## 017_distanceField_2D: 桃心函数 87 | 88 | ![quicker_3a3e5446-8dbd-47fb-b247-94fef82ae667.png](https://i.loli.net/2020/08/21/OM81xpmD26nXhTw.png) 89 | 90 | ## 018_rayMarching: 光线行进 绘制 3D 物体 91 | 92 | ![3Dbox.gif](https://i.loli.net/2020/08/21/WzX9EYKUnOCGPLd.gif) 93 | 94 | ## 019_sea2D: 2D 海洋 95 | 96 | ![sea.gif](https://i.loli.net/2020/08/21/yR35WwkshUHQLt9.gif) -------------------------------------------------------------------------------- /Shader/001_helloWorld/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-13 17:26 3 | // Title:第一个GLSH demo 4 | // ------------------------------【片元着色器】---------------------------- 5 | // uniform 统一变量:由js传递过来 6 | uniform float u_time; 7 | 8 | void main() { 9 | // 输出 10 | // 片元颜色 11 | gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0); 12 | } -------------------------------------------------------------------------------- /Shader/001_helloWorld/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 17 | -------------------------------------------------------------------------------- /Shader/001_helloWorld/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 17:26 3 | // 第一个GLSH demo 4 | 5 | // ------------------------------【顶点着色器】---------------------------- 6 | void main() { 7 | // 顶点坐标 8 | gl_Position = vec4( position, 1.0 ); 9 | } -------------------------------------------------------------------------------- /Shader/002_gradual/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-13 17:36 3 | // Title:渐变色 4 | // ------------------------------【片元着色器】---------------------------- 5 | #ifdef GL_ES 6 | precision mediump float; 7 | #endif 8 | //-------- uniform 变量, 由js传递过来------ 9 | // 屏幕尺寸 10 | uniform vec2 u_resolution; 11 | 12 | // 13 | void main() { 14 | // uv坐标 15 | vec2 uv = gl_FragCoord.xy/u_resolution; 16 | // 输出 17 | gl_FragColor = vec4(uv.x,uv.y,0.0,1.0); 18 | } -------------------------------------------------------------------------------- /Shader/002_gradual/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 18 | -------------------------------------------------------------------------------- /Shader/002_gradual/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 17:36 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | 6 | void main() { 7 | gl_Position = vec4( position, 1.0 ); 8 | } -------------------------------------------------------------------------------- /Shader/003_line/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | // Title:绘制直线 曲线 正弦波 4 | // ------------------------------【片元着色器】---------------------------- 5 | 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | //-------- uniform 变量------ 10 | // 屏幕大小 11 | uniform vec2 u_resolution; 12 | 13 | uniform float u_time; 14 | 15 | vec3 colorA = vec3(1.000,0.0,0.000); 16 | vec3 colorB = vec3(0.000,0.000,1.0); 17 | 18 | // 线的颜色 19 | vec3 lineColor = vec3(0.985,0.841,0.090); 20 | // 线宽度 21 | float lineWidth = 0.005; 22 | 23 | // 直线 24 | float line(float x){ 25 | return 1.000 * x + 0.0; 26 | } 27 | 28 | //正弦波函数 29 | float sineWave(float x){ 30 | //频率 31 | float frequency = 10.0; 32 | //震幅 33 | float amplitude = 0.2; 34 | return sin(x * frequency + u_time) * amplitude + 0.5; 35 | } 36 | 37 | void main() { 38 | // gl_FragCoord: 当前像素坐标 39 | // 对坐标进行规范化,把坐标控制在[0,1]范围. 40 | vec2 uv = gl_FragCoord.xy/u_resolution; 41 | 42 | //直线方程 43 | float y = line(uv.x); 44 | 45 | //取消注释: smoothstep曲线 46 | // y = smoothstep(0.0, 1.0,uv.x ); 47 | 48 | //取消注释:正弦波 49 | // y = sineWave(uv.x ); 50 | 51 | 52 | // 阙值, 判断该像素是否属于线: 0为线 , 1为背景 53 | float threshold = step(lineWidth, abs(y-uv.y)); 54 | // 线的颜色 55 | vec3 _lineColor = lineColor * ( 1.0 - threshold ); 56 | // 背景色, 里面mix混合两种颜色,类似插值, y是控制变量 57 | vec3 color = mix(colorA, colorB, y) * threshold; 58 | // 输出 59 | gl_FragColor = vec4(vec3(color + _lineColor ),1); 60 | } -------------------------------------------------------------------------------- /Shader/003_line/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 14 | -------------------------------------------------------------------------------- /Shader/003_line/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/004_square/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-14 22:00 3 | // Title:绘制正方形 4 | // ------------------------------【片元着色器】---------------------------- 5 | 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | 10 | uniform vec2 u_resolution; 11 | uniform vec2 u_mouse; 12 | uniform float u_time; 13 | // hsb 转 rgb 14 | vec3 hsb2rgb( in vec3 c ){ 15 | vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,0.0,1.0 ); 16 | rgb = rgb*rgb*(3.0-2.0*rgb); 17 | return c.z * mix( vec3(1.0), rgb, c.y); 18 | } 19 | 20 | void main(){ 21 | // uv坐标 22 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 23 | // 24 | vec3 color = vec3(0.); 25 | // 边长 - width 26 | float width = 0.356; 27 | 28 | // 左下两条边 - bottom-left 29 | vec2 bl = step(vec2(width),uv); 30 | float pct = bl.x * bl.y; 31 | 32 | // 右上两条边 - top-right 33 | vec2 tr = step(vec2(width),1.0-uv); 34 | pct *= tr.x * tr.y; 35 | // 颜色根据x变化, 这里用到了hsb2rgb函数 把hsb值转换为rgb值 36 | color = vec3(pct) * hsb2rgb(vec3( uv.x*2., 1.,1. )); 37 | // 输出 38 | gl_FragColor = vec4(color,1.0); 39 | } -------------------------------------------------------------------------------- /Shader/004_square/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/004_square/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/005_circle/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | // Title:绘制圆 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | //-------- uniform 变量------ 10 | // 屏幕大小 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | 14 | vec2 shakeAnimate(vec2 p,float cycle){ 15 | // animate 16 | float tt = mod(u_time, cycle) / cycle; 17 | float ss = 1.0 + 0.5 * sin(tt * 3.1415926 * 6.0 + p.y * 0.5) * exp(-tt * 4.0); 18 | vec2 res = p*vec2(0.7, 1.5) + ss * vec2(0.3, -0.5); 19 | return res; 20 | } 21 | 22 | void main() { 23 | // gl_FragCoord: 当前像素坐标 24 | // 用 gl_FragCoord.xy 除以 u_resolution,对坐标进行了规范化。 25 | // 这样做是为了使所有的值都在 0.0 到 1.0 之间。 26 | vec2 uv = gl_FragCoord.xy/u_resolution; 27 | // vec2 uv = (2.0*gl_FragCoord.xy - u_resolution.xy)/u_resolution.y; 28 | // vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / min(u_resolution.y, u_resolution.x); 29 | 30 | vec3 bcol = vec3(0.29412, 0.70196, 0.63921) * (1.0 - 0.3 * length(uv)); 31 | //半径 32 | float radius = 0.2; 33 | 34 | // 一个圆 35 | float pct = distance(vec2(0.5,0.5),uv); 36 | // -----------可以一步一步的取消下面注释,看看效果,不同的方式叠加,造成不同的效果--------------- 37 | //椭圆 38 | // pct = distance(uv,vec2(0.470,0.600)) + distance(uv,vec2(0.570,0.540)); 39 | //两个圆相吸 40 | // pct = distance(uv,vec2(0.550,0.520)) * distance(uv,vec2(0.010,0.040)); 41 | //两个圆 42 | // pct = min(distance(uv,vec2(0.140,0.130)),distance(uv,vec2(0.660,0.600))); 43 | //两个圆相交部分 - 可以用来做遮罩 44 | // pct = max(distance(uv,vec2(0.550,0.590)),distance(uv,vec2(0.6))); 45 | //不知道怎么描述 46 | // pct = pow(distance(uv,vec2(0.350,0.450)),distance(uv,vec2(-0.490,0.360))); 47 | 48 | // ----------------------------------------- 49 | 50 | // smoothstep 平滑过渡 51 | float col = smoothstep(radius + 0.008,radius,pct ) ; 52 | 53 | gl_FragColor = vec4(vec3(col+bcol),1); 54 | } -------------------------------------------------------------------------------- /Shader/005_circle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/005_circle/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/006_drawGraph/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | 2 | // Author: 长生但酒狂 3 | // create time : 2019-12-15 4 | // Title:结合不同的【造型函数】 绘制图案, 并且封装成函数,可以绘制多个、实现遮罩等效果 5 | 6 | // ------------------------------【片元着色器】---------------------------- 7 | #ifdef GL_ES 8 | precision mediump float; 9 | #endif 10 | 11 | uniform vec2 u_resolution; 12 | uniform vec2 u_mouse; 13 | uniform float u_time; 14 | 15 | // hsb 转 rgb 16 | vec3 hsb2rgb( in vec3 c ){ 17 | vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,0.0,1.0 ); 18 | rgb = rgb*rgb*(3.0-2.0*rgb); 19 | return c.z * mix( vec3(1.0), rgb, c.y); 20 | } 21 | 22 | // 圆 23 | vec3 createCircle(vec2 pos,float radius,vec2 uv){ 24 | float pct = distance(pos,uv); 25 | // smoothstep 平滑过渡 26 | return vec3(smoothstep(radius + 0.008,radius,pct )) ; 27 | } 28 | // 圆环,其实就是两个圆相减 29 | vec3 createAnnulus(vec2 pos,float radius,float width,vec2 uv){ 30 | float dis = distance(pos,uv); 31 | float col = smoothstep(radius, radius+0.010,dis) - smoothstep(radius+width, radius+width+0.010,dis); 32 | return vec3(col); 33 | } 34 | 35 | // 花瓣 36 | vec3 createPetal(vec2 pos,float scale,vec2 uv){ 37 | vec2 dir = pos - uv; 38 | // 转换为极坐标 39 | float radius = length(dir)*scale; 40 | float angle = atan(dir.y,dir.x); 41 | //造型函数 42 | float f = abs(cos(angle*2.5))*.5+.3; 43 | return vec3( 1.-smoothstep(f,f+0.02,radius)); 44 | } 45 | // 水滴 46 | vec3 createWaterDrop(vec2 pos,float scale,vec2 uv){ 47 | vec2 dir = pos - uv; 48 | // 转换为极坐标 49 | float radius = length(dir)*scale; 50 | float angle = atan(dir.y,dir.x); 51 | //造型函数 52 | float f = 1.0 - pow(abs(angle+-1.548),2.416); 53 | return vec3( 1.-smoothstep(f,f+0.02,radius)); 54 | } 55 | 56 | // 风车 57 | vec3 createWindmill(vec2 pos,float scale,vec2 uv){ 58 | vec2 dir = pos-uv; 59 | // 转换为极坐标 60 | float radius = length(dir)*scale; 61 | float angle = atan(dir.y,dir.x); 62 | //造型函数 63 | float f = fract(angle*1.273 + u_time)*0.956; 64 | return vec3( 1.-smoothstep(f,f+0.092,radius) ); 65 | } 66 | 67 | // 齿轮 68 | vec3 createGear(vec2 pos,float scale,vec2 uv){ 69 | vec2 dir = pos - uv; 70 | // 转换为极坐标 71 | float radius = length(dir)*scale; 72 | float angle = atan(dir.y,dir.x); 73 | //造型函数 74 | float f = smoothstep(-0.484,1., cos(angle*10.0+u_time))*0.080+0.372; 75 | 76 | return vec3( 1.-smoothstep(f,f+0.02,radius)); 77 | } 78 | // 创建... 79 | vec3 createD(vec2 pos,float scale,vec2 uv){ 80 | vec2 dir = pos - uv; 81 | // 转换为极坐标 82 | float radius = length(dir)*scale; 83 | float angle = atan(dir.y,dir.x); 84 | //造型函数 85 | float f = abs(cos(angle*13.136)*sin(angle*3.))*.8+.1; 86 | return vec3( 1.-smoothstep(f,f+0.02,radius)); 87 | } 88 | 89 | void main(){ 90 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 91 | 92 | vec3 color = createGear(vec2(0.800,0.480),5.0,uv); 93 | vec3 color1 = createD(vec2(0.310,0.630),5.0,uv); 94 | vec3 color2 = createCircle(vec2(0.500,0.450),0.072,uv); 95 | vec3 color3 = createPetal(vec2(0.280,0.220),5.352,uv); 96 | vec3 color4 = createWindmill(vec2(0.630,0.790),5.352,uv); 97 | vec3 color5 = createWaterDrop(vec2(0.820,0.250),5.352,uv); 98 | 99 | // color = color * hsb2rgb(vec3(0.541,1.117,0.353)); 100 | 101 | //注意这里: 102 | //"+" 代表 "||(或者)" 的意思, 即 color1 + color2 代表 只要该像素在color1或者color2其中一个上,就显示,否则不显示。【显示多个】 103 | //"-" 代表 "与非 " 的意思, 即 color1 - color2 代表 如果该像素在color1上,并且不在color2上,则显示,否则不显示。【color1减掉color2区域颜色】 104 | //"*" 代表 "&&(与)" 的意思, 即 color1 * color2 代表 如果该像素在既在color1上又在color2上,就显示,否则不显示。 【遮罩效果】 105 | gl_FragColor = vec4(color+color1+color2+color3+color4+color5, 1.0); 106 | } 107 | -------------------------------------------------------------------------------- /Shader/006_drawGraph/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/006_drawGraph/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/007_SharpEdgesAura/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | 2 | // Author: 长生但酒狂 3 | // create time : 2019-12-16 4 | // Title:尖刃光环 5 | 6 | // ------------------------------【片元着色器】---------------------------- 7 | #ifdef GL_ES 8 | precision mediump float; 9 | #endif 10 | 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | 14 | // 圆环 15 | vec3 createAnnulus(vec2 pos,float radius,float width,vec2 uv){ 16 | float dis = distance(pos,uv); 17 | float col = smoothstep(radius, radius+0.010,dis) - smoothstep(radius+width, radius+width+0.010,dis); 18 | return vec3(col); 19 | } 20 | 21 | void main(void){ 22 | vec2 p = (3.0*gl_FragCoord.xy-u_resolution.xy)/min(u_resolution.y,u_resolution.x); 23 | 24 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 25 | uv.x *= u_resolution.x/u_resolution.y; 26 | 27 | vec3 color = vec3(0.0); 28 | 29 | vec2 center = vec2(0.500,0.500); 30 | float radius = 0.308;//半径 31 | float width = 0.012;//圆环宽度 32 | float gap = 1.392; //尾部缺口 33 | 34 | //尾部缺口 35 | //上方向向量 36 | vec2 upDir = normalize(vec2(0.5,1.) - center); 37 | //当前向量 38 | vec2 currentDir = normalize(uv - center); 39 | //角度 40 | float angle = dot(upDir,currentDir); 41 | float tailRang = smoothstep(gap,gap+0.284,angle); 42 | float s = (1. - pow(abs(angle),1.)); 43 | width = width * s ; 44 | //圆环 45 | vec3 col = createAnnulus(center,radius,width,uv); 46 | 47 | gl_FragColor = vec4(vec3(col),1.0); 48 | } 49 | -------------------------------------------------------------------------------- /Shader/007_SharpEdgesAura/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/007_SharpEdgesAura/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/008_fancyGraph/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-16 3 | // Title:练习: 结合造型函数绘制炫丽的图形 4 | 5 | #ifdef GL_ES 6 | precision mediump float; 7 | #endif 8 | 9 | uniform vec2 u_resolution; 10 | uniform vec2 u_mouse; 11 | uniform float u_time; 12 | 13 | vec3 hsb2rgb( in vec3 c ){ 14 | vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,0.0,1.0 ); 15 | rgb = rgb*rgb*(3.0-2.0*rgb); 16 | return c.z * mix( vec3(1.0), rgb, c.y); 17 | } 18 | 19 | vec2 tile(vec2 _st, float _zoom){ 20 | _st *= _zoom; 21 | return fract(_st); 22 | } 23 | 24 | void main() 25 | { 26 | // Normalized pixel coordinates (from 0 to 1) 27 | vec2 uv = gl_FragCoord.xy / u_resolution.xy; 28 | uv = tile(uv,3.); 29 | //width height ratio 30 | float ratio = u_resolution.x/u_resolution.y; 31 | 32 | vec3 color = vec3(0.0); 33 | 34 | vec2 pos = vec2(0.5)-uv; 35 | float radius = length(pos)*2.0; 36 | float angle = atan(pos.y,pos.x); 37 | 38 | float f1 = fract(angle*1.376+u_time)*0.8; 39 | float f2 = fract(angle*2.408+u_time)*0.8; 40 | float f = f1*f2; 41 | 42 | color = vec3( 1.-smoothstep(f,f+0.02,radius) ); 43 | 44 | color = color * hsb2rgb(vec3((f+u_time),1.,1.000)); 45 | 46 | gl_FragColor = vec4(color, 1.0); 47 | } 48 | -------------------------------------------------------------------------------- /Shader/008_fancyGraph/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/008_fancyGraph/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/009_fancyGear/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-17 3 | // Title:炫丽的小齿轮 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | 7 | #ifdef GL_ES 8 | precision mediump float; 9 | #endif 10 | 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | 14 | vec3 hsb2rgb( in vec3 c ){ 15 | vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,0.0,1.0 ); 16 | rgb = rgb*rgb*(3.0-2.0*rgb); 17 | return c.z * mix( vec3(1.0), rgb, c.y); 18 | } 19 | 20 | // 创建齿轮 21 | vec3 createGear(vec2 pos,float scale,vec2 uv){ 22 | vec2 dir = pos - uv; 23 | float radius = length(dir)*scale; 24 | float angle = atan(dir.y,dir.x); 25 | //造型函数 26 | float f = smoothstep(-0.484,1., cos(angle*10.0+u_time*50.))*0.080+0.372; 27 | 28 | vec3 col = hsb2rgb(vec3((pos.y),1.000,1.0)); 29 | 30 | return vec3( 1.-smoothstep(f,f+0.02,radius)) *col; 31 | } 32 | 33 | 34 | // 35 | void main(){ 36 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 37 | // uv.x *= u_resolution.x/u_resolution.y; 38 | 39 | vec3 gearleLists = vec3(0.014,0.054,0.210); 40 | gearleLists = vec3(0.014,0.054,0.210); 41 | float spaceX = 0.; 42 | float spaceY = 0.; 43 | 44 | float speedX = 0.3; 45 | float speedY = 0.1; 46 | float size = 25.0; 47 | for(int i = 0;i<31;i ++){ 48 | spaceX += 0.1; 49 | spaceY += 0.1; 50 | vec2 pos = vec2(spaceX,spaceY); 51 | pos.x = abs(sin(speedX*u_time+spaceX)); 52 | pos.y = abs(cos(speedY*u_time+spaceY)); 53 | vec3 gear = createGear(pos,size,uv); 54 | gearleLists += gear; 55 | } 56 | 57 | gl_FragColor = vec4(gearleLists , 1.0); 58 | } 59 | -------------------------------------------------------------------------------- /Shader/009_fancyGear/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/009_fancyGear/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/010_matrix/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-18 3 | // Title:常用变换矩阵 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | 7 | #ifdef GL_ES 8 | precision mediump float; 9 | #endif 10 | 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | 14 | 15 | // 花瓣 16 | vec3 createPetal(vec2 pos,float scale,vec2 uv){ 17 | vec2 dir = pos - uv; 18 | float radius = length(dir)*scale; 19 | float angle = atan(dir.y,dir.x); 20 | //造型函数 21 | float f = abs(cos(angle*2.5))*.5+.3; 22 | return vec3( 1.-smoothstep(f,f+0.02,radius)); 23 | } 24 | 25 | 26 | // 旋转 27 | mat2 rotate2d(float _angle){ 28 | return mat2( 29 | cos(_angle),-sin(_angle), 30 | sin(_angle),cos(_angle) 31 | ); 32 | } 33 | 34 | // 缩放 35 | mat2 scale2d(float _scale){ 36 | return mat2( 37 | _scale,0., 38 | 0.,_scale 39 | ); 40 | } 41 | 42 | // // 平移 43 | // mat3 translate2d(vec2 pos){ 44 | // return mat3( 45 | // 1.,0.,pos.x, 46 | // 0.,1.,pos.y, 47 | // 0.,0.,1. 48 | // ); 49 | // } 50 | 51 | void main(void){ 52 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 53 | uv.x *= u_resolution.x/u_resolution.y; 54 | 55 | //旋转之前 偏移到圆点 56 | uv -= vec2(0.5); 57 | //旋转 58 | uv = rotate2d(u_time) * uv; 59 | //旋转之后偏移回原位 60 | uv += vec2(0.5); 61 | 62 | //花瓣 63 | vec3 color = createPetal(vec2(0.5,0.5 ),5.,uv); 64 | 65 | gl_FragColor = vec4(vec3(color),1.0); 66 | } -------------------------------------------------------------------------------- /Shader/010_matrix/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/010_matrix/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/011_splitGrid/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-18 3 | // Title:分割网格 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | 10 | uniform vec2 u_resolution; 11 | uniform float u_time; 12 | 13 | void main(void){ 14 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 15 | uv.x *= u_resolution.x/u_resolution.y; 16 | 17 | //放大3倍 18 | uv *= 3.; 19 | //取小数, 实际上就是分成了 3 组 [0 - 1]的浮点数 20 | vec2 f_uv = fract(uv); 21 | //3x3 的网格 22 | vec3 color = vec3(f_uv.x,f_uv.y,0.); 23 | 24 | gl_FragColor = vec4(color,1.0); 25 | } -------------------------------------------------------------------------------- /Shader/011_splitGrid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/011_splitGrid/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/012_splitGrid_animation/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-18 3 | // Title:切割(平铺)格子 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | 7 | #ifdef GL_ES 8 | precision mediump float; 9 | #endif 10 | 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | 14 | // 分割格子 - Split the grid 15 | vec2 splitGrid(vec2 _uv, float _zoom,float speed){ 16 | _uv *= _zoom; 17 | 18 | float time = u_time * speed; 19 | // 是否该行运动,否则列运动 20 | float isRow = step(0.5,fract(time)); 21 | 22 | // 每行的动作 - row action 23 | //单数行的运动 24 | _uv.x += step(1., mod(_uv.y,2.0)) * u_time * isRow; 25 | //双数行的运动 26 | _uv.x += step( mod(_uv.y,2.0),1.) * -u_time * isRow; 27 | 28 | // 每列的动作 - col action 29 | _uv.y += step(1., mod(_uv.x,2.)) * u_time * (1. - isRow); 30 | _uv.y += step( mod(_uv.x,2.),1.) * -u_time * (1. - isRow); 31 | 32 | return fract(_uv); 33 | } 34 | 35 | //创建圆 - creator circle 36 | vec3 createCircle(vec2 pos,float radius,vec2 uv){ 37 | float pct = distance(pos,uv); 38 | // 平滑过渡 - smoothstep 39 | return vec3(smoothstep(radius + 0.040,radius,pct )) ; 40 | } 41 | 42 | void main(void){ 43 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 44 | uv.x *= u_resolution.x/u_resolution.y; 45 | 46 | vec3 color = vec3(0.0); 47 | 48 | // 分割格子 - Split the grid 49 | uv = splitGrid(uv,10.0,0.5); 50 | 51 | //创建圆 - creator circle 52 | color = vec3(createCircle(vec2(0.5),0.4,uv)); 53 | 54 | 55 | gl_FragColor = vec4(color,1.0); 56 | } -------------------------------------------------------------------------------- /Shader/012_splitGrid_animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/012_splitGrid_animation/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/013_noise/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-20 3 | // Title:噪声 - 变换的墨水滴 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | 10 | uniform vec2 u_resolution; 11 | uniform vec2 u_mouse; 12 | uniform float u_time; 13 | 14 | vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } 15 | vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } 16 | vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } 17 | // Simplex Noise - 单纯形噪声 18 | float snoise(vec2 v) { 19 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 20 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 21 | -0.577350269189626, // -1.0 + 2.0 * C.x 22 | 0.024390243902439); // 1.0 / 41.0 23 | vec2 i = floor(v + dot(v, C.yy) ); 24 | vec2 x0 = v - i + dot(i, C.xx); 25 | vec2 i1; 26 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 27 | vec4 x12 = x0.xyxy + C.xxzz; 28 | x12.xy -= i1; 29 | i = mod289(i); // Avoid truncation effects in permutation 30 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 31 | + i.x + vec3(0.0, i1.x, 1.0 )); 32 | 33 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 34 | m = m*m ; 35 | m = m*m ; 36 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 37 | vec3 h = abs(x) - 0.5; 38 | vec3 ox = floor(x + 0.5); 39 | vec3 a0 = x - ox; 40 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 41 | vec3 g; 42 | g.x = a0.x * x0.x + h.x * x0.y; 43 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 44 | return 130.0 * dot(m, g); 45 | } 46 | 47 | 48 | void main() { 49 | vec2 st = gl_FragCoord.xy/u_resolution.xy; 50 | st.x *= u_resolution.x/u_resolution.y; 51 | 52 | st *= 4.0 ; 53 | vec3 color = vec3(0.); 54 | //自由度 55 | float DF = 0.0; 56 | //变化速度 57 | float speed = 0.236; 58 | // 这里其实就是一个运动 加上一个静止的点 就形成了不断溶解的点 59 | DF += snoise(st+u_time*speed)+snoise(st); 60 | 61 | color = vec3(smoothstep(0.5,0.62,DF)); 62 | //取反 63 | gl_FragColor = vec4(1. - color,1.0); 64 | } -------------------------------------------------------------------------------- /Shader/013_noise/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/013_noise/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/014_ripple/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-21 3 | // Title:波纹 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | 10 | uniform vec2 u_resolution; 11 | uniform vec2 u_mouse; 12 | uniform float u_time; 13 | // 圆 14 | vec3 createCircle(vec2 pos,float radius,vec2 uv){ 15 | float pct = distance(pos,uv); 16 | // smoothstep 平滑过渡 17 | return vec3(smoothstep(radius + 0.008,radius,pct )) ; 18 | } 19 | 20 | void main() { 21 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 22 | uv.x *= u_resolution.x/u_resolution.y; 23 | //鼠标位置 24 | vec2 mousePos = u_mouse/u_resolution; 25 | float isOnScreen = step(0.01,mousePos.x) * step(0.01,mousePos.y); 26 | 27 | vec3 color = vec3(0.); 28 | // 中心 29 | // vec2 center = vec2(0.5,0.5) * (1.-isOnScreen) + mousePos *isOnScreen ; 30 | vec2 center = vec2(0.5,0.5); 31 | 32 | //波纹宽度 33 | float width = 0.2; 34 | //波纹数量 35 | float rippleNum = 6.; 36 | //扩散速度 37 | float speed = 2.; 38 | //距离 39 | float dis = distance(center,uv); 40 | //动画 41 | float action = dis * rippleNum * 5. - u_time*speed ; 42 | //是否是波纹, 0 是波纹, 1 是背景 43 | float isRipple = smoothstep(width,width+0.05,abs(sin(action))); 44 | 45 | //背景颜色 46 | color += vec3(dis,0.504,0.960) * isRipple; 47 | //波纹颜色 48 | color += vec3(0.637,0.803,0.980) * (1. - isRipple); 49 | 50 | gl_FragColor = vec4(color,1.0); 51 | } -------------------------------------------------------------------------------- /Shader/014_ripple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/014_ripple/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/015_floridRipple/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 长生但酒狂 2 | // create time : 2019-12-21 3 | // Title:noise波纹 4 | 5 | // ------------------------------【片元着色器】---------------------------- 6 | #ifdef GL_ES 7 | precision mediump float; 8 | #endif 9 | 10 | uniform vec2 u_resolution; 11 | uniform vec2 u_mouse; 12 | uniform float u_time; 13 | 14 | vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } 15 | 16 | float snoise(vec2 v){ 17 | const vec4 C = vec4(0.211324865405187, 0.366025403784439, 18 | -0.577350269189626, 0.024390243902439); 19 | vec2 i = floor(v + dot(v, C.yy) ); 20 | vec2 x0 = v - i + dot(i, C.xx); 21 | vec2 i1; 22 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 23 | vec4 x12 = x0.xyxy + C.xxzz; 24 | x12.xy -= i1; 25 | i = mod(i, 289.0); 26 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 27 | + i.x + vec3(0.0, i1.x, 1.0 )); 28 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), 29 | dot(x12.zw,x12.zw)), 0.0); 30 | m = m*m ; 31 | m = m*m ; 32 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 33 | vec3 h = abs(x) - 0.5; 34 | vec3 ox = floor(x + 0.5); 35 | vec3 a0 = x - ox; 36 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 37 | vec3 g; 38 | g.x = a0.x * x0.x + h.x * x0.y; 39 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 40 | return 130.0 * dot(m, g); 41 | } 42 | 43 | vec3 hsv2rgb_smooth( in vec3 c ) 44 | { 45 | vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); 46 | 47 | rgb = rgb*rgb*(3.0-2.0*rgb); // cubic smoothing 48 | 49 | return c.z * mix( vec3(1.0), rgb, c.y); 50 | } 51 | 52 | // 波纹 53 | vec3 createRipple(vec2 pos,vec2 uv){ 54 | vec3 col = vec3(0.); 55 | // 中心 56 | // vec2 pos = vec2(0.5,0.5); 57 | //波纹宽度 58 | float width = 0.52; 59 | //波纹数量 60 | float rippleNum = 3.; 61 | //扩散速度 62 | float speed = 1.5; 63 | //距离 64 | float dis = distance(pos,uv); 65 | //动画 66 | float action = dis * rippleNum * 5. - u_time*speed ; 67 | //宽度逐渐减小 68 | width *= (0.6-dis); 69 | //是否是波纹, 0 是波纹, 1 是背景 70 | float isRipple = smoothstep(width,width+0.05,abs(sin(action))); 71 | 72 | //背景颜色 73 | col += vec3(dis,dis,0.) * isRipple; 74 | //波纹颜色 75 | vec3 color = hsv2rgb_smooth(vec3(snoise(uv),1,1)); 76 | col += color * (1. - isRipple); 77 | 78 | return vec3(col); 79 | } 80 | 81 | void main() { 82 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 83 | uv.x *= u_resolution.x/u_resolution.y; 84 | uv *= 1.8; 85 | 86 | vec3 color1 = createRipple(vec2(0.320,0.300),uv*snoise(uv)); 87 | 88 | vec3 col = color1 - hsv2rgb_smooth(vec3(snoise(uv)*sin(u_time),1.0,0.3)); 89 | gl_FragColor = vec4(col,1.0); 90 | } -------------------------------------------------------------------------------- /Shader/015_floridRipple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/015_floridRipple/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/016_cell/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: @patriciogv 2 | // Title: Simple Voronoi 3 | 4 | // 5 | #ifdef GL_ES 6 | precision mediump float; 7 | #endif 8 | 9 | uniform vec2 u_resolution; 10 | uniform vec2 u_mouse; 11 | uniform float u_time; 12 | 13 | vec2 random2( vec2 p ) { 14 | return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); 15 | } 16 | 17 | void main() { 18 | vec2 st = gl_FragCoord.xy/u_resolution.xy; 19 | st.x *= u_resolution.x/u_resolution.y; 20 | vec3 color = vec3(.0); 21 | 22 | // Scale - 缩放 3 倍 23 | st *= 3.; 24 | 25 | // Tile the space - 分割空间 26 | vec2 i_st = floor(st); 27 | vec2 f_st = fract(st); 28 | 29 | float m_dist = 10.; // minimun distance - 最小距离 30 | vec2 m_point; // minimum point - 最近的点 31 | 32 | //循环遍历邻居格子 33 | for (int j=-1; j<=1; j++ ) { 34 | for (int i=-1; i<=1; i++ ) { 35 | //邻居格子 36 | vec2 neighbor = vec2(float(i),float(j)); 37 | //网格中当前位置+相邻位置的随机位置 38 | vec2 point = random2(i_st + neighbor); 39 | //运动 40 | point = 0.5 + 0.5*sin(u_time + 6.2831*point); 41 | //当前像素 到 随机点 的距离 42 | vec2 diff = neighbor + point - f_st; 43 | float dist = length(diff); 44 | //取最小距离 45 | if( dist < m_dist ) { 46 | //保存最小距离 47 | m_dist = dist; 48 | //保存该点 49 | m_point = point; 50 | } 51 | } 52 | } 53 | 54 | // Assign a color using the closest point position - 使用最近的点位置分配颜色 55 | color += dot(m_point,vec2(0.230,0.700)); 56 | 57 | // Add distance field to closest point center - 向最近点中心添加距离场 58 | color.g = m_dist; 59 | 60 | // Show isolines - 显示等值线 61 | color -= abs(sin(40.0*m_dist))*0.07; 62 | 63 | // Draw cell center - 绘制细胞中心 64 | color += 1.-step(.05, m_dist); 65 | 66 | // Draw grid - 绘制网格 67 | color.r += step(.98, f_st.x) + step(.98, f_st.y); 68 | 69 | gl_FragColor = vec4(color,1.0); 70 | } 71 | -------------------------------------------------------------------------------- /Shader/016_cell/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/016_cell/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/017_distanceField_2D/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 2 | // Title: 3 | 4 | #ifdef GL_ES 5 | precision mediump float; 6 | #endif 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | float sdVesica(vec2 p, float r, float d) 13 | { 14 | p = abs(p); 15 | 16 | float b = sqrt(r*r-d*d); // can delay this sqrt by rewriting the comparison 17 | return ((p.y-b)*d > p.x*b) ? length(p-vec2(0.0,b))*sign(d) 18 | : length(p-vec2(-d,0.0))-r; 19 | } 20 | 21 | float sdCircle( vec2 p, float r ) 22 | { 23 | return length(p) - r; 24 | } 25 | 26 | 27 | float sdSphere( vec3 p, float s ) 28 | { 29 | return length(p)-s; 30 | } 31 | 32 | float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) 33 | { 34 | p.x = abs(p.x); 35 | float b = (r1-r2)/h; 36 | float a = sqrt(1.0-b*b); 37 | float k = dot(p,vec2(-b,a)); 38 | if( k < 0.0 ) return length(p) - r1; 39 | if( k > a*h ) return length(p-vec2(0.0,h)) - r2; 40 | return dot(p, vec2(a,b) ) - r1; 41 | } 42 | //心型SDF 43 | float heartSDF(vec2 point) { 44 | // point.y -= 0.25; 45 | float a = atan(point.x, point.y) / 3.141593; 46 | float r = length(point); 47 | float h = abs(a); 48 | float d = 0.5*(13.0 * h - 22.0 * h * h + 10.0 * h * h * h) / (6.0 - 5.0 * h); 49 | return r-d; 50 | } 51 | 52 | float sdHexagram( in vec2 p, in float r ) 53 | { 54 | const vec4 k = vec4(-0.5,0.8660254038,0.5773502692,1.7320508076); 55 | p = abs(p); 56 | p -= 2.0*min(dot(k.xy,p),0.0)*k.xy; 57 | p -= 2.0*min(dot(k.yx,p),0.0)*k.yx; 58 | p -= vec2(clamp(p.x,r*k.z,r*k.w),r); 59 | return length(p)*sign(p.y); 60 | } 61 | 62 | void main() { 63 | vec2 p = (2.0*gl_FragCoord.xy - u_resolution.xy)/u_resolution.y; 64 | vec3 color = vec3(0.); 65 | float d = sdHexagram( p + vec2(0.000,0.020), 0.1 ); 66 | d = heartSDF(p); 67 | vec3 col = vec3(1.0) - sign(d); 68 | gl_FragColor = vec4(col,1.0); 69 | } -------------------------------------------------------------------------------- /Shader/017_distanceField_2D/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/017_distanceField_2D/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/018_rayMarching/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform vec2 u_resolution; 7 | uniform vec2 u_mouse; 8 | uniform float u_time; 9 | //最大光线检测次数 10 | #define MAX_RAYCAST_STEPS 100 11 | #define Max_Dist 100. 12 | #define Surf_Dist 0.001 13 | 14 | // 来源:http://iquilezles.org/www/articles/distfunctions/distfunctions.htm 15 | // 距离场函数 - 球 16 | float sphereSDF( vec3 p, float s ) 17 | { 18 | // return length(p)-s; 19 | float dis = length(p)-s; 20 | return dis; 21 | } 22 | // 距离场函数 - 盒子 23 | float boxSDF( vec3 p, vec3 b ) 24 | { 25 | vec3 q = abs(p) - b; 26 | return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); 27 | } 28 | // 距离场函数 - 圆环 29 | float torusSDF( vec3 p, vec2 t ) 30 | { 31 | vec2 q = vec2(length(p.xz)-t.x,p.y); 32 | return length(q)-t.y; 33 | } 34 | 35 | //距离场函数 - 场景(包含需要绘制的所有物体) 36 | float sceneSDF(vec3 p) { 37 | float z = 10.; 38 | //盒子 39 | vec3 boxPos = vec3(3,2.,z); 40 | vec3 boxSize = vec3(0.6); 41 | float boxDist = boxSDF(p-boxPos,boxSize);// P点到box的距离 42 | //球 43 | vec3 spherePos = vec3(0,3,z); 44 | float sphereSize = 1.; 45 | float sphereDist = sphereSDF(p-spherePos,sphereSize);// P点到球面的距离 46 | //圆环 47 | vec3 torusPos = vec3(-3.0,2.,z); 48 | vec2 torusSize = vec2(.920,0.290); 49 | float torusDist = torusSDF(p-torusPos,torusSize);// P点到圆环面的距离 50 | 51 | //地面 52 | float planeDist = p.y;// P点到地面的距离,平面是xz平面,高度y = 0; 53 | //融合距离场 54 | float d = min(sphereDist,planeDist); 55 | d = min(d,boxDist); 56 | d = min(d,torusDist); 57 | return d; 58 | } 59 | 60 | 61 | // 阴影 62 | float SoftShadow(vec3 ro, vec3 rd ) 63 | { 64 | float res = 1.0; 65 | float t = 0.001; 66 | for( int i=0; i<50; i++ ) 67 | { 68 | vec3 p = ro + t*rd; 69 | float h = sceneSDF(p); 70 | res = min( res, 16.0*h/t ); 71 | t += h; 72 | if( res<0.001 ||p.y>(200.0) ) break; 73 | } 74 | return clamp( res, 0.0, 1.0 ); 75 | } 76 | 77 | //计算法线 78 | vec3 calcNormal( in vec3 p ) // for function f(p) 79 | { 80 | const float eps = 0.0001; // or some other value 81 | const vec2 h = vec2(eps,0); 82 | return normalize( vec3(sceneSDF(p+h.xyy) - sceneSDF(p-h.xyy), 83 | sceneSDF(p+h.yxy) - sceneSDF(p-h.yxy), 84 | sceneSDF(p+h.yyx) - sceneSDF(p-h.yyx) ) 85 | ); 86 | } 87 | //设置相机 88 | void SetCamera(vec2 uv,out vec3 ro, out vec3 rd){ 89 | //步骤1 获得相机位置ro 90 | ro = vec3(0.0,5.0,5);//获取相机的位置 91 | vec3 ta = vec3(0,0,10);//获取目标位置 92 | vec3 forward = normalize( ta - ro);//计算 forward 方向 93 | vec3 left = normalize(cross( vec3(0.0,1.0,0.0), forward ));//计算 left 方向 94 | vec3 up = normalize(cross(forward,left));////计算 up 方向 95 | const float zoom = 1.; 96 | 97 | //步骤2 获得射线朝向 98 | rd = normalize( uv.x*left + uv.y*up + zoom*forward ); 99 | } 100 | 101 | //获取灯光 102 | float GetLight(vec3 p) 103 | { 104 | vec3 lightPos = vec3(0,12,10); 105 | lightPos.xz += vec2(sin(u_time),cos(u_time))*2.0; 106 | 107 | vec3 l = normalize(lightPos-p);//光方向 108 | vec3 n = calcNormal(p); 109 | 110 | float dif = dot(n,l);//漫反射颜色 111 | //计算阴影 112 | float shadow = SoftShadow(p,l); 113 | return dif *shadow; 114 | } 115 | 116 | //射线检测 117 | //ro:位置, rd:方向 118 | float RayCast(vec3 ro, vec3 rd) 119 | { 120 | float depth = 0.;//深度 121 | 122 | for(int i = 0; i < MAX_RAYCAST_STEPS; i++) 123 | { 124 | //对UV进行偏移,偏移方向为rd 125 | vec3 p = ro + rd * depth; 126 | //最短距离 127 | float ds = sceneSDF(p); 128 | depth += ds; 129 | if(depth>Max_Dist || ds < Surf_Dist) 130 | break; 131 | } 132 | 133 | return depth; 134 | } 135 | 136 | void main() { 137 | vec2 uv = (2.0*gl_FragCoord.xy - u_resolution.xy)/u_resolution.y; 138 | 139 | vec3 color = vec3(0.); 140 | vec3 ro,rd; 141 | //设置Camera 142 | SetCamera(uv,ro,rd); 143 | //求射线和场景中物体的碰撞点p 144 | float ret = RayCast(ro,rd); 145 | vec3 pos = ro+ret*rd; 146 | 147 | float dif = GetLight(pos); 148 | 149 | // vec4 sph = vec4( cos( u_time + vec3(2.0,1.0,1.0) + 0.0 )*vec3(1.5,0.0,1.0), 1.0 );sph.x = 1.0; 150 | // float shadow = sphSoftShadow(pos,rd,sph,7.); 151 | 152 | color = vec3(dif) ; 153 | 154 | gl_FragColor = vec4(color,1.); 155 | } -------------------------------------------------------------------------------- /Shader/018_rayMarching/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/018_rayMarching/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/019_sea2D/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform vec2 u_resolution; 6 | uniform float u_time; 7 | #define LAYER 19.0 8 | 9 | 10 | float Circle(vec2 uv,vec2 center,float size,float blur){ 11 | uv = uv - center; 12 | uv /= size; 13 | float len = length(uv); 14 | return smoothstep(1.,1.-blur,len); 15 | } 16 | //简单直观的合成方式 17 | float DrawCloud(vec2 uv,vec2 center,float size){ 18 | uv = uv - center; 19 | uv /= size; 20 | float col = Circle(uv,vec2(0.,0.),0.2,0.05); 21 | col =col * smoothstep(-0.1,-0.1+0.01,uv.y);//将圆中不想要的的部分给剪切掉 22 | col += Circle(uv,vec2(0.15,-0.05),0.1,0.05); 23 | col += Circle(uv,vec2(0.010,-0.060),0.11,0.05); 24 | col += Circle(uv,vec2(-0.15,-0.1),0.1,0.05); 25 | col += Circle(uv,vec2(-0.3,-0.08),0.1,0.05); 26 | col += Circle(uv,vec2(-0.2,0.),0.15,0.05); 27 | return col; 28 | } 29 | float DrawClouds(vec2 uv){ 30 | uv.x += 0.03*u_time; 31 | uv.x = fract(uv.x+0.5) - 0.5; 32 | float col = DrawCloud( uv,vec2(-0.4,0.3),0.2); 33 | col += DrawCloud( uv,vec2(-0.2,0.42),0.2); 34 | col += DrawCloud( uv,vec2(0.0,0.4),0.2); 35 | col += DrawCloud( uv,vec2(0.15,0.3),0.2); 36 | col += DrawCloud( uv,vec2(0.45,0.45),0.2); 37 | return col; 38 | } 39 | 40 | float AngleCircle(vec2 uv,vec2 center,float size,float blur){ 41 | uv = uv - center; 42 | uv /= size; 43 | float deg = atan(uv.y,uv.x) + u_time * -0.1;//转化为极坐标 44 | float len = length(uv);//转化为极坐标 45 | //通过极坐标角度的方式来绘制波浪型的圆环 46 | float offs =( sin(deg*9.)*3.+sin(deg*11.+sin(u_time*6.0)*.5))*0.05; 47 | return smoothstep(1.+offs,1.-blur+offs,len); 48 | } 49 | 50 | float Wave(float layer,vec2 uv,float val){ 51 | float amplitude = layer*layer*0.00009;//这些数值都是为了美术效果 怎么漂亮怎么来 52 | float frequency = val*199.696*uv.x/layer; 53 | float phase = 9.*layer+ u_time/val; 54 | return amplitude*sin(frequency+phase); 55 | } 56 | 57 | float Remap(float oa,float ob,float na,float nb,float val){ 58 | return (val-oa)/(ob-oa) * (nb-na) + na; 59 | } 60 | 61 | void main(void){ 62 | vec2 uv = gl_FragCoord.xy/u_resolution.xy; 63 | uv.x *= u_resolution.x/u_resolution.y; 64 | 65 | vec3 col = vec3(0.0,0.0,0.0); 66 | float num = 0.; 67 | for (float i=1.; i < LAYER; i++) { 68 | //类似FBM的叠加方式,没加一层整幅下降一半,平率提升两倍左右,目的是 69 | //既可以用第一个函数控制大概的形状,又可以增加后面的函数添加高频的变化,方便控制细节 70 | //同样这些参数 是为了让函数的形状变得好看 71 | float wave = 2.*Wave(i,uv,1.)+Wave(i,uv,1.8)+.5*Wave(i,uv,3.); 72 | float layerVal = 0.7-0.03*i + wave;//控制波浪的高度 73 | if(uv.y > layerVal){ 74 | break; 75 | } 76 | num = i;//计算所在层的ID 77 | } 78 | col = num*vec3(0,.03,1);//计算每一层的基本颜色 79 | col += (LAYER - num) * vec3(.04,.04,.04);//颜色叠亮 80 | //在最高的一层海浪之上 81 | if(num == 0.){ 82 | //添加海平面泛光 83 | float ry = Remap(0.708,1.024,1.0,0.0,uv.y);//0.7是最高海浪值的水平面 84 | col = mix(vec3(0.1,0.6,0.9),vec3(0.1,0.7,0.9),ry);//简单的颜色渐变 85 | col += pow(ry,10.)*vec3(0.9,0.2,0.1)*0.2;//让接近海平面的地方泛白 pow是为了控制影响范围 86 | } 87 | gl_FragColor = vec4(col,1.0); 88 | } -------------------------------------------------------------------------------- /Shader/019_sea2D/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /Shader/019_sea2D/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /Shader/common/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Three Js for Shader 9 | 57 | 58 | 59 | 60 |
61 | 62 | 63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Shader/common/head.js: -------------------------------------------------------------------------------- 1 | // 头文件, 公用部分, 用来加载一些必要的文件。 2 | // 模板就是同目录下的 head.html 文件. 3 | document.writeln(` 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Three Js for Shader 12 | 60 | 61 | 62 | 63 |
64 | 65 | 66 |
67 |
68 | 69 | 70 | 71 | 72 | 73 | 116 | 117 | 118 | 119 | `); 120 | -------------------------------------------------------------------------------- /ShaderToyCollect/001_coloursWave/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform vec2 u_resolution; 7 | uniform vec2 u_mouse; 8 | uniform float u_time; 9 | 10 | void main() { 11 | vec3 c; 12 | float l,z=u_time; 13 | for(int i=0;i<3;i++) { 14 | vec2 uv,p=gl_FragCoord.xy/u_resolution.xy; 15 | uv=p; 16 | p-=.5; 17 | p.x*=u_resolution.x/u_resolution.y; 18 | z+=.07; 19 | l=length(p); 20 | uv+=p/l*(sin(z)+1.)*abs(sin(l*9.-z*2.)); 21 | c[i]=.01/length(abs(mod(uv,1.)-.5)); 22 | } 23 | gl_FragColor=vec4(c/l,u_time); 24 | } -------------------------------------------------------------------------------- /ShaderToyCollect/001_coloursWave/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /ShaderToyCollect/001_coloursWave/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /ShaderToyCollect/002_HappyJumping/fragmentShader.fs: -------------------------------------------------------------------------------- 1 | // Author: 2 | // Title: 3 | 4 | #ifdef GL_ES 5 | precision mediump float; 6 | #endif 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | #define iTime u_time 13 | #define iResolution.xy u_resolution 14 | // Created by inigo quilez - iq/2019 15 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 16 | // 17 | // 18 | // An animation test - a happy and blobby creature jumping and 19 | // looking around. It gets off-model very often, but it looks 20 | // good enough I think. 21 | // 22 | // Making of and related math/shader/art explanations (6 hours 23 | // long): https://www.youtube.com/watch?v=Cfe5UQ-1L9Q 24 | // 25 | // Video capture: https://www.youtube.com/watch?v=s_UOFo2IULQ 26 | 27 | #define AA 2 // Set AA to 1 if your machine is too slow 28 | 29 | 30 | //------------------------------------------------------------------ 31 | 32 | 33 | // http://iquilezles.org/www/articles/smin/smin.htm 34 | float smin( float a, float b, float k ) 35 | { 36 | float h = max(k-abs(a-b),0.0); 37 | return min(a, b) - h*h*0.25/k; 38 | } 39 | 40 | // http://iquilezles.org/www/articles/smin/smin.htm 41 | vec2 smin( vec2 a, vec2 b, float k ) 42 | { 43 | float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); 44 | return mix( b, a, h ) - k*h*(1.0-h); 45 | } 46 | 47 | // http://iquilezles.org/www/articles/smin/smin.htm 48 | float smax( float a, float b, float k ) 49 | { 50 | float h = max(k-abs(a-b),0.0); 51 | return max(a, b) + h*h*0.25/k; 52 | } 53 | 54 | // http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm 55 | float sdSphere( vec3 p, float s ) 56 | { 57 | return length(p)-s; 58 | } 59 | 60 | // http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm 61 | float sdEllipsoid( in vec3 p, in vec3 r ) // approximated 62 | { 63 | float k0 = length(p/r); 64 | float k1 = length(p/(r*r)); 65 | return k0*(k0-1.0)/k1; 66 | } 67 | 68 | vec2 sdStick(vec3 p, vec3 a, vec3 b, float r1, float r2) // approximated 69 | { 70 | vec3 pa = p-a, ba = b-a; 71 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); 72 | return vec2( length( pa - ba*h ) - mix(r1,r2,h*h*(3.0-2.0*h)), h ); 73 | } 74 | 75 | // http://iquilezles.org/www/articles/smin/smin.htm 76 | vec4 opU( vec4 d1, vec4 d2 ) 77 | { 78 | return (d1.x0.0 ) tmax = min( tmax, tp ); 252 | #endif 253 | 254 | float t = tmin; 255 | for( int i=0; i<256 && t0.0 ) tmax = min( tmax, tp ); 278 | #endif 279 | 280 | float t = 0.02; 281 | for( int i=0; i<50; i++ ) 282 | { 283 | float h = map( ro + rd*t, time ).x; 284 | res = min( res, mix(1.0,16.0*h/t, hsha) ); 285 | t += clamp( h, 0.05, 0.40 ); 286 | if( res<0.005 || t>tmax ) break; 287 | } 288 | return clamp( res, 0.0, 1.0 ); 289 | } 290 | 291 | // http://iquilezles.org/www/articles/normalsSDF/normalsSDF.htm 292 | vec3 calcNormal( in vec3 pos, float time ) 293 | { 294 | 295 | #if 0 296 | vec2 e = vec2(1.0,-1.0)*0.5773*0.001; 297 | return normalize( e.xyy*map( pos + e.xyy, time ).x + 298 | e.yyx*map( pos + e.yyx, time ).x + 299 | e.yxy*map( pos + e.yxy, time ).x + 300 | e.xxx*map( pos + e.xxx, time ).x ); 301 | #else 302 | // inspired by klems - a way to prevent the compiler from inlining map() 4 times 303 | vec3 n = vec3(0.0); 304 | for( int i=ZERO; i<4; i++ ) 305 | { 306 | vec3 e = 0.5773*(2.0*vec3((((i+3)>>1)&1),((i>>1)&1),(i&1))-1.0); 307 | n += e*map(pos+0.001*e,time).x; 308 | } 309 | return normalize(n); 310 | #endif 311 | } 312 | 313 | float calcOcclusion( in vec3 pos, in vec3 nor, float time ) 314 | { 315 | float occ = 0.0; 316 | float sca = 1.0; 317 | for( int i=ZERO; i<5; i++ ) 318 | { 319 | float h = 0.01 + 0.11*float(i)/4.0; 320 | vec3 opos = pos + h*nor; 321 | float d = map( opos, time ).x; 322 | occ += (h-d)*sca; 323 | sca *= 0.95; 324 | } 325 | return clamp( 1.0 - 2.0*occ, 0.0, 1.0 ); 326 | } 327 | 328 | vec3 render( in vec3 ro, in vec3 rd, float time ) 329 | { 330 | // sky dome 331 | vec3 col = vec3(0.5, 0.8, 0.9) - max(rd.y,0.0)*0.5; 332 | // sky clouds 333 | vec2 uv = 1.5*rd.xz/rd.y; 334 | float cl = 1.0*(sin(uv.x)+sin(uv.y)); uv *= mat2(0.8,0.6,-0.6,0.8)*2.1; 335 | cl += 0.5*(sin(uv.x)+sin(uv.y)); 336 | col += 0.1*(-1.0+2.0*smoothstep(-0.1,0.1,cl-0.4)); 337 | // sky horizon 338 | col = mix( col, vec3(0.5, 0.7, .9), exp(-10.0*max(rd.y,0.0)) ); 339 | 340 | 341 | // scene geometry 342 | vec4 res = castRay(ro,rd, time); 343 | if( res.y>-0.5 ) 344 | { 345 | float t = res.x; 346 | vec3 pos = ro + t*rd; 347 | vec3 nor = calcNormal( pos, time ); 348 | vec3 ref = reflect( rd, nor ); 349 | float focc = res.w; 350 | 351 | // material 352 | col = vec3(0.2); 353 | float ks = 1.0; 354 | 355 | if( res.y>4.5 ) // candy 356 | { 357 | col = vec3(0.14,0.048,0.0); 358 | vec2 id = floor(5.0*pos.xz+0.5); 359 | col += 0.036*cos((id.x*11.1+id.y*37.341) + vec3(0.0,1.0,2.0) ); 360 | col = max(col,0.0); 361 | focc = clamp(4.0*res.z,0.0,1.0); 362 | } 363 | else if( res.y>3.5 ) // eyeball 364 | { 365 | col = vec3(0.0); 366 | } 367 | else if( res.y>2.5 ) // iris 368 | { 369 | col = vec3(0.4); 370 | } 371 | else if( res.y>1.5 ) // body 372 | { 373 | col = mix(vec3(0.144,0.09,0.0036),vec3(0.36,0.1,0.04),res.z*res.z); 374 | col = mix(col,vec3(0.14,0.09,0.06)*2.0, (1.0-res.z)*smoothstep(-0.15, 0.15, -href)); 375 | } 376 | else // terrain 377 | { 378 | // base green 379 | col = vec3(0.05,0.09,0.02); 380 | float f = 0.2*(-1.0+2.0*smoothstep(-0.2,0.2,sin(18.0*pos.x)+sin(18.0*pos.y)+sin(18.0*pos.z))); 381 | col += f*vec3(0.06,0.06,0.02); 382 | ks = 0.5 + pos.y*0.15; 383 | 384 | // footprints 385 | vec2 mp = vec2(pos.x-0.5*(mod(floor(pos.z+0.5),2.0)*2.0-1.0), fract(pos.z+0.5)-0.5 ); 386 | float mark = 1.0-smoothstep(0.1, 0.5, length(mp)); 387 | mark *= smoothstep(0.0, 0.1, floor(time) - floor(pos.z+0.5) ); 388 | col *= mix( vec3(1.0), vec3(0.5,0.5,0.4), mark ); 389 | ks *= 1.0-0.5*mark; 390 | } 391 | 392 | // lighting (sun, sky, bounce, back, sss) 393 | float occ = calcOcclusion( pos, nor, time )*focc; 394 | float fre = clamp(1.0+dot(nor,rd),0.0,1.0); 395 | 396 | vec3 sun_lig = normalize( vec3(0.6, 0.35, 0.5) ); 397 | float sun_dif = clamp(dot( nor, sun_lig ), 0.0, 1.0 ); 398 | vec3 sun_hal = normalize( sun_lig-rd ); 399 | float sun_sha = calcSoftshadow( pos, sun_lig, time ); 400 | float sun_spe = ks*pow(clamp(dot(nor,sun_hal),0.0,1.0),8.0)*sun_dif*(0.04+0.96*pow(clamp(1.0+dot(sun_hal,rd),0.0,1.0),5.0)); 401 | float sky_dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); 402 | float sky_spe = ks*smoothstep( 0.0, 0.5, ref.y )*(0.04+0.96*pow(fre,4.0)); 403 | float bou_dif = sqrt(clamp( 0.1-0.9*nor.y, 0.0, 1.0 ))*clamp(1.0-0.1*pos.y,0.0,1.0); 404 | float bac_dif = clamp(0.1+0.9*dot( nor, normalize(vec3(-sun_lig.x,0.0,-sun_lig.z))), 0.0, 1.0 ); 405 | float sss_dif = fre*sky_dif*(0.25+0.75*sun_dif*sun_sha); 406 | 407 | vec3 lin = vec3(0.0); 408 | lin += sun_dif*vec3(8.10,6.00,4.20)*vec3(sun_sha,sun_sha*sun_sha*0.5+0.5*sun_sha,sun_sha*sun_sha); 409 | lin += sky_dif*vec3(0.50,0.70,1.00)*occ; 410 | lin += bou_dif*vec3(0.20,0.70,0.10)*occ; 411 | lin += bac_dif*vec3(0.45,0.35,0.25)*occ; 412 | lin += sss_dif*vec3(3.25,2.75,2.50)*occ; 413 | col = col*lin; 414 | col += sun_spe*vec3(9.90,8.10,6.30)*sun_sha; 415 | col += sky_spe*vec3(0.20,0.30,0.65)*occ*occ; 416 | 417 | col = pow(col,vec3(0.8,0.9,1.0) ); 418 | 419 | // fog 420 | col = mix( col, vec3(0.5,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); 421 | } 422 | 423 | return col; 424 | } 425 | 426 | mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) 427 | { 428 | vec3 cw = normalize(ta-ro); 429 | vec3 cp = vec3(sin(cr), cos(cr),0.0); 430 | vec3 cu = normalize( cross(cw,cp) ); 431 | vec3 cv = ( cross(cu,cw) ); 432 | return mat3( cu, cv, cw ); 433 | } 434 | 435 | void main( ) 436 | { 437 | vec3 tot = vec3(0.0); 438 | #if AA>1 439 | for( int m=ZERO; m1 489 | } 490 | tot /= float(AA*AA); 491 | #endif 492 | 493 | // s-surve 494 | tot = clamp(tot,0.0,1.0); 495 | tot = tot*tot*(3.0-2.0*tot); 496 | 497 | // vignetting 498 | vec2 q = gl_FragCoord/iResolution.xy; 499 | tot *= 0.5 + 0.5*pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.25); 500 | 501 | // output 502 | gl_FragColor = vec4( tot, 1.0 ); 503 | } -------------------------------------------------------------------------------- /ShaderToyCollect/002_HappyJumping/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 16 | -------------------------------------------------------------------------------- /ShaderToyCollect/002_HappyJumping/vertexShader.vs: -------------------------------------------------------------------------------- 1 | // create by 长生但酒狂 2 | // create time : 2019-12-13 22:00 3 | 4 | // ------------------------------【顶点着色器】---------------------------- 5 | void main() { 6 | gl_Position = vec4( position, 1.0 ); 7 | } -------------------------------------------------------------------------------- /ShaderToyCollect/common/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Three Js for Shader 9 | 44 | 45 | 46 | 47 |
48 | 49 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /ShaderToyCollect/common/head.js: -------------------------------------------------------------------------------- 1 | // 头文件, 公用部分, 用来加载一些必要的文件。 2 | // 模板就是同目录下的 head.html 文件. 3 | document.writeln(` 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Three Js for Shader 12 | 47 | 48 | 49 | 50 |
51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | 59 | 90 | 91 | 92 | 93 | `); 94 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 24 | 25 | -------------------------------------------------------------------------------- /js/ShaderMgr.js: -------------------------------------------------------------------------------- 1 | 2 | window.ShaderMgr = (function () { 3 | var container; 4 | var camera, scene, renderer; 5 | var uniforms = {}; 6 | var vertexShaderPath, fragmentShaderPath; 7 | var vertexShaderProgram, fragmentShaderProgram; 8 | var _update = ()=>{}; 9 | console.log("12121"); 10 | 11 | // 初始化 12 | function init(containerId) { 13 | // 读取文件 14 | readFile(vertexShaderPath, (vertexString) => { 15 | readFile(fragmentShaderPath, (fragmentString) => { 16 | vertexShaderProgram = vertexString; 17 | fragmentShaderProgram = fragmentString; 18 | initShader(containerId); 19 | animate(); 20 | }) 21 | }) 22 | } 23 | 24 | // 设置shader程序 25 | function setShaderProgram(vertexShader, fragmentShader) { 26 | vertexShaderPath = vertexShader; 27 | fragmentShaderPath = fragmentShader; 28 | } 29 | 30 | // 设置uniforms 变量 31 | function setUniforms(name, type, value) { 32 | uniforms[name] = { type, value }; 33 | } 34 | 35 | // 读取文件 36 | function readFile(path, callBack = () => { }) { 37 | $.ajax({ 38 | url: path, 39 | success: function (data, status) { 40 | callBack(data) 41 | }, 42 | error: function (data, status) { 43 | console.error(`读取${path}失败`) 44 | } 45 | }); 46 | } 47 | 48 | // 初始化shader 49 | function initShader(containerId) { 50 | container = document.getElementById(containerId); 51 | // 摄像机 52 | camera = new THREE.Camera(); 53 | camera.position.z = 1; 54 | // 场景 55 | scene = new THREE.Scene(); 56 | // 创建一个平面 57 | var geometry = new THREE.PlaneBufferGeometry(2, 2); 58 | 59 | console.log("vertexShader:", vertexShaderPath); 60 | console.log("fragmentShader:", fragmentShaderPath); 61 | console.log("uniforms:", uniforms); 62 | //屏幕大小 63 | setUniforms("u_resolution","v2", new THREE.Vector2()); 64 | // 运行时间 65 | setUniforms("u_time","f", 1.0) 66 | 67 | // 材质 68 | var material = new THREE.ShaderMaterial({ 69 | uniforms: uniforms, 70 | vertexShader: vertexShaderProgram, 71 | fragmentShader: fragmentShaderProgram, 72 | }); 73 | // 74 | var mesh = new THREE.Mesh(geometry, material); 75 | scene.add(mesh); 76 | 77 | renderer = new THREE.WebGLRenderer(); 78 | renderer.setPixelRatio(window.devicePixelRatio); 79 | 80 | container.appendChild(renderer.domElement); 81 | //重新调整窗体大小 82 | onWindowResize(container); 83 | // window.addEventListener('resize', onWindowResize, false); 84 | } 85 | 86 | // 窗口大小改变会触发 87 | function onWindowResize(container) { 88 | // let width = Math.min(window.innerWidth, window.innerHeight); 89 | let width = container.clientWidth; 90 | // console.log(document.getElementById("container").clientWidth); 91 | 92 | renderer.setSize(width,width); 93 | uniforms.u_resolution.value.x = renderer.domElement.width; 94 | uniforms.u_resolution.value.y = renderer.domElement.height; 95 | } 96 | 97 | function animate() { 98 | requestAnimationFrame(animate); 99 | render(); 100 | } 101 | 102 | // 渲染 103 | function render() { 104 | uniforms.u_time.value += 0.05; 105 | _update(); 106 | renderer.render(scene, camera); 107 | } 108 | 109 | // 每帧调用 110 | function update(func) { 111 | _update = func; 112 | } 113 | 114 | return { init, setShaderProgram ,setUniforms,update} 115 | }()) 116 | -------------------------------------------------------------------------------- /js/stats.min.js: -------------------------------------------------------------------------------- 1 | // stats.js - http://github.com/mrdoob/stats.js 2 | (function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;d=g+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/ 4 | 1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v); 5 | b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f}); --------------------------------------------------------------------------------