Skip to content

概述

简单的扩散墙效果

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;
    }
}

更新于:

夜茶 2020 ~ 2026