使用3D引擎threeJS实现星空粒子移动效果


Posted in Javascript onSeptember 13, 2020

three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。

下载地址: http://threejs.org/

首先创建一个HTML文件,引入three.js引擎包.

<!DOCTYPE HTML>
<html>
 <head>
 <meta charset="utf-8">
 <title>Three.js实现3D空间粒子效果</title>
 <style type="text/css">
 body{
 background-color:#000000;
 margin:0px;
 overflow:hidden;
 }
 </style>
 <script src="scripts/three.js"></script>
 </head>
 <body >
 </body>
</html>

声明全局变量

//定义应用所需的组件:相机,场景,渲染器
 var camera, scene, renderer;
 //跟踪鼠标的位置
 var mouseX = 0, mouseY = 0;
 //定义存储粒子的数组
 var particles = [];

相机:

OpenGL(WebGL)中、三维空间中的物体投影到二维空间的方式中,存在透视投影和正投影两种相机。
透视投影就是、从视点开始越近的物体越大、远处的物体绘制的较小的一种方式、和日常生活中我们看物体的方式是一致的。
正投影就是不管物体和视点距离,都按照统一的大小进行绘制、在建筑和设计等领域需要从各个角度来绘制物体,因此这种投影被广泛应用。
在 Three.js 也能够指定透视投影和正投影两种方式的相机。

场景:

场景就是一个三维空间。 用 [Scene] 类声明一个叫 [scene] 的对象。

渲染器:
三维空间里的物体映射到二维平面的过程被称为三维渲染。 一般来说我们都把进行渲染的操作叫做渲染器。

数据初始化

//数据初始化
 function init(){
 //相机参数:
 //四个参数值分别代表:视野角:fov 纵横比:aspect 相机离视体最近的距离:near 相机离视体最远的距离:far
 camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 4000 );
 //设置相机位置,默认位置为:0,0,0. 
 camera.position.z = 1000;

 //声明场景
 scene = new THREE.Scene();
 //将相机装加载到场景
 scene.add(camera);

 //生成渲染器的对象
 renderer = new THREE.CanvasRenderer();
 //设置渲染器的大小
 renderer.setSize( window.innerWidth, window.innerHeight );
 //追加元素
 document.body.appendChild(renderer.domElement);
 //调用自定义的生成粒子的方法
 makeParticles();
 //添加鼠标移动监听
 document.addEventListener('mousemove',onMouseMove,false);
 //设置间隔调用update函数,间隔次数为每秒30次
 setInterval(update,1000/30);
 }

相机初始化说明:

实例中使用的是透视投影. var camera = new THREE.PerspectiveCamera( fov , aspect , near , far );

透视投影中,会把称为视体积领域中的物体作成投影图。 视体积是通过以下4个参数来指定。

视野角:fov

纵横比:aspect

相机离视体积最近的距离:near

相机离视体积最远的距离:far

设置相机的位置:

相机的位置坐标和视野的中心坐标,按照

 //设置相机的位置坐标

camera.position.x = 100;


camera.position.y = 20;


camera.position.z = 50;

方式进行设置。 和该方式一样,下面这样的方法也可以
 camera.position.set(100,20,50);

此外还可以设置相机的上方向,视野中心等,
设置相机的上方向为正方向: 

camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;

设置相机的视野中心 

利用[lookAt]方法来设置相机的视野中心。 「lookAt()」的参数是一个属性包含中心坐标「x」「y」「z」的对象。   

「lookAt()」方法不仅是用来设置视点的中心坐标、 在此之前设置的相机属性要发生实际作用,也需要调用 [lookAt] 方法。

使用3D引擎threeJS实现星空粒子移动效果

其他投影方式

在 Three.js 中、有各种各样的类,用来来实现透视投影、正投影或者复合投影(透视投影和正投影)这样的相机。

var camera = THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) //正投影
var camera = THREE.CombinedCamera = function ( width, height, fov, near, far, orthonear, orthofar ) //?合投影

渲染器

创建CanvasRenderer对象.这是一个普通的2D画布对象,实例中我们添加到body标签中. 否则我们就不会看到它。我们想让它充满整个浏览器窗口,所以我们设置其大小为window.innerwidth和window.innerheight。

鼠标监听

使用自定义函数makeParticles()创建粒子,并为其添加mousemove侦听器来跟踪鼠标的位置,最后我们建立一个间隔调用update函数一秒30次。
update函数中的定义如下:

function update() {
 updateParticles();
 renderer.render( scene, camera );
 }

产生粒子的函数

//定义粒子生成的方法
 function makeParticles(){
 
 var particle,material;
 //粒子从Z轴产生区间在-1000到1000
 for(var zpos=-1000;zpos<1000;zpos+=20){
 //we make a particle material and pass through the colour and custom particle render function we defined. 
 material = new THREE.ParticleCanvasMaterial( { color: 0xffffff, program: particleRender } );
 //生成粒子
 particle = new THREE.Particle(material);
 //随即产生x轴,y轴,区间值为-500-500
 particle.position.x = Math.random()*1000-500;
 particle.position.y = Math.random()*1000-500;
 //设置z轴
 particle.position.z = zpos;
 //scale it up a bit
 particle.scale.x = particle.scale.y = 10;
 //将产生的粒子添加到场景,否则我们将不会看到它
 scene.add(particle);
 //将粒子位置的值保存到数组
 particles.push(particle);
 }
 }

math . random()返回一个浮点数在0和1之间,我们乘以1000,给了我们一个0到1000之间的数字。然后我们减去500,这给了我们一个号码在-500和500之间.我们也可以这样定义一个生成范围区间内随机值的函数

function randomRange(min, max) { 
 return Math.random()*(max-min) + min; 
}

绘制粒子的函数

//定义粒子绘制函数
 function particleRender( context ) {
 //获取canvas上下文的引用
 context.beginPath();
 // and we just have to draw our shape at 0,0 - in this
 // case an arc from 0 to 2Pi radians or 360º - a full circle!
 context.arc( 0, 0, 1, 0, Math.PI * 2, true );
 //设置原型填充
 context.fill();
 }

定义粒子移动的函数,这里设置成移动速度随着鼠标距离Y轴0点的值越大,粒子移动越快

//移动粒子的函数
 function updateParticles(){
 
 //遍历每个粒子
 for(var i=0; i<particles.length; i++){
 particle = particles[i];
 //设置粒子向前移动的速度依赖于鼠标在平面Y轴上的距离
 particle.position.z += mouseY * 0.1;
 //如果粒子Z轴位置到1000,将z轴位置设置到-1000,即移动到原点,这样就会出现无穷尽的星域效果.
 if(particle.position.z>1000){
  particle.position.z-=2000; 
 }
 }
 }

鼠标移动时函数监听

//鼠标移动时调用
 function onMouseMove(event){
 mouseX = event.clientX;
 mouseY = event.clientY;
 }

至此,空间粒子简单效果学习完毕.

整合代码如下:

<!DOCTYPE HTML>
<html>
 <head>
 <meta charset="utf-8">
 <title>Three.js实现3D空间粒子效果</title>
 <style type="text/css">
 body{
 background-color:#000000;
 margin:0px;
 overflow:hidden;
 }
 </style>
 <script src="scripts/three.js"></script>
 <script>
 //定义应用所需的组件:相机,场景,渲染器
 var camera, scene, renderer;
 //跟踪鼠标的位置
 var mouseX = 0, mouseY = 0;
 //定义存储粒子的数组
 var particles = [];
 
 //数据初始化
 function init(){
 //相机参数:
 //四个参数值分别代表:视野角:fov 纵横比:aspect 相机离视体最近的距离:near 相机离视体最远的距离:far
 camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 4000 );
 //设置相机位置,默认位置为:0,0,0. 
 camera.position.z = 1000;

 //声明场景
 scene = new THREE.Scene();
 //将相机装加载到场景
 scene.add(camera);
 
 //生成渲染器的对象
 renderer = new THREE.CanvasRenderer();
 //设置渲染器的大小
 renderer.setSize( window.innerWidth, window.innerHeight );
 //追加元素
 document.body.appendChild(renderer.domElement);
 //调用自定义的生成粒子的方法
 makeParticles();
 //添加鼠标移动监听
 document.addEventListener('mousemove',onMouseMove,false);
 //设置间隔调用update函数,间隔次数为每秒30次
 setInterval(update,1000/30);
 }
 
 function update() {
 //调用移动粒子的函数
 updateParticles();
 //重新渲染
 renderer.render( scene, camera );
 }

 //定义粒子生成的方法
 function makeParticles(){
 
 var particle,material;
 //粒子从Z轴产生区间在-1000到1000
 for(var zpos=-1000;zpos<1000;zpos+=20){
  //we make a particle material and pass through the colour and custom particle render function we defined. 
  material = new THREE.ParticleCanvasMaterial( { color: 0xffffff, program: particleRender } );
  //生成粒子
  particle = new THREE.Particle(material);
  //随即产生x轴,y轴,区间值为-500-500
  particle.position.x = Math.random()*1000-500; //math . random()返回一个浮点数在0和1之间
  particle.position.y = Math.random()*1000-500;
  //设置z轴
  particle.position.z = zpos;
  //scale it up a bit
  particle.scale.x = particle.scale.y = 10;
  //将产生的粒子添加到场景
  scene.add(particle);
  //将粒子位置的值保存到数组
  particles.push(particle);
 }
 }

 //定义粒子渲染器
 function particleRender( context ) {
 //获取canvas上下文的引用
 context.beginPath();
 // and we just have to draw our shape at 0,0 - in this
 // case an arc from 0 to 2Pi radians or 360º - a full circle!
 context.arc( 0, 0, 1, 0, Math.PI * 2, true );
 //设置原型填充
 context.fill();
 }

 
 //移动粒子的函数
 function updateParticles(){
 
 //遍历每个粒子
 for(var i=0; i<particles.length; i++){
  particle = particles[i];
  //设置粒子向前移动的速度依赖于鼠标在平面Y轴上的距离
  particle.position.z += mouseY * 0.1;
  //如果粒子Z轴位置到1000,将z轴位置设置到-1000
  if(particle.position.z>1000){
  particle.position.z-=2000; 
  }
 }
 }
 
 //鼠标移动时调用
 function onMouseMove(event){
 mouseX = event.clientX;
 mouseY = event.clientY;
 }
 </script>
 </head>
 <body onload="init()">
 </body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
区分JS中的undefined,null,&quot;&quot;,0和false
Mar 08 Javascript
Javascript设置对象的ReadOnly属性(示例代码)
Dec 25 Javascript
jQuery常用且重要方法汇总
Jul 13 Javascript
详解Javascript中的Object对象
Feb 28 Javascript
js实现内容显示并使用json传输数据
Mar 16 Javascript
JS中this的指向以及call、apply的作用
May 06 Javascript
微信小程序自定义对话框弹出和隐藏动画
Jul 19 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
May 16 Javascript
ES6 class的应用实例分析
Jun 27 Javascript
Vue使用NProgress进度条的方法
Sep 21 Javascript
Vue跨域请求问题解决方案过程解析
Aug 07 Javascript
一篇文章学会Vue中间件管道
Jun 20 Vue.js
vue.js项目打包上线的图文教程
Nov 16 #Javascript
Three.js基础学习教程
Nov 16 #Javascript
three.js实现3D视野缩放效果
Nov 16 #Javascript
three.js中3D视野的缩放实现代码
Nov 16 #Javascript
js的函数的按值传递参数(实例讲解)
Nov 16 #Javascript
React/Redux应用使用Async/Await的方法
Nov 16 #Javascript
详谈DOM简介及节点、属性、查找节点的方法
Nov 16 #Javascript
You might like
Terran魔法科技
2020/03/14 星际争霸
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
PHP中字符安全过滤函数使用小结
2015/02/25 PHP
php 输出json及显示json中的中文汉字详解及实例
2016/11/09 PHP
php函数式编程简单示例
2019/08/08 PHP
推荐40款强大的 jQuery 导航插件和教程(上篇)
2012/09/14 Javascript
JavaScript建立一个语法高亮输入框实现思路
2013/02/26 Javascript
JQuery Tips相关(1)----关于$.Ready()
2014/08/14 Javascript
jQuery分组选择器用法实例
2014/12/23 Javascript
创建你的第一个AngularJS应用的方法
2015/06/16 Javascript
使用Node.js搭建静态资源服务详细教程
2017/08/02 Javascript
微信小程序实现底部导航
2018/11/05 Javascript
vue+iview 兼容IE11浏览器的实现方法
2019/01/07 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
vue cli3 配置proxy代理无效的解决
2019/10/30 Javascript
浅谈JavaScript窗体Window.ShowModalDialog使用
2020/07/22 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
Python中Django框架下的staticfiles使用简介
2015/05/30 Python
Python字典数据对象拆分的简单实现方法
2017/12/05 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
pandas去重复行并分类汇总的实现方法
2019/01/29 Python
selenium python 实现基本自动化测试的示例代码
2019/02/25 Python
python3利用Socket实现通信的方法示例
2019/05/06 Python
利用Django模版生成树状结构实例代码
2019/05/19 Python
Python运行提示缺少模块问题解决方案
2020/04/02 Python
Python bisect模块原理及常见实例
2020/06/17 Python
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
哥伦比亚最大的网上商店:Linio哥伦比亚
2016/09/25 全球购物
方太官方网上商城:销售方太抽油烟机、燃气灶、消毒柜等
2017/01/17 全球购物
大一军训感言
2014/01/09 职场文书
好家长事迹材料
2014/01/23 职场文书
投标人法定代表人授权委托书格式
2014/09/28 职场文书
师德师风培训感言
2015/08/03 职场文书
咖啡厅里的创业计划书
2019/08/21 职场文书
浅谈Python 中的复数问题
2021/05/19 Python
Valheim服务器 Mod修改安装教程 【ValheimPlus】
2022/12/24 Servers