【可视化学习】13-shader
发表于:2023-06-03 |

前言

是不是看我许多天没更新可视化的内容了,以为我放弃了,哈哈,并没有,只是这一块的内容比较晦涩,我学起来也费事,多学了一会,加上这两天有点忙,然后下班后想放松下,就拖了俩天,好了,废话不多说,开始我们今天的内容分享部分,这个也是webgl的核心部分,shader。之前我们在可视化学习12中讲过shader。太久没讲了,重新复习下。

复习

让我们用shader画一个最基础的图形
先搞一份基础代码,创建一个基础平面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import * as THREE from "three";

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// 初始化场景
const scene = new THREE.Scene();

// 创建透视相机
const camera = new THREE.PerspectiveCamera(
90,
window.innerHeight / window.innerHeight,
0.1,
1000
);
// 设置相机位置
// object3d具有position,属性是1个3维的向量
camera.position.set(0, 0, 2);
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
scene.add(camera);

// 加入辅助轴,帮助我们查看3维坐标轴
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

const material = new THREE.MeshBasicMaterial({ color: "#00ff00" });

// 创建平面
const floor = new THREE.Mesh(
new THREE.PlaneBufferGeometry(1, 1, 64, 64),
material
);
scene.add(floor);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer({ alpha: true });

// 设置渲染尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);

// 监听屏幕大小改变的变化,设置渲染的尺寸
window.addEventListener("resize", () => {
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();

// 更新渲染器
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置渲染器的像素比例
renderer.setPixelRatio(window.devicePixelRatio);
});

// 将渲染器添加到body
document.body.appendChild(renderer.domElement);

// 初始化控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼
controls.enableDamping = true;

const clock = new THREE.Clock();
function animate(t) {
const elapsedTime = clock.getElapsedTime();
// console.log(elapsedTime);
requestAnimationFrame(animate);
// 使用渲染器渲染相机看这个场景的内容渲染出来
renderer.render(scene, camera);
}

animate();

效果图

这是我们将threejs的材质用我们的shader替换,也可以有一样的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 创建着色器材质
const shaderMaterial = new THREE.ShaderMaterial({
vertexShader: `
void main(){
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ) ;
}
`,
fragmentShader: `
void main(){
gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
`,
});

// 创建平面
const floor = new THREE.Mesh(
new THREE.PlaneBufferGeometry(1, 1, 64, 64),
shaderMaterial
);

效果图

打造流动旗帜

我们先来看看效果图
效果图

  1. 接下来,我们把shader拆出去,单独写一个文件,然后引入进来

    1
    2
    3
    4
    // 顶点着色器
    import basicVertexShader from "../shader/raw/vertex.glsl";
    // 片元着色器
    import basicFragmentShader from "../shader/raw/fragment.glsl";

    效果图

  2. 导入旗帜的图片作为纹理

    1
    2
    3
    // 创建纹理加载器对象
    const textureLoader = new THREE.TextureLoader();
    const texture = textureLoader.load("./texture/ca.jpeg");
  3. 创建材质使用我们外部引入的shader并把纹理给我们的shader文件,这里因为用到了shader,因此使用了原始着色器材质

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const rawShaderMaterial = new THREE.RawShaderMaterial({
    vertexShader: basicVertexShader,
    fragmentShader: basicFragmentShader,
    side: THREE.DoubleSide,
    uniforms: {
    uTexture: {
    value: texture,
    },
    },
    });
  4. 精度理解
    精度越高就越细节,但是渲染花费的资源也就越多,所以我们要根据实际情况来选择精度

    1
    2
    3
    // highp  -2^16 - 2^16
    // mediump -2^10 - 2^10
    // lowp -2^8 - 2^8
  5. 简单介绍uv坐标
    就拿我们刚才的正方形来说,我们的uv坐标是这样的,从左下角开始是(0,0),右上角是(1,1),大家只需要知道这个值在0-1之间就可以了

  6. 变量介绍
    变量介绍
    简单来说就是

  • attribute 使用内部属性
  • uniform 使用外部属性
  • varying 着色器之间传递数据
  1. 顶点着色器内容绘制
    在文件vertex.glsl中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 设置为低精度
    precision lowp float;
    // 位置信息
    attribute vec3 position;
    // uv信息
    attribute vec2 uv;

    // 各类模型矩阵,用来计算最终的位置
    uniform mat4 modelMatrix;
    uniform mat4 viewMatrix;
    uniform mat4 projectionMatrix;

    varying vec2 vUv;
    void main(){
    // 传递uv
    vUv = uv;
    // 计算最终的位置
    vec4 modelPosition = modelMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * viewMatrix * modelPosition ;
    }
  2. 片元着色器
    在外部fragment.glsl中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    precision lowp float;
    varying vec2 vUv;
    uniform sampler2D uTexture;

    void main(){
    // 根据UV,取出对应的颜色
    float height = 0.05 * 20.0;
    vec4 textureColor = texture2D(uTexture,vUv);
    textureColor.rgb*=height;
    gl_FragColor = textureColor;
    }

    这样完成之后让我们看下效果
    导入纹理后效果图

  3. 添加时间,让旗帜动起来
    在main.js中,添加时间变量

    1
    2
    3
    4
    5
    6
    7
    8
    uniforms: {
    uTime: {
    value: 0,
    },
    uTexture: {
    value: texture,
    },
    },

    animate赋值

    1
    2
    3
    4
    5
    6
    7
    8
    function animate(t) {
    const elapsedTime = clock.getElapsedTime();
    // 赋值
    rawShaderMaterial.uniforms.uTime.value = elapsedTime;
    requestAnimationFrame(animate);
    // 使用渲染器渲染相机看这个场景的内容渲染出来
    renderer.render(scene, camera);
    }

    在顶点着色器中使用时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    precision lowp float;
    attribute vec3 position;
    attribute vec2 uv;


    uniform mat4 modelMatrix;
    uniform mat4 viewMatrix;
    uniform mat4 projectionMatrix;

    // 获取时间
    uniform float uTime;


    varying vec2 vUv;

    // highp -2^16 - 2^16
    // mediump -2^10 - 2^10
    // lowp -2^8 - 2^8

    // 把位置信息传递出去,根据偏移量设置抖动时候的阴影
    varying float vElevation;


    void main(){
    vUv = uv;
    vec4 modelPosition = modelMatrix * vec4( position, 1.0 );
    // 根据时间抖动
    modelPosition.z = sin((modelPosition.x+uTime) * 10.0)*0.05 ;
    modelPosition.z += sin((modelPosition.y+uTime) * 10.0)*0.05 ;
    vElevation = modelPosition.z;
    gl_Position = projectionMatrix * viewMatrix * modelPosition ;
    }

// 把顶点着色器位置信息传递出去,片元着色器根据偏移量设置抖动时候的颜色改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
precision lowp float;
varying vec2 vUv;
varying float vElevation;

uniform sampler2D uTexture;


void main(){
// 根据UV,取出对应的颜色
float height = vElevation+0.05 * 20.0;
vec4 textureColor = texture2D(uTexture,vUv);
textureColor.rgb*=height;
gl_FragColor = textureColor;
}

这样,我们就将抖动的旗帜完成了

uv搞颜色

核心就是理解uv的概念

通过顶点对应的uv,决定每一个像素在uv图像的位置,通过这个位置x,y决定颜色

顶点着色器保持不要变

1
2
3
4
5
6
7
varying vec2 vUv;
precision lowp float;
void main(){
vec4 modelPosition = modelMatrix * vec4( position, 1.0 );
vUv=uv;
gl_Position = projectionMatrix * viewMatrix * modelPosition;
}

片元着色器
1
gl_FragColor =vec4(vUv,0,1);

效果图

简单讲解下,为什么会出现这么一样的效果,之前说过,uv是从0-1变化的,左小右大,上大下小,最左下方是(0,0),那么这个颜色就是(0,0,0,1),是黑色,最右上方是(1,1),那么这个颜色就是(1,1,0,1),红色和绿色融合就是黄色,所以就出现了这样的效果

对第一种变形

1
gl_FragColor = vec4(vUv,1,1);

效果图

利用uv实现渐变效果,从左到右

1
2
float strength = vUv.x;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用uv实现渐变效果,从下到上

1
2
float strength = vUv.y;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用uv实现渐变效果,从上到下

1
2
float strength = 1.0-vUv.y;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用uv实现短范围内渐变

1
2
float strength = vUv.y * 10.0;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用通过取模达到反复效果

1
2
float strength = mod(vUv.y * 10.0 , 1.0) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用step(edge, x)如果x < edge,返回0.0,否则返回1.0

1
2
3
float strength =  mod(vUv.y * 10.0 , 1.0) ;
strength = step(0.5,strength);
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用step(edge, x)如果x < edge,返回0.0,否则返回1.0,换个参数

1
2
3
float strength =  mod(vUv.y * 10.0 , 1.0) ;
strength = step(0.8,strength);
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用step(edge, x)如果x < edge,返回0.0,否则返回1.0,换个参数

1
2
3
float strength =  mod(vUv.x * 10.0 , 1.0) ;
strength = step(0.8,strength);
gl_FragColor =vec4(strength,strength,strength,1);

效果图

条纹相加

1
2
3
float strength = step(0.8, mod(vUv.x * 10.0 , 1.0)) ;
strength += step(0.8, mod(vUv.y * 10.0 , 1.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

条纹相乘

1
2
3
float strength = step(0.8, mod(vUv.x * 10.0 , 1.0)) ;
strength *= step(0.8, mod(vUv.y * 10.0 , 1.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

条纹相减

1
2
3
float strength = step(0.8, mod(vUv.x * 10.0 , 1.0)) ;
strength -= step(0.8, mod(vUv.y * 10.0 , 1.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

方块图形

1
2
3
float strength = step(0.2, mod(vUv.x * 10.0 , 1.0)) ;
strength *= step(0.2, mod(vUv.y * 10.0 , 1.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

T型图

1
2
3
4
5
float barX = step(0.4, mod(vUv.x * 10.0 - 0.2 , 1.0))*step(0.8, mod(vUv.y * 10.0 , 1.0)) ;
float barY = step(0.4, mod(vUv.y * 10.0 , 1.0))*step(0.8, mod(vUv.x * 10.0 , 1.0)) ;
float strength = barX+barY;

gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用绝对值

1
2
float strength = abs(vUv.x - 0.5) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

取2个值的最小值

1
2
float strength =min(abs(vUv.x - 0.5), abs(vUv.y - 0.5))  ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

取2个值的最大值

1
2
float strength =max(abs(vUv.x - 0.5), abs(vUv.y - 0.5))  ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

step

1
2
float strength =step(0.2,max(abs(vUv.x - 0.5), abs(vUv.y - 0.5)))   ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

小正方形

1
2
float strength =1.0-step(0.2,max(abs(vUv.x - 0.5), abs(vUv.y - 0.5)))   ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

利用取整,实现条纹渐变

1
2
3
4
5
6
float strength = floor(vUv.x*10.0)/10.0;
gl_FragColor =vec4(strength,strength,strength,1);


// float strength = floor(vUv.y*10.0)/10.0;
// gl_FragColor =vec4(strength,strength,strength,1);

效果图

条纹相乘,实现渐变格子

1
2
3
float strength = floor(vUv.x*10.0)/10.0*floor(vUv.y*10.0)/10.0;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

向上取整

1
2
3
float strength = ceil(vUv.x*10.0)/10.0*ceil(vUv.y*10.0)/10.0;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

随机效果

这些shader方法可以通过bookshader去查找bookshader
效果图

1
2
3
4
5
6
7
// 随机函数
float random (vec2 st) {
return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);
}
float strength = random(vUv);
gl_FragColor =vec4(strength,strength,strength,1);


效果图

随机+格子效果

1
2
3
4
5
float strength = ceil(vUv.x*10.0)/10.0*ceil(vUv.y*10.0)/10.0;
strength = random(vec2(strength,strength));
gl_FragColor =vec4(strength,strength,strength,1);


效果图

依据length返回向量长度

1
2
float strength = length(vUv);
gl_FragColor =vec4(strength,strength,strength,1);

效果图

根据distance技术2个向量的距离

1
2
float strength =1.0 - distance(vUv,vec2(0.5,0.5));
gl_FragColor =vec4(strength,strength,strength,1);

效果图

根据相除,实现星星

1
2
float strength =0.15 / distance(vUv,vec2(0.5,0.5)) - 1.0;
gl_FragColor =vec4(strength,strength,strength,strength);

效果图

设置vUv水平或者竖直变量

1
2
float strength =0.15 / distance(vec2(vUv.x,(vUv.y-0.5)*5.0),vec2(0.5,0.5)) - 1.0;
gl_FragColor =vec4(strength,strength,strength,strength);

效果图

十字交叉的星星

1
2
float strength =0.15 / distance(vec2(vUv.x,(vUv.y-0.5)*5.0),vec2(0.5,0.5)) - 1.0;
gl_FragColor =vec4(strength,strength,strength,strength);

效果图

旋转飞镖,旋转uv

1
2
3
4
vec2 rotateUv = rotate(vUv,-uTime*5.0,vec2(0.5));
float strength = 0.15 / distance(vec2(rotateUv.x,(rotateUv.y-0.5)*5.0+0.5),vec2(0.5,0.5)) - 1.0;
strength += 0.15 / distance(vec2(rotateUv.y,(rotateUv.x-0.5)*5.0+0.5),vec2(0.5,0.5)) - 1.0;
gl_FragColor =vec4(strength,strength,strength,strength);

效果图

狗皮膏药

1
2
float strength = step(0.5,distance(vUv,vec2(0.5))+0.25) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

绘制圆

1
2
float strength = 1.0 - step(0.5,distance(vUv,vec2(0.5))+0.25) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

圆环

1
2
3
float strength = step(0.5,distance(vUv,vec2(0.5))+0.35) ;
strength *= (1.0 - step(0.5,distance(vUv,vec2(0.5))+0.25)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

渐变环

1
2
float strength =  abs(distance(vUv,vec2(0.5))-0.25) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

打靶

1
2
float strength = step(0.1,abs(distance(vUv,vec2(0.5))-0.25))   ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

圆环

1
2
float strength = 1.0 - step(0.1,abs(distance(vUv,vec2(0.5))-0.25))   ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

波浪环1

1
2
3
4
5
6
vec2 waveUv = vec2(
vUv.x,
vUv.y+sin(vUv.x*30.0)*0.1
);
float strength = 1.0 - step(0.01,abs(distance(waveUv,vec2(0.5))-0.25)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

波浪环2

1
2
3
4
5
6
vec2 waveUv = vec2(
vUv.x+sin(vUv.y*30.0)*0.1,
vUv.y+sin(vUv.x*30.0)*0.1
);
float strength = 1.0 - step(0.01,abs(distance(waveUv,vec2(0.5))-0.25)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

波浪环3

1
2
3
4
5
6
   vec2 waveUv = vec2(
vUv.x+sin(vUv.y*100.0)*0.1,
vUv.y+sin(vUv.x*100.0)*0.1
);
float strength = 1.0 - step(0.01,abs(distance(waveUv,vec2(0.5))-0.25)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

根据角度显示视图

1
2
3
float angle = atan(vUv.x,vUv.y);
float strength = angle;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

根据角度实现螺旋渐变

1
2
3
float angle = atan(vUv.x-0.5,vUv.y-0.5);
float strength = (angle+3.14)/6.28;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

实现雷达扫射

1
2
3
4
float alpha =  1.0 - step(0.5,distance(vUv,vec2(0.5)));
float angle = atan(vUv.x-0.5,vUv.y-0.5);
float strength = (angle+3.14)/6.28;
gl_FragColor =vec4(strength,strength,strength,alpha);

效果图

通过时间实现动态

1
2
3
4
5
6
7
8
9
10
11
12
vec2 rotate(vec2 uv, float rotation, vec2 mid)
{
return vec2(
cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x,
cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y
);
}
vec2 rotateUv = rotate(vUv,-uTime*5.0,vec2(0.5));
float alpha = 1.0 - step(0.5,distance(vUv,vec2(0.5)));
float angle = atan(rotateUv.x-0.5,rotateUv.y-0.5);
float strength = (angle+3.14)/6.28;
gl_FragColor =vec4(strength,strength,strength,alpha);

效果图

万花筒

define PI 3.1415926535897932384626433832795

1
2
3
4
float angle = atan(vUv.x-0.5,vUv.y-0.5)/PI;
float strength = mod(angle*10.0,1.0);

gl_FragColor =vec4(strength,strength,strength,1);

效果图

光芒四射

define PI 3.1415926535897932384626433832795

1
2
3
4
float angle = atan(vUv.x-0.5,vUv.y-0.5)/(2.0*PI);
float strength = sin(angle*100.0);

gl_FragColor =vec4(strength,strength,strength,1);

效果图

使用噪声实现烟雾、波纹效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 噪声函数
float noise (in vec2 _st) {
vec2 i = floor(_st);
vec2 f = fract(_st);

// Four corners in 2D of a tile
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));

vec2 u = f * f * (3.0 - 2.0 * f);

return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float strength = step(0.5,noise(vUv * 100.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

根据时间设置波形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
vec4 permute(vec4 x)
{
return mod(((x*34.0)+1.0)*x, 289.0);
}

vec2 fade(vec2 t)
{
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
float cnoise(vec2 P)
{
vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation
vec4 ix = Pi.xzxz;
vec4 iy = Pi.yyww;
vec4 fx = Pf.xzxz;
vec4 fy = Pf.yyww;
vec4 i = permute(permute(ix) + iy);
vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024...
vec4 gy = abs(gx) - 0.5;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;
vec2 g00 = vec2(gx.x,gy.x);
vec2 g10 = vec2(gx.y,gy.y);
vec2 g01 = vec2(gx.z,gy.z);
vec2 g11 = vec2(gx.w,gy.w);
vec4 norm = 1.79284291400159 - 0.85373472095314 * vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
float n00 = dot(g00, vec2(fx.x, fy.x));
float n10 = dot(g10, vec2(fx.y, fy.y));
float n01 = dot(g01, vec2(fx.z, fy.z));
float n11 = dot(g11, vec2(fx.w, fy.w));
vec2 fade_xy = fade(Pf.xy);
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return 2.3 * n_xy;
}
float strength = step(uScale,cnoise(vUv * 10.0+uTime)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

发光路径

1
2
3

float strength = abs(cnoise(vUv * 10.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

1
2
3

float strength = 1.0-abs(cnoise(vUv * 10.0)) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

波纹效果

1
2
float strength = sin(cnoise(vUv * 10.0)*5.0+uTime) ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

1
2
float strength = step(0.9,sin(cnoise(vUv * 10.0)*20.0))  ;
gl_FragColor =vec4(strength,strength,strength,1);

效果图

使用混合函数混颜色

1
2
3
4
5
6
7
8
9
vec3 purpleColor = vec3(1.0, 0.0, 1.0);
vec3 greenColor = vec3(1.0, 1.0, 1.0);
vec3 uvColor = vec3(vUv,1.0);
float strength = step(0.9,sin(cnoise(vUv * 10.0)*20.0)) ;


vec3 mixColor = mix(greenColor,uvColor,strength);
// gl_FragColor =vec4(mixColor,1.0);
gl_FragColor =vec4(mixColor,1.0);

效果图

拖更了几天的货,是不是很大,哈哈,今天就分享到这里了,下次再见。

上一篇:
【可视化学习】14-漫天孔明灯
下一篇:
百度地图右击添加点标记