碰撞的粒子群(Particle)

碰撞的粒子群(Particle)

示例

在这里插入图片描述

HTML

<div id="text-wrapper">
  <div id="text">Click and drag to rotate the camera. Scroll to zoom in/out.</div>
</div>
<div id="container"></div>

CSS

body {
  background-color: #000;
  margin: 0;
  overflow: hidden;
  padding: 0;
}

#text-wrapper {
  position: fixed;
  width: 100%;
}

#text {
  border: 1px solid #555;
  background-color: rgba(150, 150, 150, 0.2);
  border-radius: 10px;
  color: #ddd;
  display: block;
  font-size: 20px;
  margin: 4px auto 0;
  min-width: 320px;
  padding: 10px;
  position: relative;
  text-align: center;
  width: 50%;
  z-index: 1000;
}

JS

/**
 * @file
 * The main scene.
 */

/**
 * Define constants.
 */
const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/';

/**
 * Set our global variables.
 */
var cubeCount = 1000;
var test = 0;
var camera,
    scene,
    renderer,
    effect,
    controls,
    element,
    container,
    rotationPoint;

var cubes = [];

var textureFlare0;
var textureFlare2;
var textureFlare3;

document.addEventListener( 'mousemove', onDocumentMouseMove, false );

init();
animate(); 

/**
 * Initializer function.
 */
function init() {
  // Build the container
  container = document.createElement( 'div' );
  document.body.appendChild( container );
  
  // Create the scene.
  scene = new THREE.Scene();
  
  // Create a rotation point.
  rotationPoint = new THREE.Object3D();
  rotationPoint.position.set( 0, 0, 0 );
  scene.add(rotationPoint);
  
    // Create the camera.
  camera = new THREE.PerspectiveCamera(
   50, // Angle
    window.innerWidth / window.innerHeight, // Aspect Ratio.
    1, // Near view.
    23000 // Far view.
  );
  camera.position.z = -1000;
  rotationPoint.add( camera );

  // Build the renderer.
  renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
  element = renderer.domElement;
  renderer.setSize( window.innerWidth, window.innerHeight );
  renderer.shadowMap.enabled;
  container.appendChild( element );
  
  // Build the controls.
  controls = new THREE.OrbitControls( camera, element );
  controls.enablePan = true;
  controls.enableZoom = true; 
  controls.maxDistance = 2000; 
  controls.minDistance = 500;
  controls.target.copy( new THREE.Vector3( 0, 0, 0 ) );
  
  function setOrientationControls(e) {
    if (!e.alpha) {
     return;
    }

    controls = new THREE.DeviceOrientationControls( camera );
    controls.connect();

    window.removeEventListener('deviceorientation', setOrientationControls, true);
  }
  window.addEventListener('deviceorientation', setOrientationControls, true);
  
  // Ambient lights
  var ambient = new THREE.AmbientLight( 0x555555);
  scene.add( ambient );

  // Add the skymap.
  addSkybox();
  
  // Build a bunch of cubes.
  var counter = cubeCount;
  
  while (counter > 0) {
    buildObject();
    counter--;
  }
  
  window.addEventListener('resize', onWindowResize, false);
}

/**
 * Events to fire upon window resizing.
 */
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

/**
 * Updates to apply to the scene while running.
 */
function update() {
  camera.updateProjectionMatrix();
}

/**
 * Render the scene.
 */
function render() {
  renderer.render(scene, camera);
  
  var timer = 0.0001 * Date.now();
  
  for (var i = 0; i < cubeCount; i++) {
    var cube = cubes[i];

        if (cube.in == true) {
          var posX = Math.abs(cube.position.x);
          var posY = Math.abs(cube.position.y);
          var posZ = Math.abs(cube.position.z);
          var distance = Math.sqrt((posY * posY) + Math.sqrt(posX * posX + posZ * posZ));

          var multiplierX = 1;
          var multiplierY = 1;
          var multiplierZ = 1;
          if (cube.position.x > 0) {
            multiplierX = -1;
          }

          if (cube.position.y > 0) {
            multiplierY = -1;
          }

          if (cube.position.z > 0) {
            multiplierZ = -1;
          }

          cube.position.x = cube.position.x + ((posX/distance)) * multiplierX;
          cube.position.y = cube.position.y + ((posY/distance)) * multiplierY;
          cube.position.z = cube.position.z + ((posZ/distance)) * multiplierZ;
          
          // The closer the brighter.
          var red = 0;
          var green = Math.floor(14000/distance);
          var blue = Math.floor(20000/distance);
          
          if (red > 255) {
            red = 255;
          }
          if (green > 255) {
            green = 255;
          }
          if (blue > 255) {
            blue = 255;
          }
          
          // Convert to hex.
          var hex = rgbToHex(red, green, blue);
    
          hex = parseInt(hex);
          
          cube.material.color = new THREE.Color(hex);
          cube.material.emissive = new THREE.Color(hex); 
          
          if (distance < 5) {
            cube.in = false;
          }
        }
        if (cube.in == false) {
          
          var posX = Math.abs(cube.originalPositionX - cube.position.x);
          var posY = Math.abs(cube.originalPositionY - cube.position.y);
          var posZ = Math.abs(cube.originalPositionZ - cube.position.z);
          
          var distance = Math.sqrt((posY * posY) + Math.sqrt(posX * posX + posZ * posZ));
          
          // The closer to the center the brighter.
          var red = Math.floor(0.5 * distance);
          var green = Math.floor(.05 * distance);
          var blue = Math.floor(.05 * distance);
          
          if (red > 255) {
            red = 255;
          }
          if (green > 255) {
            green = 255;
          }
          if (blue > 255) {
            blue = 255;
          }
          
          // Convert to hex.
          var hex = rgbToHex(red, green, blue);
    
          hex = parseInt(hex);
          
          // Update the object's color.
          cube.material.color = new THREE.Color(hex);
          cube.material.emissive = new THREE.Color(hex); 
          
          // Calculate positions.
          var multiplierX = 1;
          var multiplierY = 1;
          var multiplierZ = 1;
          if (posX > cube.originalPositionX) {
            multiplierX = -1;
          }

          if (posY > cube.originalPositionY) {
            multiplierY = -1;
          }

          if (posZ > cube.originalPositionZ) {
            multiplierZ = -1;
          }

          // Update the objects position.
          cube.position.x = cube.position.x + (posX/distance) * multiplierX;
          cube.position.y = cube.position.y + (posY/distance) * multiplierY;
          cube.position.z = cube.position.z + (posZ/distance) * multiplierZ;
            
          // If the object is at its starting point, bring it back to center.
          if (Math.abs(cube.position.x - cube.originalPositionX) < 20 && Math.abs(cube.position.y - cube.originalPositionY) < 20 && Math.abs(cube.position.z - cube.originalPositionZ) < 20) {
            cube.in = true;
          }
        }
  }
         
  // Automatically rotate the camera.
  rotationPoint.rotation.y -= 0.0005;
  //rotationPoint.rotation.y = Math.sin(timer);
  rotationPoint.rotation.x = Math.cos(timer);
}

/**
 * Animate the scene.
 */
function animate() {
  requestAnimationFrame(animate);
  update();
  render();
}

/**
 * Add the skybox, the stars wrapper.
 */
function addSkybox() {
  var urlPrefix = TEXTURE_PATH;
  var urls = [
    urlPrefix + 'test.jpg',
    urlPrefix + 'test.jpg',
    urlPrefix + 'test.jpg',
    urlPrefix + 'test.jpg',
    urlPrefix + 'test.jpg',
    urlPrefix + 'test.jpg',
  ];

  var loader = new THREE.CubeTextureLoader();
  loader.setCrossOrigin( 'https://s.codepen.io' );
  
  var textureCube = loader.load( urls );
  textureCube.format = THREE.RGBFormat;

  var shader = THREE.ShaderLib[ "cube" ];
  shader.uniforms[ "tCube" ].value = textureCube;

  var material = new THREE.ShaderMaterial( {
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
  } );

  var geometry = new THREE.BoxGeometry( 20000, 20000, 20000 );
  var skybox = new THREE.Mesh( geometry, material );
  scene.add( skybox );
}

function onDocumentMouseMove( event ) {
  event.preventDefault();
}

/**
 * Build the object.
 */
function buildObject() {
  var randNumX = Math.floor(Math.random() * (3 - 1) + 1);
  var randNumY = Math.floor(Math.random() * (3 - 1) + 1);
  var randNumZ = Math.floor(Math.random() * (3 - 1) + 1);
  
  // X Positions can be negative.
  var multiplierX = 1;
  if (randNumX == 1) {
    multiplierX = -1;
  } else if (randNumX == 2) {
    multiplierX = 1;
  }
  
  // Y Positions can be negative.
  var multiplierY = 1;
  if (randNumY == 1) {
    multiplierY = -1;
  } else if (randNumY == 2) {
    multiplierY = 1;
  }
  
  // Z Positions can be negative.
  var multiplierZ = 1;
  if (randNumZ == 1) {
    multiplierZ = -1;
  } else if (randNumZ == 2) {
    multiplierZ = 1;
  }
  
  // Create the object.
  var geometry = new THREE.SphereGeometry(5, 8, 8);
  var material = new THREE.MeshPhongMaterial( {color: 0xffffff, emissive: 0xffffff} );
  var cube = new THREE.Mesh( geometry, material );
  
  // Set initial position.
  cube.position.x = Math.floor((Math.random() * 1000) + 250) * multiplierX;
  cube.position.y = Math.floor((Math.random() * 1000) + 250) * multiplierY;
  cube.position.z = Math.floor((Math.random() * 1000) + 250) * multiplierZ;
  
  // Store original positions so we can return the object.
  cube.originalPositionX = cube.position.x;
  cube.originalPositionY = cube.position.y;
  cube.originalPositionZ = cube.position.z;
  
  // Objects start heading towards the middle.
  cube.in = true;
  
  // Set slightly random sizes.
  cube.scale.x = cube.scale.y = cube.scale.z = Math.random() * 0.5 + 0.1;
  
  // Add the object to the scene and object array.
  scene.add( cube );
  cubes.push( cube );
}

/**
 * Convert a rgb set to hex.
 */
function rgbToHex(r, g, b) {
  return "0x" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).toUpperCase().slice(1);
}
发布了117 篇原创文章 · 获赞 54 · 访问量 8617

猜你喜欢

转载自blog.csdn.net/weixin_45544796/article/details/104179185