当个快乐的WebGL炫酷背景搬运工!

简介: 看到shadertoy里面的那么多炫酷的背景是不是很心动?那我们就来把人家的shader搬过来用一下吧!

看到shadertoy里面的那么多炫酷的背景是不是很心动?那我们就来把人家的shader搬过来用一下吧!

1.搞个webgl背景板

默认顶点着色器

attribute vec2 pos;
void main(){gl_Position=vec4(pos,0.0,1.0);}

背景板坐标点共六个,两个三角形组成矩形填充满整个webgl


 initArrBuffer(
    gl,
    'pos',
    new Float32Array(
      flatArr([
        [1.0, 1.0],
        [1.0, -1.0],
        [-1.0, -1.0],
        [-1.0, -1.0],
        [-1.0, 1.0],
        [1.0, 1.0]
      ])
    ),
    2
  );

其他初始化着色器程序流程不变

2.初始化相关参数

mouse 鼠标移动位置

 var mouse = {
    x: 0, y: 0 };

  gl.canvas.addEventListener('pointermove', (ev) => {
   
    mouse.x = ev.clientX / gl.canvas.width;
    mouse.y = 1 - ev.clientY / gl.canvas.height;
  });

time(运行时间-开始时间)的秒数

var time = performance.now() - startTime;

resolution 宽高,用于片元坐标转二维坐标

3.画出场景,动起来

function drawScene() {
   
    cleanGl(gl);
    gl.uniform2f(gl.getUniformLocation(gl.program, 'resolution'), gl.canvas.width, gl.canvas.height);
    var time = performance.now() - startTime;
    gl.uniform1f(gl.getUniformLocation(gl.program, 'time'), time / 1000);
    gl.uniform2f(gl.getUniformLocation(gl.program, 'mouse'), mouse.x, mouse.y);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
  }
  function animate() {
   
    drawScene();
    requestAnimationFrame(animate);
  }
  animate();

4.简单示例:shader画出鼠标点

precision highp float;

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main(void) {
    vec2 position = (gl_FragCoord.xy / resolution.x);
    //一定要对鼠标点进行转换,否则就会出现很大的偏差
    vec2 ms = (mouse * resolution / resolution.x);
    //片元左边与鼠标距离
    float d = length(position - ms);
    //0.1范围内设置为白色
    if(d <= 0.1) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    } else {
        gl_FragColor = vec4(1.0, 0, 0, 1.0);
    }
}

20230507_231040.gif

5.搬运shadertoy里面的好看示例

在片元着色器顶部加上进度和变量名,定义成shadertoy名称

//定义精度
#ifdef GL_ES
precision highp float;
#endif
//传入的值
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;
//定义成shadertoy的变量名
#define iMouse mouse
#define iTime time
#define iResolution resolution

执行生成画面的方法

//shadertoy一般都有这个方法
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
}

void main(void) {
    mainImage(gl_FragColor, gl_FragCoord.xy);
}
  • 注意:不能照搬照抄,要根据具体情况进行调整或增加glsl里面的参数

6.搬运实践1

20230507_231656.gif

https://www.shadertoy.com/view/7sBfDD

  • 这个华丽丽的放射线示例中鼠标点需要转换iMouse = mouse * resolution;
 //定义精度
#ifdef GL_ES
precision highp float;
#endif
//传入的值
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;
//定义成shadertoy的变量名
//#define iMouse mouse
#define iTime time
#define iResolution resolution
//这里的iMouse需要转换
vec2 iMouse = vec2(0.0);

//--------------------- shadertoy start---------------------
#define pi 3.14159

mat2 Rot(float a) {
    float c = cos(a), s = sin(a);
    return mat2(c, -s, s, c);
}

vec3 pal(in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d) {
    return a + b * cos(6.28318 * (c * t + d));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    vec2 ms = (iMouse.xy - 0.5 * iResolution.xy) / iResolution.y;

          // change me! (and uncomment for loop stuff below)
    float A = 1.;    // -1. // 0.
    float r = 0.3;   // 0.6
    float th = 0.02; // 0.12

    vec2 dir = uv - ms;
    float a = atan(dir.x, dir.y);
    float s = 0.;

          // n is higher than it needs to be but works fine
    const float n = 20.;
    float k = 6. / iResolution.y;

    for(float i = n; i > 0.; i--) {
        float io = A * 2. * pi * i / n;
        float sc = -4. - 0.5 * i + 0.9 * cos(io - 9. * length(dir) + iTime);
        vec2 fpos = fract(sc * uv + 0.5 * i * ms) - 0.5;
              //fpos = abs(fpos) - 0.25;
        fpos *= Rot(a); // a + io // 5. * a // a + 3. * atan(fpos.x, fpos.y)
        float d = abs(fpos.x);
        s *= 0.865;
        s += step(0., s) * smoothstep(-k, k, -abs(d - r) + th);
    }

    float val = s * 0.1 + 0.72 + 0. * iTime - 0.23 * pow(dot(dir, dir), 0.25);
    val = clamp(val, 0.4, 1.);
    vec3 e = vec3(1);
    vec3 col = 0.5 * pal(val, e, e, e, 0.24 * vec3(0, 1, 2) / 3.);
    col = smoothstep(0., 1., col);

    fragColor = vec4(col, 1.0);
}
//--------------------- shadertoy end---------------------

void main(void) {
//鼠标点转换
    iMouse = mouse * resolution;
    //执行生成画面
    mainImage(gl_FragColor, gl_FragCoord.xy);
}

7.搬运实战2

https://www.shadertoy.com/view/tdSXzD

20230508_010655.gif

  • (1)里面采用了贴图噪声,因为存在GL_EXT_shader_texture_lod等wegbl2版本扩展不兼容问题,我这里直接改成噪声函数了。
  • (2)鼠标点击后奇怪地出现颜色不对,就禁用了,
//定义精度
#ifdef GL_ES
precision highp float;
#endif
//传入的值
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;

//定义成shadertoy的变量名
// #define iMouse mouse
//静态化鼠标操作,很奇怪,我这里点击后画面奇怪
vec2 iMouse = vec2(0.0);
#define iTime time
#define iResolution resolution

//--------------------- shadertoy start---------------------
//END AURORA STUFF
// 替换噪声函数
// float noise(in vec2 v) {
//     return textureLod(iChannel0, (v + .5) / 256., 0.).g;

// }

float rand(vec2 n) {
    return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
}

float noise(vec2 p) {
    vec2 ip = floor(p);
    vec2 u = fract(p);
    u = u * u * (3.0 - 2.0 * u);

    float res = mix(mix(rand(ip), rand(ip + vec2(1.0, 0.0)), u.x), mix(rand(ip + vec2(0.0, 1.0)), rand(ip + vec2(1.0, 1.0)), u.x), u.y);
    return res * res;
}

float mod289(float x) {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 perm(vec4 x) {
    return mod289(((x * 34.0) + 1.0) * x);
}

float Noise(vec3 p) {
    vec3 a = floor(p);
    vec3 d = p - a;
    d = d * d * (3.0 - 2.0 * d);

    vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
    vec4 k1 = perm(b.xyxy);
    vec4 k2 = perm(k1.xyxy + b.zzww);

    vec4 c = k2 + a.zzzz;
    vec4 k3 = perm(c);
    vec4 k4 = perm(c + 1.0);

    vec4 o1 = fract(k3 * (1.0 / 41.0));
    vec4 o2 = fract(k4 * (1.0 / 41.0));

    vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
    vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);

    return o4.y * d.y + o4.x * (1.0 - d.y);
} 
// // by iq
// 替换噪声函数
// float Noise(in vec3 x) {
//     vec3 p = floor(x);
//     vec3 f = fract(x);
//     f = f * f * (3.0 - 2.0 * f);

//     vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
//     vec2 rg = texture(iChannel0, (uv + 0.5) / 256.0, -100.0).yx;
//     return mix(rg.x, rg.y, f.z);
// }


//--------------------- shadertoy end---------------------
void main(void) {
    mainImage(gl_FragColor, gl_FragCoord.xy);
}

glsl noise函数参考:https://blog.csdn.net/qq_28299311/article/details/103654190

github地址

https://github.com/xiaolidan00/awesome-bg

shadertoyglslsandbox里面扒拉下来的好多好看的背景。有些shader运行起来真的很耗资源,量力而行打开看看,别把电脑卡死了!

20230508_015228.gif

参考

  • shadertoy:https://www.shadertoy.com/
  • glslsandbox:https://glslsandbox.com/
相关文章
|
2月前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
58 11
|
3月前
|
前端开发 JavaScript
还在为酷炫css动画背景头疼吗?1分钟解决
还在为酷炫css动画背景头疼吗?1分钟解决
|
3月前
|
存储 API 图形学
Unity精华☀️二、到底是什么原因导致“万向锁”?旋转翻车的终极解析!
Unity精华☀️二、到底是什么原因导致“万向锁”?旋转翻车的终极解析!
|
6月前
网页星光闪耀背景动画特效
网页星光闪耀背景动画特效
36 0
网页星光闪耀背景动画特效
|
6月前
对游戏设计案例杂谈1
对游戏设计案例杂谈1
|
6月前
|
前端开发 JavaScript 数据可视化
元宇宙基础案例 | 大帅老猿threejs特训
元宇宙基础案例 | 大帅老猿threejs特训
|
IDE 定位技术 开发工具
如何用three.js实现我的太空遐想3D网页
如何用three.js实现我的太空遐想3D网页
346 0
如何用three.js实现我的太空遐想3D网页
|
前端开发
前端知识案例学习3-毛玻璃效果
前端知识案例学习3-毛玻璃效果
65 0
前端知识案例学习3-毛玻璃效果
|
存储 Web App开发 算法
每个前端工程师都应该了解的图片知识(长文建议收藏)
随着web的发展,网站资源的流量也变得越来越大。据统计,60% 的网站流量均来自网站图片,可见对图片合理优化可以大幅影响网站流量,减小带宽消耗和服务器压力。
266 0
每个前端工程师都应该了解的图片知识(长文建议收藏)
|
前端开发 JavaScript
Three.js - 走进3D的奇妙世界
本文将通过Three.js的介绍及示例带我们走进3D的奇妙世界。