three实现一个三维唱片碟片旋转播放曲线乐章效果代码

代码语言:html

所属分类:三维

代码描述:three实现一个三维唱片碟片旋转播放曲线乐章效果代码

代码标签: three 三维 唱片 碟片 旋转 播放 曲线 乐章

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

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

<head>

  <meta charset="UTF-8">
  

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



</head>

<body  >
    <script  async type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.2.js"></script>

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


  
      <script  type="module">
import * as THREE from "three";
import {OrbitControls} from "three/addons/controls/OrbitControls.js";
import {mergeBufferGeometries} from "three/addons/utils/BufferGeometryUtils.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 { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';

console.clear();

class Postprocessing {
  constructor(scene, camera, renderer) {
    const renderScene = new RenderPass(scene, camera);
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      1.25,
      0.25,
      0
    );
    let samples = 4;
    const target1 = new THREE.WebGLRenderTarget(
      window.innerWidth,
      window.innerHeight,
      {
        type: THREE.FloatType,
        format: THREE.RGBAFormat,
        encoding: THREE.sRGBEncoding,
        samples: samples
      }
    );
    this.bloomComposer = new EffectComposer(renderer, target1);
    this.bloomComposer.renderToScreen = false;
    this.bloomComposer.addPass(renderScene);
    this.bloomComposer.addPass(bloomPass);
    const finalPass = new ShaderPass(
      new THREE.ShaderMaterial({
        uniforms: {
          baseTexture: { value: null },
          bloomTexture: { value: this.bloomComposer.renderTarget2.texture }
        },
        vertexShader: `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`,
        fragmentShader: `uniform sampler2D baseTexture; uniform sampler2D bloomTexture; varying vec2 vUv; void main() { gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) ); }`,
        defines: {}
      }),
      "baseTexture"
    );
    finalPass.needsSwap = true;
    const target2 = new THREE.WebGLRenderTarget(
      window.innerWidth,
      window.innerHeight,
      {
        type: THREE.FloatType,
        format: THREE.RGBAFormat,
        encoding: THREE.sRGBEncoding,
        samples: samples
      }
    );
    this.finalComposer = new EffectComposer(renderer, target2);
    this.finalComposer.addPass(renderScene);
    this.finalComposer.addPass(finalPass);
  }
}

class LightEmitterCurve extends THREE.Curve{
	constructor( radius, turns, height ) {
		super();
    this.radius = radius;
    this.height = height;
    this.turns = turns;
	}

	getPoint( t, optionalTarget = new THREE.Vector3() ) {

		return optionalTarget.setFromCylindricalCoords( this.radius, -Math.PI * 2 * this.turns * t, this.height * t );

	}

}

class LightEmitters extends THREE.Object3D{
  constructor(gu, count, maxR, height, turns, m){
    super();
    let gsBall = [];
    let gsEmitter = [];
    let start = maxR / 4;
    let totalWidth = maxR * 0.9 - start;
    let step = totalWidth / (count - 1);
    let v3 = new THREE.Vector3();
    let axis = new THREE.Vector3(0, 1, 0);
    for( let i = 0; i < count; i++){
      
      let shift = start + step * i;
      
      let gBall = new THREE.SphereGeometry(0.05, 64, 32, 0, Math.PI * 2, 0, Math.PI * 0.5);
      gBall.translate(0, 0, shift);
      gsBall.push(gBall);
      
      /*let gEmitter = new THREE.CylinderGeometry(0.03, 0.03, height, 16, 200);
      gEmitter.translate(shift, height * 0.5, 0);
      let pos = gEmitter.attributes.position;
      for(let i = 0; i < pos.count; i++){
        v3.fromBufferAttribute(pos, i);
        let ratio = v3.y / height;
        let angle = -ratio * Math.PI * 2 * turns;
        v3.applyAxisAngle(axis, angle);
        pos.setXYZ(i, v3.x, v3.y, v3.z);
      }
      gEmitter.computeVertexNormals();*/
      let lightEmitterCurve = new LightEmitterCurve(shift, turns, height);
      let gEmitter = new THREE.TubeGeometry(lightEmitterCurve, 200, 0.02, 16);
      gsEmitter.push(gEmitter);
    }
    
    let gBalls = mergeBufferGeometries(gsBall);
    let balls = new THREE.Mesh(gBalls, m.clone());
    balls.userData.nonGlowing = true;
    //balls.castShadow = true;
    this.add(balls);
    
    let gEmitters = mergeBufferGeometries(gsEmitter);
    let mEmitters = new THREE.MeshBasicMaterial({
      side: THREE.DoubleSide,
      color: new THREE.Color(1, 0.25, 0),
      onBeforeCompile: shader => {
        shader.uniforms.globalBloom = gu.globalBloom;
        shader.vertexShader = `
          varying vec3 vPos;
          ${shader.vertexShader}
        `.replace(
          `#include <begin_vertex>`,
          `#include <begin_vertex>
            vPos = position;
          `
.........完整代码请登录后点击上方下载按钮下载查看

网友评论0