Three.js/Shader墙体渐变透明特效

在这里插入图片描述

生成方法

  • 通过Shader实现透明墙体效果
  • 通过路径解析算法生成不规则墙体
  • 支持颜色/高度/透明度/动画配置
	 /**
       * 创建透明墙体材质
       * option =>
       * params height color opacity speed
       * **/
      const createOpacityWallMat = ({
        height = 10,
        color = "#00ffff",
        opacity = 0.5,
        speed = 1,
      }) => {
        // 顶点着色器
        const vertexShader = `
          uniform vec3 u_color;

          uniform float time;
          uniform float u_height;
          varying float v_opacity;

          void main() {
              vec3 vPosition = position;
              v_opacity = mix(1.0, 0.0, position.y / u_height * 1.0) * (1.0 + sin(time) * 0.5);
              gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1);
          }
       `;
        // 片元着色器
        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);
          }
        `;

        return new THREE.ShaderMaterial({
          uniforms: {
            u_height: {
              value: height,
            },
            u_opacity: {
              value: opacity,
            },
            u_color: {
              value: new THREE.Color(color),
            },
            time: {
              value: 0,
            },
            speed: {
              value: speed,
            },
          },
          transparent: true,
          depthWrite: false,
          depthTest: false,
          side: THREE.DoubleSide,
          vertexShader: vertexShader,
          fragmentShader: fragmentShader,
        });
      };

使用

路径解析算法见我的另一篇文章 Three.js通过不规则路径生成墙体

	/ // 路径
      const path = [
        [80, 0, -40],
        [10, 0, 0],
        [60, 0, 50],
        [0, 0, 0],
        [-60, 0, 50],
        [-50, 0, -30],
        [80, 0, -40],
      ];
      const material = createOpacityWallMat({ height: 15, speed: 5 });
      const wallMesh = creatWallByPath({
        path,
        material,
        height: 15,
      });
      // 动画
      animationList.push(() => {
        wallMesh.material.uniforms.time.value +=
        clock.getDelta() * wallMesh.material.uniforms.speed.value;
      });
      scene.add(wallMesh);

效果

路径
在这里插入图片描述
动画效果
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐