webgl着色器学习 - 绘制多个不同颜色圆形并且不断变换颜色位置
·
动态

在three.js中每帧更新时间参数
three.js
/*
* @Author: hongbin
* @Date: 2022-10-01 18:31:26
* @LastEditors: hongbin
* @LastEditTime: 2022-10-02 16:04:40
* @Description:绘制一个圆形
*/
import * as THREE from "three";
import vertexShader from "../../shader/circular.vt.glsl";
import fragmentShader from "../../shader/circular.fs.glsl";
export const drawCircular = () => {
const clock = new THREE.Clock();
const uniforms = {
time: { value: clock.getElapsedTime() },
};
const box = new THREE.Mesh(
new THREE.BoxGeometry(5, 6, 10, 20, 20, 20),
new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
uniforms,
})
);
frameLoop(() => {
uniforms.time.value = clock.getElapsedTime();
window.render();
});
return box;
};
const frameLoop = (script: () => void) => {
requestAnimationFrame(() => {
frameLoop(script);
});
script();
};
片元着色器
varying vec2 vUv;
varying vec3 vPosition;
uniform float time;
void circularRange(vec2 face, vec2 center, float r, float d, vec3 color, inout vec3 defColor) {
vec2 position = vec2(face.xy) - center;
if(length(position.xy) < r && length(position.xy) > d) {
// 圆环颜色
defColor = color;
}
}
void main() {
float val = (sin(time));
// 默认颜色
vec3 color = vec3(0.1, 0.1, val);
// 前后
circularRange(vPosition.xy, vec2(val, val), 1.0, 0.5, vec3(1.0, val, 0.42), color);
circularRange(vPosition.xy, vec2(val, -val), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
circularRange(vPosition.xy, vec2(-val, val), 1.0, 0.5, vec3(0.73, val, 0.1), color);
circularRange(vPosition.xy, vec2(-val, -val), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
// 上下
circularRange(vPosition.xz, vec2(1.0, 0.5), 1.0, 0.5, vec3(0.30, 0.5, 0.42), color);
circularRange(vPosition.xz, vec2(1.0, -1.5), 1.0, 0.5, vec3(0.2, 0.47, 0.1), color);
circularRange(vPosition.xz, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.13, 1, 0.1), color);
circularRange(vPosition.xz, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.6, 0.16, 1), color);
// 左右
circularRange(vPosition.zy, vec2(2.0, 0.5), 1.0, 0.5, vec3(2.0, 0.1, 0.42), color);
circularRange(vPosition.zy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
circularRange(vPosition.zy, vec2(-2.0, 1.5), 1.0, 0.5, vec3(1.73, 1, 0.1), color);
circularRange(vPosition.zy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
circularRange(vPosition.zy, vec2(-3.0, 1.5), 1.0, 0.5, vec3(0.1, 1, 0.63), color);
circularRange(vPosition.zy, vec2(-3.0, -1.5), 1.0, 0.5, vec3(0.52, 0.1, 1), color);
gl_FragColor = vec4(color, 1);
}
顶点着色器
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}
静态

绘制一个圆形案例
顶点着色器
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}
片元着色器
void circularRange(vec2 face, vec2 center, float r, float d, vec3 color, inout vec3 defColor) {
vec2 position = vec2(face.xy) - center;
if(length(position.xy) < r && length(position.xy) > d) {
// 圆环颜色
defColor = color;
}
}
void main() {
// 默认颜色
vec3 color = vec3(0.1, 0.1, 0.42);
// 前后
circularRange(vPosition.xy, vec2(1.0, 0.5), 1.0, 0.5, vec3(1.0, 0.1, 0.42), color);
circularRange(vPosition.xy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
circularRange(vPosition.xy, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.73, 1, 0.1), color);
circularRange(vPosition.xy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
// 上下
circularRange(vPosition.xz, vec2(1.0, 0.5), 1.0, 0.5, vec3(0.30, 0.5, 0.42), color);
circularRange(vPosition.xz, vec2(1.0, -1.5), 1.0, 0.5, vec3(0.2, 0.47, 0.1), color);
circularRange(vPosition.xz, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.13, 1, 0.1), color);
circularRange(vPosition.xz, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.6, 0.16, 1), color);
// 左右
circularRange(vPosition.zy, vec2(2.0, 0.5), 1.0, 0.5, vec3(2.0, 0.1, 0.42), color);
circularRange(vPosition.zy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
circularRange(vPosition.zy, vec2(-2.0, 1.5), 1.0, 0.5, vec3(1.73, 1, 0.1), color);
circularRange(vPosition.zy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
circularRange(vPosition.zy, vec2(-3.0, 1.5), 1.0, 0.5, vec3(0.1, 1, 0.63), color);
circularRange(vPosition.zy, vec2(-3.0, -1.5), 1.0, 0.5, vec3(0.52, 0.1, 1), color);
gl_FragColor = vec4(color, 1);
}
应用到three.js中
/*
* @Author: hongbin
* @Date: 2022-10-01 18:31:26
* @LastEditors: hongbin
* @LastEditTime: 2022-10-01 21:04:21
* @Description:绘制圆形
*/
import * as THREE from "three";
import vertexShader from "../../shader/circular.vt.glsl";
import fragmentShader from "../../shader/circular.fs.glsl";
export const drawCircular = () => {
const box = new THREE.Mesh(
new THREE.BoxGeometry(5, 6, 10, 20, 20, 20),
new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
})
);
return box;
};
更多推荐
所有评论(0)