当个快乐的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/
相关文章
|
11月前
|
机器学习/深度学习 人工智能 开发者
阿里云支持DeepSeek-V3和DeepSeek-R1全自动安装部署,小白也能轻松上手!
阿里云PAI平台支持DeepSeek-V3和DeepSeek-R1大模型的全自动安装部署,零代码一键完成从训练到推理的全流程。用户只需开通PAI服务,在Model Gallery中选择所需模型并点击部署,即可快速生成PAI-EAS服务,获取调用信息。整个过程简单快捷,适合各水平开发者轻松上手。
3330 80
|
弹性计算 网络安全
阿里云服务器更换公网IP地址教程
阿里云服务器更换公网IP地址教程
881 0
|
JavaScript 前端开发
js实现移动端图片预览:手势缩放, 手势拖动,双击放大...
原文:js实现移动端图片预览:手势缩放, 手势拖动,双击放大... 前言本文将介绍如何通过js实现移动端图片预览,包括图片的 预览模式,手势缩放,手势拖动,双击放大等基本功能; 扫码查看示例效果: 代码地址http://pangyongsheng.github.io/imgPreview/ 一、功能介绍   图片预览主要有以下几个功能点组成: 监听图片点击事件,进入图片预览模式 自定义手势事件, (双指缩放,滑动,双击。
3604 0
|
存储 Linux Perl
6.9 Linux sed命令的高级玩法
《Linux sed用法详解》一节给大家介绍了如何用 sed 命令的基本功能处理文本中的数据,所涵盖的知识点,可以满足日常大多数文本编辑需求。本节将介绍 sed 提供的一些高级功能,这些功能虽不常用,但知道这些功能的存在以及用法也是有必要的。
1880 0
6.9 Linux sed命令的高级玩法
|
消息中间件 NoSQL 关系型数据库
hyperf| 带你一起看 hyperf 文档之 amqp
花 2 个小时认真看一遍文档, 比遇到问题就卡住然后到处问要高效得多.
1844 0
|
资源调度 大数据 调度
独家下载 | “伏羲”神算!阿里巴巴经济体核心调度系统揭秘
阿里巴巴 9 位技术专家为你深度解析阿里巴巴经济体核心调度系统“伏羲”。伏羲(Fuxi)作为十年前最初创立飞天平台时的三大服务之一(分布式存储 Pangu,分布式计算 MaxCompute,分布式调度 Fuxi),十年来,在技术能力上持续演进。本书从面向大数据、云计算的调度挑战出发,介绍伏羲调度系统及各子领域的关键技术进展,并以双11为典型场景进行最佳实践的介绍,为你呈现大数据分布式调度技术的深水区玩法。— 《“伏羲”神算》现在可以免费下载阅读啦,快来先睹为快吧。
38815 0
独家下载 | “伏羲”神算!阿里巴巴经济体核心调度系统揭秘
|
监控 大数据 Apache
【必看】如何正确使用实时计算 Flink 版?
本篇文章将从实时计算 Flink 版产品功能、产品架构、产品模式、产品优势、产品应用场景等全面呈现,同时还汇总了实时计算 Flink 版学习资料!更有特惠独享活动限时参与!
【必看】如何正确使用实时计算 Flink 版?
|
数据采集 Web App开发 JSON
python爬虫AJAX数据爬取和HTTPS访问 | python爬虫实战之四
本节介绍了通过“豆瓣电影”来进行了json数据的处理,另外说明了HTTPS访问需要获得CA证书。使用HTTPS加密数据更加安全。
python爬虫AJAX数据爬取和HTTPS访问 | python爬虫实战之四
|
关系型数据库 分布式数据库 Apache
HBase的备份以及恢复方案
云HBase的备份以及恢复方案
25985 0
|
分布式数据库 数据库 数据安全/隐私保护
访问云数据库HBase版的WebUI
访问HBase WebUI 一、查看访问机器的真实IP 直接浏览器打开如下网址:http://ifconfig.me/ 查看访问机器的真实IP,如下图: 二、修改集群的网络白名单 打开集群详情页面,点击修改网络白名单,如下图: 在打开的页面中输入第一步查询到的真实IP,I
2939 1