three实现三维粒子跟随音乐跳动音频可视化效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维粒子跟随音乐跳动音频可视化效果代码
代码标签: three 三维 粒子 跟随 音乐 跳动 音频 可视化
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> html, body { margin: 0; overflow: hidden; font-family: sans-serif; background: #13091B; height: 100%; } #three-container { position: absolute; left: 0; top: 0; } .container { display: flex; align-items: center; justify-content: center; height: 100%; } .play-btn { color: #13091B; background: #007A99; display: inline-block; padding: 16px 48px; font-size: 18px; cursor: pointer; border-radius: 4px; letter-spacing: 0.1em; z-index: 1; } </style> </head> <body > <audio id="song" src="" style="display:none;"></audio> <div class="container"> <div class="play-btn">PLAY</div> </div> <div id="three-container"></div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.72.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.72.js"></script> <script > var mContainer; var mCamera, mRenderer; var mControls; var mShadowColor = 0x13091B; //0x1B0914 var mScene; var mLight; var mLight2; var mLight3; var mUseAA = true; var mParticleCount = 250000; var mParticleSystem; var mDuration; var mPathLength = 32; var mAudioElement = document.getElementById('song'); var mAnalyser; var mPlayBtn = document.querySelector('.play-btn'); var mPlayBtnContainer = document.querySelector('.container'); mPlayBtn.addEventListener('click', function () { mAnalyser.context.resume().then(() => { console.log('Playback resumed successfully'); }); mPlayBtnContainer.style.display = 'none'; mAudioElement.currentTime = 0; mAudioElement.play(); mCamera.position.set(0, 0, 1200); }); mAudioElement.addEventListener('ended', function () { mPlayBtnContainer.style.display = 'flex'; }); window.onload = function () { init(); }; function init() { initAudio(); initTHREE(); initControls(); initParticleSystem(); requestAnimationFrame(tick); window.addEventListener('resize', resize, false); } function initAudio() { mAudioElement.crossOrigin = "anonymous"; mAudioElement.src = '//repo.bfw.wiki/bfwrepo/sound/63e1f2ab02799.mp3'; mAnalyser = new SpectrumAnalyzer(mPathLength * 0.5, 0.80); mAnalyser.setSource(mAudioElement); } function initTHREE() { mRenderer = new THREE.WebGLRenderer({ antialias: mUseAA }); mRenderer.setSize(window.innerWidth, window.innerHeight); //mRenderer.setClearColor(0xffffff); mRenderer.setClearColor(mShadowColor); mContainer = document.getElementById('three-container'); mContainer.appendChild(mRenderer.domElement); mCamera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 5000); mCamera.position.set(0, 0, 1200); mScene = new THREE.Scene(); mLight = new THREE.PointLight(0xffffff, 1, 1200, 2); mLight.position.set(0, 0, 0); mScene.add(mLight); mLight2 = new THREE.DirectionalLight(0xFF311F, 0.25); mLight2.position.set(0, 1, 1); mScene.add(mLight2); mLight3 = new THREE.DirectionalLight(0x007A99, 0.25); mLight3.position.set(0, 1, -1); mScene.add(mLight3); } function initControls() { mControls = new THREE.OrbitControls(mCamera, mRenderer.domElement); mControls.autoRotate = true; mControls.enableZoom = true; mControls.enablePan = false; mControls.constraint.minDistance = 10; mControls.constraint.maxDistance = 1200; mControls.constraint.minPolarAngle = Math.PI * 0.4; mControls.constraint.maxPolarAngle = Math.PI * 0.6; } function initParticleSystem() { var prefabGeometry = new THREE.PlaneGeometry(4, 4); var bufferGeometry = new THREE.BAS.PrefabBufferGeometry(prefabGeometry, mParticleCount); //bufferGeometry.computeVertexNormals(); // generate additional geometry data var aDelayDuration = bufferGeometry.createAttribute('aDelayDuration', 2); var aPivot = bufferGeometry.createAttribute('aPivot', 3); var aAxisAngle = bufferGeometry.createAttribute('aAxisAngle', 4); var aColor = bufferGeometry.createAttribute('color', 3); var i, j, offset; // buffer time offset var delay; var duration; var prefabDelay = 0.00015; var vertexDelay = 0.0175; var minDuration = 32.0; var maxDuration = 56.5; mDuration = maxDuration + prefabDelay * mParticleCount + vertexDelay * prefabGeometry.vertices.length; for (i = 0, offset = 0; i < mParticleCount; i++) { delay = i * prefabDelay; duration = THREE.Math.randFloat(minDuration, maxDuration); for (j = 0; j < prefabGeometry.vertices.length; j++) { aDelayDuration.array[offset++] = delay + j * vertexDelay; aDelayDuration.array[offset++] = duration; } } // buffer pivot var pivot = new THREE.Vector3(); for (i = 0, offset = 0; i < mParticleCount; i++) { pivot.x = THREE.Math.randFloat(0, 2); pivot.y = THREE.Math.randFloat(0, 2); pivot.z = THREE.Math.randFloat(0, 2); for (j = 0; j < prefabGeometry.vertices.length; j++) { aPivot.array[offset++] = pivot.x; aPivot.array[offset++] = pivot.y; aPivot.array[offset++] = pivot.z; } } // buffer axis angle var axis = new THREE.Vector3(); var angle = 0; for (i = 0, offset = 0; i < mParticleCount; i++) { axis.x = THREE.Math.randFloatSpread(2); axis.y = THREE.Math.randFloatSpread(2); axis.z = THREE.Math.randFloatSpread(2); axis.normalize(); angle = Math.PI * THREE.Math.randInt(48, 64); for (j = 0; j < prefabGeometry.vertices.length; j++) { aAxisAngle.array[offset++] = axis.x; aAxisAngle.array[offset++] = axis.y; aAxisAngle.array[offset++] = axis.z; aAxisAngle.array[offset++] = angle; } } // buffer color var color = new THREE.Color(); var h, s, l; for (i = 0, offset = 0; i < mParticleCount; i++) { //h = i / mParticleCount; h = THREE.Math.randFloat(0.5, 1.00); s = THREE.Math.randFloat(0.5, 0.75); l = THREE.Math.randFloat(0.25, 0.5); color.setHSL(h, s, l); for (j = 0; j < prefabGeometry.vertices.length; j++) { aColor.array[offset++] = color.r; aColor.array[offset++] = color.g; aColor.array[offset++] = color.b; } } // buffer spline (uniform) var pathArray = []; var radiusArray = []; var length = mPathLength; var x, y, z; for (i = 0; i < length; i++) { if (!i) { x = 0; y = -1400; z = 0; } else if (!(i - length + 1)) { x = 0; y = 1200; z = 0; } else { x = THREE.Math.randFloatSpread(600); y = -400 + 800 / length * i + THREE.Math.randFloatSpread(200); z = THREE.Math.randFloatSpread(600); } pathArray.push(x, y, z); radiusArray.push(0); } var material = new THREE.BAS.PhongAnimationMaterial( // custom parameters & THREE.MeshPhongMaterial parameters { vertexColors: THREE.VertexColors, shading: THREE.FlatShading, side: THREE.DoubleSide, defines: { PATH_LENGTH: pathArray.length / 3 }, uniforms: { uTime: { type: 'f', value: 0 }, uPath: { type: 'fv', value: pathArray }, uRadius: { type: 'fv1', value: radiusArray }, uRoundness: { type: 'v2', value: new THREE.Vector2(2, 2) } }, shaderFunctions: [ THREE.BAS.ShaderChunk['quaternion_rotation'], THREE.BAS.ShaderChunk['catmull-rom'], THREE.BAS.ShaderChunk['ease_in_out_cubic']], shaderParameters: [ 'uniform float uTime;', 'uniform vec3 uPath[PATH_LENGTH];', 'uniform float uRadius[PATH_LENGTH];', 'uniform vec2 uRoundness;', 'attribute vec2 aDelayDuration;', 'attribute vec3 aPivot;', 'attribute vec4 aAxisAngle;'], shaderVertexInit: [ 'float tDelay = aDelayDuration.x;', 'float tDuration = aDelayDuration.y;', 'float tTime = clamp(uTime - tDelay, 0.0, tDuration);', 'float tProgress = tTime / tDuration;', 'float angle = aAxisAngle.w * tProgress;', 'vec4 tQuat = quatFromAxisAngle(aAxisAngle.xyz, angle);'], shaderTransformNormal: [ 'objectNormal = rotateVector(tQuat, objectNormal);'], shaderTransformPosition: [ 'float tMax = float(PATH_LENGTH - 1);', 'float tPoint = tMax * tProgress;', 'float tIndex = floor(tPoint);', 'float tWeight = tPoint - tIndex;', 'int i0 = int(max(0.0, tIndex - 1.0));', 'int i1 = int(tIndex);', 'int i2 = int(min(tIndex + 1.0, tMax));', 'int i3 = int(min(tIndex + 2.0, tMax));', 'vec3 p0 = uPath[i0];', 'vec3 p1 = uPath[i1];'.........完整代码请登录后点击上方下载按钮下载查看
网友评论0