概述
简单的扩散墙效果
shader
js
const vertexShader = `
uniform vec3 u_color;
uniform float time;
uniform float u_height;
varying float v_opacity;
void main() {
vec3 vPosition = position * mod(time, 1.0);
v_opacity = mix(1.0, 0.0, position.y / u_height);
gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}
`;
const fragmentShader = `
uniform vec3 u_color;
uniform float u_opacity;
varying float v_opacity;
void main() {
gl_FragColor = vec4(u_color, v_opacity * u_opacity);
}
`;解析
通过对时间不断取余,获取一个0~1之间不断变化的值,使顶点随时间不短变化。
class
js
export default class Wall extends THREE.Mesh {
constructor(option = {}) {
super();
this.init(option);
}
init(option) {
const {
radius = 50,
height = 100,
opacity = 1,
color = "#fff",
speed = 1,
position = {
x: 0,
y: 0,
z: 0
},
rotation = {
x: -Math.PI / 2,
y: 0,
z: 0
}
} = option;
const geometry = new THREE.CylinderGeometry(radius, radius, height, 32, 1, true);
geometry.translate(0, height / 2, 0);
const material = new THREE.ShaderMaterial({
uniforms: {
u_height: {
value: height
},
u_speed: {
value: speed
},
u_opacity: {
value: opacity
},
u_color: {
value: new THREE.Color(color)
},
time: {
value: 0
}
},
transparent: true,
depthWrite: false,
depthTest: false,
side: THREE.DoubleSide,
vertexShader: vertexShader,
fragmentShader: fragmentShader
});
this.position.set(position.x, position.y, position.z);
this.rotation.set(rotation.x, rotation.y, rotation.z);
this.geometry = geometry;
this.material = material;
this.rotateX(Math.PI / 2);
}
update(time) {
this.material.uniforms.time.value += time;
}
}