three+webgl实现鼠标互动鸟群粒子动画效果代码
代码语言:html
所属分类:粒子
代码描述:three+webgl实现鼠标互动鸟群粒子动画效果代码
代码标签: three webgl 鼠标 互动 鸟群 粒子 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> @import url("https://fonts.googleapis.com/css2?family=Asap&display=swap"); * { margin: 0; padding: 0; box-sizing: border-box; } html, body { overscroll-behavior-x: none; overscroll-behavior-y: none; } body { font-family: "Asap", sans-serif; position: relative; width: 100vw; min-height: 100vh; text-align: center; overflow-x: hidden; color: white; } canvas { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; position: fixed; width: 100vw; height: 100vh; top: 0; left: 0; z-index: 0; } main { position: relative; } section { position: relative; width: 100vw; min-height: 100vh; display: flex; align-items: center; justify-content: center; } </style> </head> <body translate="no"> <main> <section> <div> <h1>title</h1> <p>contents</p> </div> </section> </main> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.3.js"></script> <script type="importmap"> { "imports": { "three": "//repo.bfw.wiki/bfwrepo/js/module/three/build/162/three.module.js", "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/162/jsm/" } } </script> <!-- shader for bird's position --> <script id="fragmentShaderPosition" type="x-shader/x-fragment"> uniform float time; uniform float delta; void main() { vec2 uv = gl_FragCoord.xy / resolution.xy; vec4 tmpPos = texture2D( texturePosition, uv ); vec3 position = tmpPos.xyz; vec3 velocity = texture2D( textureVelocity, uv ).xyz; float phase = tmpPos.w; phase = mod( ( phase + delta + length( velocity.xz ) * delta * 3. + max( velocity.y, 0.0 ) * delta * 6. ), 62.83 ); gl_FragColor = vec4( position + velocity * delta * 15. , phase ); } </script> <!-- shader for bird's velocity --> <script id="fragmentShaderVelocity" type="x-shader/x-fragment"> uniform float time; uniform float testing; uniform float delta; // about 0.016 uniform float separationDistance; // 20 uniform float alignmentDistance; // 40 uniform float cohesionDistance; // uniform float freedomFactor; uniform vec3 predator; const float width = resolution.x; const float height = resolution.y; const float PI = 3.141592653589793; const float PI_2 = PI * 2.0; // const float VISION = PI * 0.55; float zoneRadius = 40.0; float zoneRadiusSquared = 1600.0; float separationThresh = 0.45; float alignmentThresh = 0.65; const float UPPER_BOUNDS = BOUNDS; const float LOWER_BOUNDS = -UPPER_BOUNDS; const float SPEED_LIMIT = 7.0;//9.0; float rand( vec2 co ){ return fract( sin( dot( co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 ); } void main() { zoneRadius = separationDistance + alignmentDistance + cohesionDistance; separationThresh = separationDistance / zoneRadius; alignmentThresh = ( separationDistance + alignmentDistance ) / zoneRadius; zoneRadiusSquared = zoneRadius * zoneRadius; vec2 uv = gl_FragCoord.xy / resolution.xy; vec3 birdPosition, birdVelocity; vec3 selfPosition = texture2D( texturePosition, uv ).xyz; vec3 selfVelocity = texture2D( textureVelocity, uv ).xyz; float dist; vec3 dir; // direction float distSquared; float separationSquared = separationDistance * separationDistance; float cohesionSquared = cohesionDistance * cohesionDistance; float f; float percent; vec3 velocity = selfVelocity; float limit = SPEED_LIMIT; dir = predator * UPPER_BOUNDS - selfPosition; dir.z = 0.; // dir.z *= 0.6; dist = length( dir ); distSquared = dist * dist; float preyRadius = 150.0; float preyRadiusSq = preyRadius * preyRadius; // move birds away from predator if ( dist < preyRadius ) { f = ( distSquared / preyRadiusSq - 1.0 ) * delta * 100.; velocity += normalize( dir ) * f; limit += 5.0; } // if (testing == 0.0) {} // if ( rand( uv + time ) < freedomFactor ) {} // Attract flocks to the center vec3 central = vec3( 0., 0., 0. ); dir = selfPosition - central; dist = length( dir ); dir.y *= 2.5; velocity -= normalize( dir ) * delta * 5.; for ( float y = 0.0; y < height; y++ ) { for ( float x = 0.0; x < width; x++ ) { vec2 ref = vec2( x + 0.5, y + 0.5 ) / resolution.xy; birdPosition = texture2D( texturePosition, ref ).xyz; dir = birdPosition - selfPosition; dist = length( dir ); if ( dist < 0.0001 ) continue; distSquared = dist * dist; if ( distSquared > zoneRadiusSquared ) continue; percent = distSquared / zoneRadiusSquared; if ( percent < separationThresh ) { // low // Separation - Move apart for comfort f = ( separationThresh / percent - 1.0 ) * delta; velocity -= normalize( dir ) * f; } else if ( percent < alignmentThresh ) { // high // Alignment - fly the same direction float threshDelta = alignmentThresh - separationThresh; float adjustedPercent = ( percent - separationThresh ) / threshDelta; birdVelocity = texture2D( textureVelocity, ref ).xyz; f = ( 0.5 - cos( adjustedPercent * PI_2 ) * 0.5 + 0.5 ) * delta; velocity += normalize( birdVelocity ) * f; } else { // Attraction / Cohesion - move closer float threshDelta = 1.0 - alignmentThresh; float adjustedPercent; if( threshDelta == 0. ) adjustedPercent = 1.; else adjustedPercent = ( percent - alignmentThresh ) / threshDelta; f = ( 0.5 - ( cos( adjustedPercent * PI_2 ) * -0.5 + 0.5 ) ) * delta; velocity += normalize( dir ) * f; } } } // this make tends to fly around than down or up // if (velocity.y > 0.) velocity.y *= (1. - 0.2 * delta); // Speed Limits if ( length( velocity ) > limit ) { velocity = normalize( velocity ) * limit; } gl_FragColor = vec4( velocity, 1.0 ); } </script> <script type="x-shader/x-vertex" id="birdVS"> attribute vec2 reference; attribute float birdVertex; attribute vec3 birdColor; uniform sampler2D texturePosition; uniform sampler2D textureVelocity; varying vec4 vColor; varying float z; uniform float time; void main() { vec4 tmpPos = texture2D( texturePosition, reference ); vec3 pos = tmpPos.xyz; vec3 velocity = normalize(texture2D( textureVelocity, reference ).xyz); vec3 newPosition = position; if ( birdVertex == 4.0 || birdVertex == 7.0 ) { // flap wings newPosition.y = sin( tmpPos.w ) * 5.; } newPosition = mat3( modelMatrix ) * newPosition; velocity.z *= -1.; float xz = length( velocity.xz ); float xyz = 1.; float x = sqrt( 1. - velocity.y * velocity.y ); float cosry = velocity.x / xz; float sinry = velocity.z / xz; float cosrz = x / xyz; float sinrz = velocity.y / xyz; mat3 maty = mat3( cosry, 0, -sinry, 0 , 1, 0 , sinry, 0, cosry ); mat3 matz = mat3( cosrz , sinrz, 0, -sinrz, cosrz, 0, 0 , 0 , 1 ); newPosition = maty * matz * newPosition; newPosition += pos; z = newPosition.z; // change vColor = vec4( birdColor, 1.0 ); //vColor = vec4( color, 1.0 ); // vColor = color; gl_Position = projectionMatrix * viewMatrix * vec4( newPosition, 1.0 ); } </script> <!-- bird geometry shader --> <script type="x-shader/x-fragment" id="birdFS"> varying vec4 vColor; varying float z; uniform vec3 color; void main() { // Fake colors for now //float z2 = 0.2 + ( 1000. - z ) / 1000. * vColor.x; //gl_FragColor = vec4( z2, z2, z2, 1. ); // change gl_FragColor = vec4( vColor.rgb, 1.0 ); //gl_FragColor = vec4( vColor.rgb, 1.0 ); } </script> <script type="module"> "use strict"; console.clear(); import * as THREE from "three"; import { GPUComputationRenderer } from "three/addons/misc/GPUComputationRenderer.js"; (function () { const param = { color1: "paleturquoise", //0xededed, color2: "royalblue", //0x434343, colorMode: "lerpGradient", // lerpGradient,variance,mix bgColor: "lightblue", separation: 20.0, alignment: 20.0, cohesion: 20.0, freedom: 0.75, numRatio: 0.3 // default:1 (num=WIDTH*WIDTH) }; /* TEXTURE WIDTH FOR SIMULATION */ const WIDTH = 32; const BIRDS = Math.round(WIDTH * WIDTH * param.numRatio); // Custom Geometry - using 3 triangles each. No UVs, no normals currently. class BirdGeometry extends THREE.BufferGeometry { constructor() { super(); const trianglesPerBird = 3; const triangles = BIRDS * trianglesPerBird; const points = triangles * 3; const vertices = new THREE.BufferAttribute( new Float32Array(points * 3), 3); const birdColors = new THREE.BufferAttribute( new Float32Array(points * 3), 3); const references = new THREE.BufferAttribute( new Float32Array(points * 2), 2); const birdVertex = new THREE.BufferAttribute(new Float32Array(points), 1); this.setAttribute("position", vertices); this.setAttribute("birdColor", birdColors); this.setAttribute("reference", references); this.setAttribute("birdVertex", birdVertex); // this.setAttribute( 'normal', new Float32Array( points * 3 ), 3 ); let v = 0; function verts_push() { for (let i = 0; i < arguments.length; i++) { vertices.array[v++] = arguments[i]; } } .........完整代码请登录后点击上方下载按钮下载查看
网友评论0