three+webgl实现2025新年快乐文字灵光动画效果代码

代码语言:html

所属分类:动画

代码描述:three+webgl实现2025新年快乐文字灵光动画效果代码

代码标签: three webgl 2025 新年 快乐 文字 灵光 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">

  
  
<style>
body{
  overflow: hidden;
  margin: 0;
}
</style>


  
  
</head>

<body translate="no">
      
    <script type="importmap">
  {
    "imports": {
      "three": "//repo.bfw.wiki/bfwrepo/js/module/three/build/171/three.module.js",
    
      "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/171/jsm/"
    }
  }
</script>

<script>
  let rotations = `
    // https://forum.gamemaker.io/index.php?threads/solved-3d-rotations-with-a-shader-matrix-or-a-matrix-glsl-es.61064/
      mat4 rx(float a) {
        return mat4( 1.0, 0.0, 0.0, 0.0,
                     0.0,cos(a),sin(a), 0.0,
                     0.0,-sin(a),cos(a), 0.0,
                     0.0, 0.0, 0.0, 1.0);
      }

      mat4 ry(float a){
        return mat4( cos(a),0.0, -sin(a), 0.0,
                     0.0, 1.0, 0.0, 0.0,
                     sin(a), 0.0, cos(a), 0.0,
                     0.0,0.0,0.0,1.0);
      }
               
      mat4 rz(float a){
        return mat4( cos(a), sin(a), 0.0, 0.0,
                     -sin(a), cos(a), 0.0, 0.0,
                     0.0        , 0.0       ,1.0 ,0.0,
                     0.0        , 0.0       ,0.0 ,1.0);
      }
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      mat4 rotationXYZ(vec3 angles){
        return rz(angles.z) * ry(angles.y) * rx(angles.x);
      }
  `;
</script>
  
      <script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import { VignetteShader } from 'three/addons/shaders/VignetteShader.js';
import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShader.js';

console.clear();

window.addEventListener("dblclick", () => {
  if(!document.fullscreenElement){
    document.documentElement.requestFullscreen();
  }else{
    document.exitFullscreen();
  }
});

// load fonts
await (async function () {
  async function loadFont(fontface) {
    await fontface.load();
    document.fonts.add(fontface);
  }
  let fonts = [
    new FontFace(
      "Limelight",
      "url(https://fonts.gstatic.com/s/limelight/v19/XLYkIZL7aopJVbZJHDuoNOlH.woff2) format('woff2')"
    ),
    new FontFace(
      "BerkshireSwash",
      "url(https://fonts.gstatic.com/s/berkshireswash/v20/ptRRTi-cavZOGqCvnNJDl5m5XmN_qs4z.woff2) format('woff2')"
    )
  ];
  for (let font in fonts) {
    await loadFont(fonts[font]);
  }
})();

class Postprocessing extends EffectComposer{
  constructor(){
    super(renderer, new THREE.WebGLRenderTarget(innerWidth, innerHeight, {samples: 4}));
    
    let renderPass = new RenderPass(scene, camera);
    let effectVignette = new ShaderPass(VignetteShader);
        effectVignette.uniforms[ 'offset' ].value = 0.2;
	      effectVignette.uniforms[ 'darkness' ].value = 10;
    let gammaCorrection = new ShaderPass( GammaCorrectionShader );
    
    //console.log(effectVignette.material);
    effectVignette.material.onBeforeCompile = shader => {
      shader.uniforms.time = gu.time;
      shader.uniforms.aspect = gu.aspect;
      shader.uniforms.texWriting = {
        value: (() => {
          let c = document.createElement("canvas");
          c.width = 2048;
          c.height = 512;
          let ctx = c.getContext("2d");
          let u = val => val * c.height * 0.01;
          
          ctx.fillStyle = `rgba(255, 255, 255, 0.5)`;
          ctx.strokeStyle = `rgba(255, 255, 255, 1)`;
          ctx.lineWidth = u(2);
          ctx.font = `${u(45)}px BerkshireSwash`;
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";
          
          //ctx.strokeRect(0, 0, c.width, c.height);
          ctx.strokeText("Happy New Year!", c.width * 0.5, c.height * 0.5);
          ctx.fillText("Happy New Year!", c.width * 0.5, c.height * 0.5);
          
          let tex = new THREE.CanvasTexture(c);
          tex.colorSpace = "srgb";
          
          return tex;
        })()
      }
      
      shader.fragmentShader = `
        uniform float time;
        uniform float aspect;
        uniform sampler2D texWriting;
        
        vec2 N22(vec2 p){
          vec3 a = fract(p.xyx * vec3(123.45, 234.56, 345.67));
          a += dot(a, a+45.69);
          return fract(vec2(a.x * a.y, a.y * a.z));
        }
        ${shader.fragmentShader}
      `.replace(
        `gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );`,
        `gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );
        
        vec2 texUV = (vUv - 0.5) * vec2(aspect, 4.) + 0.5;
        texUV.y += 1.7;

        float col = texture(texWriting, texUV).a;
        
        gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.9875, 1, 1) * 0.9, col);
        
        `
      );
      console.log(shader.fragmentShader);
    }
    
    this.addPass(renderPass);
    this.addPass(gammaCorrection);
    this.addPass(effectVignette);
  }
}

class BackShards extends THREE.LineSegments{
  constructor(){
    let g = new THREE.InstancedBufferGeometry().copy(
      new THREE.EdgesGeometry(new THREE.TetrahedronGeometry())
    );
    g.instanceCount = 100;
    let v = new THREE.Vector3();
    g.setAttribute("instPos", new THREE.InstancedBufferAttribute(
      new Float32Array(
        Array.from({length: g.instanceCount}, () => {
          v.random().subScalar(0.5).multiply(new THREE.Vector3(40, 20, 0));
          return [v.x, v.y, v.z];
        }).flat()
      )
      ,3
    ));
    g.setAttribute("instRotPhase", new THREE.InstancedBufferAttribute(
      new Float32Array(
        Array.from({length: g.instanceCount}, () => {
          v.random().subScalar(0.5).multiplyScalar(2);
          return [v.x, v.y, v.z];
        }).flat()
      )
      ,3
    ));
    g.setAttribute("instRotSpeed", new THREE.InstancedBufferAttribute(
      new Float32Array(
        Array.from({length: g.instanceCount}, () => {
          v.random().multiplyScalar(0.1).addScalar(0.1).multiplyScalar(2);
          return [v.x, v.y, v.z];
        }).flat()
      )
      ,3
    ));
    
    let m = new THREE.LineBasicMaterial({
      color: 0x003377,
      onBeforeCompile: shader => {
        shader.uniforms.time = gu.time;
        shader.vertexShader = `
          uniform float time;
          
          attribute vec3 instPos;
          attribute vec3 instRotPhase;
          attribute vec3 instRotSpeed;
          
          ${rotations}
          ${shader.vertexShader}
        `.replace(
          `#include <begin_vertex>`,
          `#include <begin_vertex>
          
            mat4 rotXYZ = rotationXYZ((instRotPhase + instRotSpeed * time * 1. * normalize(instRotPhase)) * ${Math.PI});
            
            transformed = vec3(rotXYZ * vec4(transformed, 1.));
            transformed += instPos;
          `
        );
        //console.log(shader.vertexShader);
      }
    });
    
    super(g, m);
  }
  
  update(){
    camera.getWorldDirection(this.position);
    this.position.setLength(22).add(camera.position);
    this.quaternion.copy(camera.quaternion);
  }
}

class Shards extends THREE.Mesh{
  constructor(){
    super();
    
    let g = new THREE.InstancedBufferGeometry().copy(new THREE.TetrahedronGeometry());
    g.instanceCount = 10000;
    let v = new THREE.Vector3();
    g.setAttribute("center", new THREE.Float32BufferAttribute(
      [
        1, 0, 0, 0, 1, 0, 0, 0, 1,
        1, 0, 0, 0, 1, 0, 0, 0, 1,
        1, 0, 0, 0, 1, 0, 0, 0, 1,
        1, 0, 0, 0, 1, 0, 0, 0, 1
      ],
      3
    ));
    g.setAttribute("instPos", new THREE.InstancedBufferAttribute(
      new Float32Array(
        Array.from({length: g.instanceCount}, () => {
          let a = Math.random() * Math.PI * 2;
          v.set(
            Math.cos(a),
            Math.sin(a),
            Math.random()
          );
          return [v.x, v.y, v.z];
        }).flat()
      )
      ,3
    ));
    g.s.........完整代码请登录后点击上方下载按钮下载查看

网友评论0