three.js

参考链接: 郭隆邦的技术博客

一、第一个three.js程序

1.1 引入three.js

学习three.js前需简单了解node.js
运行前需安装 live-server,安装命令cnpm install live-server -g
运行程序命令 live-server

第一个three.js程序:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			// Our Javascript will go here.
		</script>
	</body>
</html>

效果:
在这里插入图片描述

1.2 创建场景

在three.js中显示东西,我们需要三样东西:scene, camera和renderer,这样我们就可以用camera渲染场景。
在之前的script中添加代码

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

效果:
在这里插入图片描述

1.3 创建立方体

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

要创建一个立方体,我们需要一个BoxGeometry。这是一个包含立方体的所有点(顶点)和填充(面)的对象。我们将在未来对此进行更多的探索。

除了几何形状之外,我们还需要一种材质来给它上色。Three.js自带了几个材质,但我们现在只使用MeshBasicMaterial。所有材料都有一个将被应用于其上的属性对象。为了保持简单,我们只提供一个颜色属性0x00ff00,它是绿色的。这与颜色在CSS或Photoshop(十六进制颜色)中的工作方式相同。

我们需要的第三样东西是一个网格。网格是一个对象,它接受一个几何,并应用一个材料,然后我们可以插入到我们的场景中,并自由移动。

默认情况下,当我们调用scene.add()时,我们添加的东西将被添加到坐标(0,0,0)中。这将导致摄像机和立方体都在对方的内部。为了避免这种情况,我们简单地将摄像机移出一点。

1.4 渲染场景

function animate() {
	requestAnimationFrame( animate );
	renderer.render( scene, camera );
}
animate();

效果:
在这里插入图片描述

1.5 动画多维数据集

如果您将上述所有代码插入到您在开始之前创建的文件中,您应该会看到一个绿色框。旋转一下,让它更有趣一些。
在渲染器的右上方添加如下内容。在你的动画函数渲染调用:

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

这将每帧运行一次(通常是每秒60次),并给立方体一个漂亮的旋转动画。基本上,当应用运行时,任何你想移动或改变的东西都必须经过动画循环。你当然可以从那里调用其他函数,这样你就不会最终得到一个有几百行代码的动画函数。

效果:
在这里插入图片描述

1.6 第一个three.js的全部代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

            const renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );
            const geometry = new THREE.BoxGeometry();
            const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
            const cube = new THREE.Mesh( geometry, material );
            scene.add( cube );

            camera.position.z = 5;

            function animate() {
                requestAnimationFrame( animate );
                cube.rotation.x += 0.01;
                cube.rotation.y += 0.01;
                renderer.render( scene, camera );
            }
            animate();
		</script>
	</body>
</html>

二、

2.1、绘直线

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			const renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );

            const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );
            camera.position.set( 0, 0, 100 );
            camera.lookAt( 0, 0, 0 );

            const scene = new THREE.Scene();

            const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );

            const points = [];
            points.push( new THREE.Vector3( - 10, 0, 0 ) );
            points.push( new THREE.Vector3( 0, 10, 0 ) );
            points.push( new THREE.Vector3( 10, 0, 0 ) );

            const geometry = new THREE.BufferGeometry().setFromPoints( points );
            const line = new THREE.Line( geometry, material );

            scene.add( line );
            renderer.render( scene, camera );   
		</script>
	</body>
</html>

三、创建地球案例

3.1、创建一个可鼠标拖动的球

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>第一个three.js文件_WebGL三维场景</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="js/three.js"></script>
  <script src="OrbitControls.js"></script>
</head>

<body>
  <script>
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
    /**
     * 创建网格模型
     */
    var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象
    //var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
    var material = new THREE.MeshLambertMaterial({
      color: 0x0000ff
    }); //材质对象Material
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    scene.add(mesh); //网格模型添加到场景中
    /**
     * 光源设置
     */
    //点光源
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300); //点光源位置
    scene.add(point); //点光源添加到场景中
    //环境光
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);
    // console.log(scene)
    // console.log(scene.children)
    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);//设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    //执行渲染操作   指定场景、相机作为参数
    function render() {
            renderer.render(scene,camera);//执行渲染操作
            mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
            requestAnimationFrame(render);//请求再次执行渲染函数render
        }
    render();
    // 已经通过requestAnimationFrame(render);周期性执行render函数,没必要再通过监听鼠标事件执行render函数
    var controls = new THREE.OrbitControls(camera, renderer.domElement);
  </script>
</body>
</html>

效果如下:
在这里插入图片描述

3.2、增加贴图

增加地图图片

var texLoader = new THREE.TextureLoader();

var material = new THREE.MeshLambertMaterial({
      // color: 0x0000ff,
      map: texLoader.load('./贴图/diffuse.png'),
    }); //材质对象Material

在这里插入图片描述
可以看到,光线不是很均匀

3.3、改变光源

改变光线,将点光源改变为两束平行光

    var directionalLight = new THREE.DirectionalLight(0xffffff, 0.9);
    directionalLight.position.set(400, 200, 300);
    scene.add(directionalLight);
    // var point = new THREE.PointLight(0xffffff);
    // point.position.set(100, 100, 100); //点光源位置
    // scene.add(point); //点光源添加到场景中
    var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.9);
    directionalLight2.position.set(-400, -200, -300);
    scene.add(directionalLight2);

在这里插入图片描述

3.4、改变环境光

      var ambient = new THREE.AmbientLight(0xffffff, 0.6);
    //var ambient = new THREE.AmbientLight(0x444444);

在这里插入图片描述

3.5、改变背景颜色,修改球大小,增加凹凸性

   var geometry = new THREE.SphereGeometry(100, 40, 40); //创建一个球体几何对象

   //renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
   
   var material = new THREE.MeshPhongMaterial({
      // color: 0x0000ff,
      map: texLoader.load('./贴图/diffuse.png'),
       normalMap:  texLoader.load('./贴图/normal.png'),
      //设置深浅程度,默认值(1,1)。
      normalScale: new THREE.Vector2(2, 2),
    }); //材质对象Material

在这里插入图片描述

3.6、创建地球的全部代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>第一个three.js文件_WebGL三维场景</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="js/three.js"></script>
  <script src="OrbitControls.js"></script>
</head>

<body>
    <script>
      /**
       * 创建场景对象Scene
       */
      var texLoader = new THREE.TextureLoader();
      var scene = new THREE.Scene();
      /**
       * 创建网格模型
       */
      // TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
      
      // var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
      var geometry = new THREE.SphereGeometry(100, 25, 25);
      // MeshLambertMaterial
      var material = new THREE.MeshPhongMaterial({
        // color: 0x0000ff,
        // 设置颜色贴图
        map: texLoader.load('./贴图/diffuse.png'),
        //法线贴图
        normalMap:  texLoader.load('./贴图/normal.png'),
        //设置深浅程度,默认值(1,1)。
        normalScale: new THREE.Vector2(2, 2),
        //高光贴图
        specularMap: texLoader.load('./贴图/specular.png'),
      }); //材质对象Material
      var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      scene.add(mesh); //网格模型添加到场景中
      /**
       * 光源设置
       */
      // 平行光1
      var directionalLight = new THREE.DirectionalLight(0xffffff, 0.9);
      directionalLight.position.set(400, 200, 300);
      scene.add(directionalLight);
      // 平行光2
      var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.9);
      directionalLight2.position.set(-400, -200, -300);
      scene.add(directionalLight2);
      //环境光
      var ambient = new THREE.AmbientLight(0xffffff, 0.6);
      scene.add(ambient);
      /**
       * 相机设置
       */
      var width = window.innerWidth; //窗口宽度
      var height = window.innerHeight; //窗口高度
      var k = width / height; //窗口宽高比
      var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
      //创建相机对象
      var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(200, 300, 200); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      /**
       * 创建渲染器对象
       */
      var renderer = new THREE.WebGLRenderer({
        antialias: true, //开启锯齿
      });
      renderer.setSize(width, height); //设置渲染区域尺寸
      // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
  
      // 渲染函数
      function render() {
        renderer.render(scene, camera); //执行渲染操作
        //mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
        requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
      }
      render();
      //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
      var controls = new THREE.OrbitControls(camera, renderer.domElement);
    </script>
  </body>
</html>

四、创建天体运行案例

4.1、给地球添加三维坐标

      var axesHelper = new THREE.AxesHelper(200);
      scene.add(axesHelper);

其中200为三维坐标的长度
在这里插入图片描述

4.2、 创建另一个天体形状

首先缩小地球

  var geometry = new THREE.SphereGeometry(10, 25, 25); // 20 代表圆的直径

创建太阳

    var geometry2 = new THREE.SphereGeometry(30, 25, 25);
    var material2 = new THREE.MeshBasicMaterial({
    // 设置颜色贴图
    map: texLoader.load('./贴图/太阳.jpg'),
    }); //材质对象Material
    var mesh2 = new THREE.Mesh(geometry2, material2); //网格模型对象Mesh
    scene.add(mesh2); //网格模型添加到场景中

将地球进行沿着z轴平移

mesh.position.z = 150

开启自转

    // 渲染函数
      function render() {
        renderer.render(scene, camera); //执行渲染操作
        mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
        mesh2.rotateY(0.01);//每次绕y轴旋转0.01弧度
        requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
      }

效果如下
在这里插入图片描述

4.3、 使地球公转

通过angle改变位置

     var R = 130;// 地球公转半径
     var angle = 0;
     // 渲染函数
     function render() {
       renderer.render(scene, camera); //执行渲染操作
       mesh.rotateY(0.02);//每次绕y轴旋转0.01弧度
       mesh2.rotateY(0.01);//每次绕y轴旋转0.01弧度
       angle += 0.01;// 每次执行render角度新增加
       var x = R*Math.sin(angle);//地球x坐标计算
       var z = R*Math.cos(angle);//地球z坐标计算
     // 设置地球xz坐标,实现公转动画
       mesh.position.set(x,0,z);
       requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
     }

效果图:
在这里插入图片描述

4.4、 绘制轨迹路线

      var R = 130;// 地球公转半径
      circle(R);//调用函数circle绘制圆弧轨迹
      
      function circle(r) {
	      // ArcCurve创建一个圆弧曲线
	      var arc = new THREE.ArcCurve(0, 0, r, 0, 2 * Math.PI, true);
	      // 获取点数越多,圆弧越光滑
	      var points = arc.getPoints(100); //返回一个vector2对象作为元素组成的数组
	      // console.log('points', points);
	      var geometry = new THREE.Geometry();
	      //setFromPoints方法的本质:遍历points把vector2转变化vector3
	      geometry.setFromPoints(points);
	      var material = new THREE.LineBasicMaterial({
	        color: 0x006666,
	      });
	      // THREE.Line
	      var line = new THREE.LineLoop(geometry, material); //起始点闭合
	      // 圆弧线默认在XOY平面上,绕x轴旋转到XOZ平面上
	      line.rotateX(Math.PI / 2);
	      scene.add(line);
      }

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值