three实现三维音频可视化频谱动画效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维音频可视化频谱动画效果代码,通过lil-gui可调节视觉参数,实现其他的动态效果。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> @import url('https://fonts.googleapis.com/css?family=Architects+Daughter|Orbitron'); * { margin: 0; padding: 0; } html, body { overflow: hidden; font-family:'Orbitron',sans-serif; font-size:14px; } /* dat.gui align to left */ .lil-gui.autoPlace{ right:auto !important; left:15px !important; } .Experience { position:relative; width:100vw; height:100vh; } .Experience > .Experience_Canvas { top:0; left:0; position:absolute; outline: none; filter:grayscale(0%); transition:filter 1s; } .Experience[loading = "true"] > .Experience_Canvas { filter:grayscale(90%); } .Experience_Panel { position:relative; border:1px solid #000022; background-color: rgba(30, 30, 90, 0.75); color:#FFFFFF; border-radius: 6px; box-shadow: 5px 5px 5px rgba(0,0,0, 0.5); } .Experience > .Experience_Loading { padding:0.6em; /* width:4em;*/ margin:auto; top: calc(50vh - 10px); height: 18px; display:none; font-family:'Orbitron',sans-serif; font-size:max(1.5vw, 1.5vh); } .Experience[loading = "true"] > .Experience_Loading { display:table; } /* Group of controls (fps, button logo, button full screen) */ .Experience_Controls { position:fixed; bottom :0; right:0; z-index:10000; } .Experience_Static, .Experience_Control { user-select: none; position:relative; width:48px; /*max(3.2vw, 3.2vh);*/ height:48px; /*max(3.2vw, 3.2vh);*/ margin-bottom:max(0.5vw, 0.5vh); margin-right:max(0.5vw, 0.5vh); padding:6px; /* padding:max(0.4vw, 0.4vh);*/ text-align: center; border:2px solid transparent; display: block; margin-left: auto; transition:border 0.4s; } .Experience_FPS { font-size:24px; } .Experience_TxtFPS { font-size:14px; } .Experience_Control:hover { border:2px solid rgb(234, 80, 78); cursor:pointer; } .Experience_Control > img { transition:transform 0.4s; width:48px; height:48px; position:relative; } .Experience_Control:hover > img { transform: scale(1.5, 1.5); } #restoreScreen { display:none; } #Logo { display: block; transition: width 0.33s ease-in; } /* Logo svg need to be fixed on the right, because of the letter logo animation */ #Logo img { position:absolute; right: 6px; } #Logo > * { pointer-events: none; } #Logo:hover { width:280px; } #Logo > #LogoText { position:absolute; bottom:14px; margin-top:3px; transition:0.4s; width:230px; /* 12 caracters * 400px */ font-size:24px; } #Logo > #LogoText > span { transition:0.33s cubic-bezier(.17,-0.42,0,1.15); opacity:0; position: relative; display: inline-block; color:#FFF; } #Logo:hover > #LogoText > span { position:relative; opacity:1; left:230px; animation: LogoAnimation 0.33s 0.33s cubic-bezier(.17,-0.42,0,1.15); animation-fill-mode:forwards; } /* Color rojo del 33 */ #Logo > #LogoText > span:nth-child(11), #Logo > #LogoText > span:nth-child(12) { color: rgb(234, 80, 78); } #Logo:hover > #LogoText > span:nth-child(1) { animation-delay: 0.55s; } #Logo:hover > #LogoText > span:nth-child(2) { animation-delay: 0.50s; } #Logo:hover > #LogoText > span:nth-child(3) { animation-delay: 0.45s; } #Logo:hover > #LogoText > span:nth-child(4) { animation-delay: 0.40s; } #Logo:hover > #LogoText > span:nth-child(5) { animation-delay: 0.35s; } #Logo:hover > #LogoText > span:nth-child(6) { animation-delay: 0.30s; } #Logo:hover > #LogoText > span:nth-child(7) { animation-delay: 0.25s; } #Logo:hover > #LogoText > span:nth-child(8) { animation-delay: 0.20s; } #Logo:hover > #LogoText > span:nth-child(9) { animation-delay: 0.15s; } #Logo:hover > #LogoText > span:nth-child(10) { animation-delay: 0.10s; } #Logo:hover > #LogoText > span:nth-child(11) { animation-delay: 0.05s; } #Logo:hover > #LogoText > span:nth-child(12) { animation-delay: 0.0s; } @keyframes LogoAnimation { 0% { left:230px; } 100% { left:0px; } } /* * Audio controls */ .Experience_AudioControls { user-select: none; position:fixed; display:flex; flex-flow: row; flex-direction:column; /* flex-wrap: wrap;*/ bottom:1vh; /* height:80px;*/ width:75vw; left:12.5vw; /* padding:0 0 min(1vw, 1vh) 0 0;*/ pointer-events: none; } .Experience_AudioControls label, .Experience_AudioControls button { font-size:14px !important; font-family:'Orbitron',sans-serif; } .Experience_AC_Play { /* margin:max(0.5vw, 0.5vh);*/ flex-basis:32px; } .Experience_AC_Play > button { width:62px; height:62px; border-radius: 100px; background-color: rgba(30, 30, 150, 1.0); cursor:pointer; color:#fff; transition:background-color 0.5s; pointer-events:all; } .Experience_AC_Play > button:hover { background-color: rgb(49, 49, 255); } .Experience_AC_Songs { flex: 3 0 10%; /* margin:max(0.5vw, 0.5vh);*/ position:relative; /* top:6px;*/ /* flex-basis:176px;*/ flex-basis:32px; } .Experience_AC_Songs > select { position:relative; left:5px; height: 22px; pointer-events:all; } .Experience_AC_Volume { flex-basis:32px; /* margin:max(0.5vw, 0.5vh);*/ /* flex-basis:150px;*/ } .Experience_AC_Volume > input { position:relative; left:5px; top:5px; pointer-events:all; } .Experience_AC_Time { flex-basis:32px; /* margin:max(0.5vw, 0.5vh);*/ } .Experience_AC_Time > input { position:relative; left:5px; top:5px; width: calc(100% - 10px); pointer-events:all; } .Experience td { color:#ffffff; text-shadow: 1px 1px #000000; } /* Pay & Pause buttons */ .Experience_Play, .Experience_Pause { position: fixed; margin-bottom: max(0.5vw, 0.5vh); margin-left: max(0.5vw, 0.5vh); bottom:0; } /* when play is true, play button is enabled, and pause button is disabled, when is false is the oposite */ .Experience_Play[play="false"], .Experience_Pause[play="true"] { display:none; } .Experience_SongInfo { position:fixed; margin-bottom: max(0.5vw, 0.5vh); margin-left: max(0.5vw, 0.5vh); bottom:70px; padding:12px; left:-500px; transition:left 0.4s cubic-bezier(.17,-0.42,0,1.15); } .Experience_SongInfo[visible="false"] { left:0px; animation: SongInfoAnimation 0.4s 5s cubic-bezier(.17,-0.42,0,1.15); animation-fill-mode:forwards; } .Experience_SongInfo td { padding: 4px; color:#CCCCCC; } .Experience_SongInfo a, .Experience_SongInfo a:visited { color:#FFFFFF; } @keyframes SongInfoAnimation { 0% { opacity:1; left:0px; } 100% { opacity:0; left:-300px; } } </style> <script> window.console = window.console || function(t) {}; </script> </head> <body > <!-- import THREE.js cdn --> <script 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/151/three.module.js", "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/151/jsm/" } } </script> <!-- lil.gui --> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/lil-gui.umd.min.js"></script> <link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/lil-gui.min.css"> <!-- Basic depth vertex shader with varying vUv --> <script id="DepthVertexShader" type="x-shader/x-vertex"> varying vec2 vUv; #include <common> #include <uv_pars_vertex> #include <displacementmap_pars_vertex> #include <morphtarget_pars_vertex> #include <skinning_pars_vertex> #include <logdepthbuf_pars_vertex> #include <clipping_planes_pars_vertex> varying vec2 vHighPrecisionZW; void main() { #include <uv_vertex> #include <skinbase_vertex> #ifdef USE_DISPLACEMENTMAP #include <beginnormal_vertex> #include <morphnormal_vertex> #include <skinnormal_vertex> #endif #include <begin_vertex> vUv = uv; #include <morphtarget_vertex> #include <skinning_vertex> #include <displacementmap_vertex> #include <project_vertex> #include <logdepthbuf_vertex> #include <clipping_planes_vertex> vHighPrecisionZW = gl_Position.zw; } </script> <!-- Floor Standard vertex shader--> <script id="FloorStandardVertexShader" type="x-shader/x-vertex"> uniform sampler2D uAudioTexture; //uniform float uTime; uniform float uAudioStrength; varying vec2 vUv; /* * Three.js globals */ #define STANDARD varying vec3 vViewPosition; #ifdef USE_TRANSMISSION varying vec3 vWorldPosition; #endif #include <common> #include <uv_pars_vertex> #include <displacementmap_pars_vertex> #include <color_pars_vertex> #include <fog_pars_vertex> #include <normal_pars_vertex> #include <morphtarget_pars_vertex> #include <skinning_pars_vertex> #include <shadowmap_pars_vertex> #include <logdepthbuf_pars_vertex> #include <clipping_planes_pars_vertex> /* * Three.js main */ void main() { #include <uv_vertex> #include <color_vertex> #include <morphcolor_vertex> #include <beginnormal_vertex> #include <morphnormal_vertex> #include <skinbase_vertex> #include <skinnormal_vertex> #include <defaultnormal_vertex> #include <normal_vertex> #include <begin_vertex> // Audio value on Y axis vec4 textureColor = texture2D(uAudioTexture, uv); transformed.z += textureColor.r * uAudioStrength; vUv = uv; /* * Three.js main end */ #include <morphtarget_vertex> #include <skinning_vertex> #include <displacementmap_vertex> #include <project_vertex> #include <logdepthbuf_vertex> #include <clipping_planes_vertex> vViewPosition = - mvPosition.xyz; #include <worldpos_vertex> #include <shadowmap_vertex> #include <fog_vertex> #ifdef USE_TRANSMISSION vWorldPosition = worldPosition.xyz; #endif } </script> <!-- Floor Depth vertex shader--> <script id="FloorDepthVertexShader" type="x-shader/x-vertex"> uniform sampler2D uAudioTexture; uniform float uAudioStrength; #include <common> #include <uv_pars_vertex> #include <displacementmap_pars_vertex> #include <morphtarget_pars_vertex> #include <skinning_pars_vertex> #include <logdepthbuf_pars_vertex> #include <clipping_planes_pars_vertex> varying vec2 vHighPrecisionZW; void main() { #include <uv_vertex> #include <skinbase_vertex> #ifdef USE_DISPLACEMENTMAP #include <beginnormal_vertex> #include <morphnormal_vertex> #include <skinnormal_vertex> #endif #include <begin_vertex> //vec4 audioValue = vec4(1.0); vec4 audioValue = texture2D(uAudioTexture, uv); if (uv.y > 0.5) { // Add the red channel intensity to the Y of the model transformed.y += audioValue.r * uAudioStrength; } else { transformed.y -= audioValue.r * uAudioStrength; } #include <morphtarget_vertex> #include <skinning_vertex> #include <displacementmap_vertex> #include <project_vertex> #include <logdepthbuf_vertex> #include <clipping_planes_vertex> vHighPrecisionZW = gl_Position.zw; } </script> <!-- Perlin Sun Depth fragment shader--> <script id="SSPerlinSunDepthFragmentShader" type="x-shader/x-fragment"> uniform sampler2D uAudioTexture; uniform float uAudioStrengthFreq; uniform float uAudioStrengthSin; uniform float uRadiusFreq; uniform float uRadiusSin; uniform float uTime; //uniform float uHover; uniform float uNoiseStrength; uniform float uNoiseSpeed; //uniform vec3 uColorFrequency; //uniform vec3 uColorSin; varying vec2 vUv; // Coordenadas UV del fragmento #define NPI 3.14159265 // idk what happens with THREE js PI, and im finishing for today... #define TAU PI * 2.0 // Classic Perlin 3D Noise // by Stefan Gustavson // vec4 permute(vec4 x) { return mod(((x*34.0)+1.0)*x, 289.0); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec3 fade(vec3 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } float cnoise(vec3 P){ vec3 Pi0 = floor(P); // Integer part for indexing vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 Pi0 = mod(Pi0, 289.0); Pi1 = mod(Pi1, 289.0); vec3 Pf0 = fract(P); // Fractional part for interpolation vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); vec4 iy = vec4(Pi0.yy, Pi1.yy); vec4 iz0 = Pi0.zzzz; vec4 iz1 = Pi1.zzzz; vec4 ixy = permute(permute(ix) + iy); vec4 ixy0 = permute(ixy + iz0); vec4 ixy1 = permute(ixy + iz1); vec4 gx0 = ixy0 / 7.0; vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; gx0 = fract(gx0); vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); vec4 sz0 = step(gz0, vec4(0.0)); gx0 -= sz0 * (step(0.0, gx0) - 0.5); gy0 -= sz0 * (step(0.0, gy0) - 0.5); vec4 gx1 = ixy1 / 7.0; vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; gx1 = fract(gx1); vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); vec4 sz1 = step(gz1, vec4(0.0)); gx1 -= sz1 * (step(0.0, gx1) - 0.5); gy1 -= sz1 * (step(0.0, gy1) - 0.5); vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); g000 *= norm0.x; g010 *= norm0.y; g100 *= norm0.z; g110 *= norm0.w; vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); g001 *= norm1.x; g011 *= norm1.y; g101 *= norm1.z; g111 *= norm1.w; float n000 = dot(g000, Pf0); float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); float n111 = dot(g111, Pf1); vec3 fade_xyz = fade(Pf0); vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } // Function to make a round rectangle when the 2d plane is hover /*vec4 borderRoundRect(vec4 currentColor, vec2 size, float radius) { vec2 position = vUv * size; vec2 rounded = vec2(clamp(position.x, radius, size.x - radius), clamp(position.y, radius, size.y - radius)); vec2 difference = position - rounded; float dist = length(difference); vec4 color = vec4(1.0, 1.0, 1.0, uHover); // Border color float borderSize = 0.015; // Border size float alpha = step(0.2, smoothstep(radius - borderSize, radius- borderSize, dist) - smoothstep(radius, radius + borderSize, dist)); color.a = alpha * uHover; // Its inside if (dist > radius - borderSize) { return color; } // Its outside return currentColor; }*/ // Make a circle with the frequency data vec4 circleFreq(vec4 currentColor, vec2 center, vec3 color) { vec2 pos = vec2(0.55, 0.5); float dist = length(vUv - pos); float rad = atan(vUv.y - pos.y, vUv.x - pos.x); float normAngle = 0.0; if (rad < 0.0) { normAngle = ((rad + NPI) / NPI); } else { normAngle = 1.0 - (1.0 + ((rad - NPI) / NPI)); } float audioValue = (texture2D(uAudioTexture, vec2(normAngle, 0.0)).r - 0.5) * .25 * uAudioStrengthFreq; // Perlin noise float strength = cnoise(vec3(rad * 2.0, dist * uNoiseStrength, uTime * uNoiseSpeed)) * uRadiusFreq * 0.1; if (dist - audioValue + strength < uRadiusFreq) { color.r += audioValue * 0.5; color.b += audioValue * 0.5; return vec4(color, 1.0); } return currentColor; } // // Make a circle with the time domain data vec4 circleSin(vec4 currentColor, vec2 center, vec3 color) { vec2 pos1 = vec2(0.4, 0.5); float dist = length(vUv - center); float rad = atan(vUv.y - center.y, vUv.x - center.x); float normAngle = 0.0; if (rad < 0.0) { normAngle = ((rad + NPI) / NPI); } else { normAngle = (1.0 + ((rad - NPI) / NPI)); } float audioValue = (texture2D(uAudioTexture, vec2(normAngle, 0.0)).g - 0.5) * .5 * uAudioStrengthSin; // Perlin noise float strength = 0.0; //cnoise(vec3(rad * TAU * 5.0, dist * 100.0, uTime + color.b)) * radius * 0.1; if (dist - audioValue + strength < uRadiusSin) { color.g += 1.0 - audioValue; return vec4(color, 1.0); } return currentColor; } #if DEPTH_PACKING == 3200 uniform float opacity; #endif #include <common> #include <packing> #include <uv_pars_fragment> #include <map_pars_fragment> #include <alphamap_pars_fragment> #include <alphatest_pars_fragment> #include <logdepthbuf_pars_fragment> #include <clipping_planes_pars_fragment> varying vec2 vHighPrecisionZW; void main() { #include <clipping_planes_fragment> vec4 diffuseColor = vec4( 1.0 ); #if DEPTH_PACKING == 3200 diffuseColor.a = opacity; #endif // Center of the plane vec2 center = vec2(0.5, 0.5); // Base color vec4 color = vec4(0.0, 0.0, 0.0, 0.0); color = circleFreq(color, center, vec3(1.0)); color = circleSin(color, center, vec3(1.0)); diffuseColor = color; if (color.a == 0.0) discard; #include <map_fragment> #include <alphamap_fragment> #include <alphatest_fragment> #include <logdepthbuf_fragment> float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5; #if DEPTH_PACKING == 3200 gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity ); #elif DEPTH_PACKING == 3201 gl_FragColor = packDepthToRGBA( fragCoordZ ); #endif } </script> <!-- Perlin Sun fragment shader--> <script id="SSPerlinSunFragmentShader" type="x-shader/x-fragment"> uniform sampler2D uAudioTexture; uniform float uAudioStrengthFreq; uniform float uAudioStrengthSin; uniform float uRadiusFreq; uniform float uRadiusSin; uniform float uTime; uniform float uNoiseStrength; uniform float uNoiseSpeed; varying vec2 vUv; // Coordenadas UV del fragmento #define PI 3.14159265 #define TAU PI * 2.0 // Classic Perlin 3D Noise // by Stefan Gustavson // vec4 permute(vec4 x) { return mod(((x*34.0)+1.0)*x, 289.0); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec3 fade(vec3 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } float cnoise(vec3 P){ vec3 Pi0 = floor(P); // Integer part for indexing vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 Pi0 = mod(Pi0, 289.0); Pi1 = mod(Pi1, 289.0); vec3 Pf0 = fract(P); // Fractional part for interpolation vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); vec4 iy = vec4(Pi0.yy, Pi1.yy); vec4 iz0 = Pi0.zzzz; vec4 iz1 = Pi1.zzzz; vec4 ixy = permute(permute(ix) + iy); vec4 ixy0 = permute(ixy + iz0); vec4 ixy1 = permute(ixy + iz1); vec4 gx0 = ixy0 / 7.0; vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; gx0 = fract(gx0); vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); vec4 sz0 = step(gz0, vec4(0.0)); gx0 -= sz0 * (step(0.0, gx0) - 0.5); gy0 -= sz0 * (step(0.0, gy0) - 0.5); vec4 gx1 = ixy1 / 7.0; vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; gx1 = fract(gx1); vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); vec4 sz1 = step(gz1, vec4(0.0)); gx1 -= sz1 * (step(0.0, gx1) - 0.5); gy1 -= sz1 * (step(0.0, gy1) - 0.5); vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); g000 *= norm0.x; g010 *= norm0.y; g100 *= norm0.z; g110 *= norm0.w; vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); g001 *= norm1.x; g011 *= norm1.y; g101 *= norm1.z; g111 *= norm1.w; float n000 = dot(g000, Pf0); float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); float n111 = dot(g111, Pf1); vec3 fade_xyz = fade(Pf0); vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } vec3 getColor(float time) { float t = fract(time); // Fracción de tiempo entre 0 y 1 // Red, green y blue varían en ciclos independientes de tiempo float red = cos(t * 6.2831); // Variación sinusoidal en el rango [-1, 1] float green = cos(t * 6.2831); // Variación cosinusoidal en el rango [-1, 1] float blue = sin(t * 6.2831 * 2.0); // Variación sinusoidal rápida en el rango [-1, 1] // Normalización y asignación del color resultante vec3 color = vec3(red, green, blue) * 0.5 + 0.75; return color; } // Make a circle with the frequency data vec4 circleFreq(vec4 currentColor, vec2 center) { vec2 pos = vec2(0.55, 0.5); float dist = length(vUv - pos); float rad = atan(vUv.y - pos.y, vUv.x - pos.x); float normAngle = 0.0; if (rad < 0.0) { normAngle = ((rad + PI) / PI); } else { normAngle = 1.0 - (1.0 + ((rad - PI) / PI)); } float audioValue = (texture2D(uAudioTexture, vec2(normAngle, 0.0)).r - 0.5) * .25 * uAudioStrengthFreq; // Perlin noise float strength = cnoise(vec3(rad * 2.0, dist * uNoiseStrength, uTime * uNoiseSpeed)) * 0.1; if (dist - audioValue + strength + 0.005 < uRadiusFreq) { float angle = uTime * .5 * PI; // Ángulo de rotación en función del tiempo // Aplicar matriz de rotación al vector de coordenadas UV float cosAngle = cos(angle); float sinAngle = sin(angle); mat2 rotationMatrix = mat2(cosAngle, -sinAngle, sinAngle, cosAngle); vec2 rotatedUV = rotationMatrix * vUv; return vec4(abs(sin(uTime * 0.1)), abs(rotatedUV.x), abs(rotatedUV.y), 1.0);//vec4(color, 1.0); } else if (dist - audioValue + strength < uRadiusFreq) { return vec4(1.0, 1.0, 1.0, 1.0); } return currentColor; } // // Make a circle with the time domain data vec4 circleSin(vec4 currentColor, vec2 center) { vec2 pos1 = vec2(0.4, 0.5); float dist = length(vUv - center); float rad = atan(vUv.y - center.y, vUv.x - center.x); float normAngle = 0.0; if (rad < 0.0) { normAngle = ((rad + PI) / PI); } else { normAngle = (1.0 + ((rad - PI) / PI)); } float audioValue = (texture2D(uAudioTexture, vec2(normAngle, 0.0)).g - 0.5) * .5 * uAudioStrengthSin; // Perlin noise float strength = 0.0; //cnoise(vec3(rad * TAU * 5.0, dist * 100.0, uTime + color.b)) * radius * 0.1; if (dist - audioValue + strength + 0.01 < uRadiusSin) { return vec4(getColor(uTime * 0.05) , 0.5 + (2.0 * dist) - sin(uTime) * 0.25); } else if (dist - audioValue + strength < uRadiusSin) { // color.g += 1.0 - audioValue; return vec4(1.0, 1.0, 1.0, 1.0); } return currentColor; } void main() { // Center of the plane vec2 center = vec2(0.5, 0.5); // Base color vec4 color = vec4(0.0, 0.0, 0.0, 0.0); color = circleFreq(color, center); color = circleSin(color, center); gl_FragColor = color; } </script> <!-- Perlin Sun vertex shader--> <script id="SSPerlinSunVertexShader" type="x-shader/x-vertex"> varying vec2 vUv; void main() { // Aplicar las transformaciones de modelo, vista y proyección vec4 modelPosition = modelMatrix * vec4(position, 1.0); vec4 viewPosition = viewMatrix * modelPosition; vec4 projectionPosition = projectionMatrix * viewPosition; // Asignar la posición transformada a gl_Position gl_Position = projectionPosition; // Pasar las coordenadas de textura sin transformar a la etapa de fragmentos vUv = uv; } </script> <script type="module"> import { OrbitControls } from 'three/addons/controls/OrbitControls.js' import * as THREE from 'three' /* Experience created by Josep Antoni Bover for https://devildrey33.es. * This Audio shader is a part of my Audio-PlayGround experience : * https://github.com/devildrey33/Audio-PlayGround * * #8 Perlin sun effect. * - This effect is a mix of Onion #4 and Circular osciloscope #2 effects. * - This script creates an audio data texture with the getByteTimeFrequency values * on the red channel and the getByteTimeByDomain on the green channel. (Its more easy than creating extra attributes, and looks better) * - Then this texture is sent to the sunset shader and the sunset depth shader. * - You can drag & drop any song of your computer to play it. * - Song name : Alone * Song artist : Color Out * URL : https://www.jamendo.com/track/1886257/alone * * Created on : 25/05/2023 * Last modification : 25/05/2023 */ // Simple 2d buffer canvas class BufferCanvas { constructor(width, height) { this.canvas = document.createElement("canvas"); this.canvas.setAttribute("width", width); this.canvas.setAttribute("height", height); this.context = this.canvas.getContext("2d", { willReadFrequently : true }); this.width = width; this.height = height; } } export default class CodepenThreeAudio { // Default options options = { // Y position. Use 'auto' to center canvas horizontaly to the view port top : 0, // X position. Use 'auto' to center canvas verticaly to the view port left : 0, // Width in pixels. Use 'auto' to fit all viewport width width : "auto", // Height in pixels. Use 'auto' to fit all viewport height height : "auto", // Show framerate inside the butons frame showFPS : true, // Show full screen buton in the buttons frame buttonFullScreen : true, // Show my logo buton in the buttons frame (that redirects to devildrey33.es) buttonLogo : true, // Show a github icon to go to the example repository buttonGitHub : true, // GitHub url for this project (only used if buttonGitHub is true) urlGitHub : "", // Element where canvas is inserted (by default is document.body) // For example you can use document.getElementById() to retrieve tag inside you want to create the canvas rootElement : document.body, // Anti alias (by default true) antialias : true, // OrbitControls enabled by default orbitControls : true, // Song path songPath : "//repo.bfw.wiki/bfwrepo/sound/5c89fd22dea6948307.mp3" }; constructor(options) { // Merge options this.options = { ...this.options, ...options }; // Create basic html elements this.createHtml(); // Setup sizes this.setupSizes(); // Setup audio fft size this.fftSize = 2048; this.square = Math.sqrt(this.fftSize * 0.5); // Setup audio texture this.bufferCanvasLinear = new BufferCanvas(1024, 1); this.bufferCanvasLinear.texture = new THREE.CanvasTexture(this.bufferCanvasLinear.canvas); this.imageDataLinear = this.bufferCanvasLinear.context.createImageData(1024, 1); this.bufferCanvasLinear.texture.generateMipMaps = false; this.bufferCanvasLinear.texture.minFilter = THREE.NearestFilter; this.bufferCanvasLinear.texture.magFilter = THREE.NearestFilter; this.bufferCanvasSquare = new BufferCanvas(this.square, this.square); this.bufferCanvasSquare.texture = new THREE.CanvasTexture(this.bufferCanvasSquare.canvas); this.bufferCanvasSquare.texture.minFilter = THREE.NearestFilter; this.bufferCanvasSquare.texture.magFilter = THREE.NearestFilter; this.imageDataSquare = this.bufferCanvasSquare.context.createImageData(this.square, this.square); // Setup buffers for audio data this.analizerData = new Uint8Array(this.fftSize * 0.5); this.analizerDataSin = new Uint8Array(this.fftSize * 0.5); // Fill the sin array with 128, because its the central point for (let i = 0; i < this.fftSize * 0.5; i++) { this.analizerDataSin[i] = 128; } // Setup a basic scene with camera this.setupBasicScene(); // Time values this.timeStart = Date.now(); this.timeCurrent = this.timeStart; this.timeElapsed = 0; this.timeDelta = 16; // Time from this second this.timeActualFrame = this.timeStart + 1000; // Number of frames during this second this.timeFrameCounter = 0; // actual framerate this.fps = 0; // Drag & drop events this.hEventDragEnter = this.eventDragEnter.bind(this); this.hEventDragOver = this.eventDragOver.bind(this); this.hEventDrop = this.eventDrop.bind(this); this.elementCanvas.addEventListener("dragenter", this.hEventDragEnte.........完整代码请登录后点击上方下载按钮下载查看
网友评论0