ttp://www.xwwzsj.com/weixin#item4">小程序开发
  • 案例展示
  • 新闻资讯
  • 解决方案
  • 瑞达杰昌建站
  • 联系我们
  • 客户专线:135-1821-9792

    服务热线:028-86922220

    我们专注于高端品牌网站创意设计与开发

  • 怎么使用Three.js实现太阳系八大行星的自转公转

    这篇文章将为大家详细讲解有关怎么使用Three.js实现太阳系八大行星的自转公转,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    创新互联是一家从事企业网站建设、做网站、成都网站建设、行业门户网站建设、网页设计制作的专业的建站公司,拥有经验丰富的网站建设工程师和网页设计人员,具备各种规模与类型网站建设的实力,在网站建设领域树立了自己独特的设计风格。自公司成立以来曾独立设计制作的站点超过千家。

    一. Three.js框架简介

    Three.js是用javascript编写的WebGL第三方库,运用three.js框架写3D程序,就如同在现实生活中观察一个3D场景一样,让人置身其中。介绍three.js必须提到它的三大组件,Scene,Camera,Render。它们是整个框架的基础,有了这三个组件才能将物体渲染到网页上,实现整个场景的搭建。

    场景(scene)

    顾名思义,就是用来放置所有的元素。

    var scene = new THREE.Scene(); //建立场景

    相机(camera)

    相机,我们要在哪个位置,如何去看这些元素。

    相机分为多种,不展开介绍,这里我们使用的是 透视相机。

    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); //设置相机为 角度60度,宽高比,最近端Z轴为1,最远端Z轴为10000

    我们可以通过一张来自three.js文档中的图片来了解这些属性

    怎么使用Three.js实现太阳系八大行星的自转公转

    渲染器(render)

    当把场景中的所有内容准备好后,就可以对场景进行渲染,表示我们怎样来绘制这些元素。

    渲染器也分为多种,这里使用的是WebGLRenderer;

    var renderer = new THREE.WebGLRenderer();

    具体步骤:建立元素->定义相机->搭建场景->将元素和相机放入场景中->渲染场景

    具体代码我们会在后面介绍,然后让我们先瞅一眼效果图。

    二. 基本初始化

    这里直接在cdn上引入three.js

    注:因为某些行星的大小,转速,距离差距过大,所以进行了一些不平衡调整。

    下面将一一分析这些元素是如何放入的。

    1.canvas

    我们没有把场景直接挂载到body中,而是在body中放置了一个canvas画布,在其上显示。

    2.背景

    我们没有做3D的旋转背景,而是直接放了一张背景图作为小太阳系的背景。这张背景图是直接在canvas中放置的。

    
    renderer = new THREE.WebGLRenderer({ //定义渲染器
       alpha: true, //让背景透明,默认是黑色,以显示我们自己的背景图
      });
    renderer.setClearAlpha(0);
    //css文件
    #webglcanvas {
       background: url(./images/bg4.jpg) no-repeat;
       background-size: cover;
      }

    但如果只是这样简单的操作是没有用的,因为在添加渲染器后,会默认添加一个背景颜色为黑色。所以要在渲染器中设置它的alpha属性(WebGL渲染器及属性方法),让背景透明,以显示我们自己的背景图

    3.定义基本组件

    定义场景

    scene = new THREE.Scene(), //建立场景

    定义照相机位置

    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1,10000); //设置相机为 角度60度,宽高比,最近端Z轴为1,最远端Z轴为10000
      camera.position.z = 2000; //调整相机位置
      camera.position.y = 500;

    建立一个组

    组可以看作是一些元素的容器,将某些有共同特征的元素放在一个组里。

    group = new THREE.Group(), //建立一个组

    我会在第三节解释为什么要建立额外16个组。

     //下面这些组用来建立每个星球的父元素,以实现 八大行星不同速度的公转与自转
      var group1 = new THREE.Group();
       groupParent1 = new THREE.Group();
       group2 = new THREE.Group();
       groupParent2 = new THREE.Group();
       group3 = new THREE.Group();
       groupParent3 = new THREE.Group();
       group4 = new THREE.Group();
       groupParent4 = new THREE.Group();
       group5 = new THREE.Group();
       groupParent5 = new THREE.Group();
       group6 = new THREE.Group();
       groupParent6 = new THREE.Group();
       group7 = new THREE.Group();
       groupParent7 = new THREE.Group();
       group8 = new THREE.Group();
       groupParent8 = new THREE.Group();

    定义渲染器

    WebGLRenderer中有一个用来绘制输出的canvas对象,现在获取设置的canvas放入我们渲染器中的canvas对象中

    var canvas = document.getElementById('webglcanvas'),
    renderer = new THREE.WebGLRenderer({ //定义渲染器
       alpha: true, //让背景透明,默认是黑色 以显示我们自己的背景图
       canvas: canvas, //一个用来绘制输出的Canvas对象
       antialias: true //抗锯齿
      });
    renderer.setSize(window.innerWidth, window.innerHeight); //设置渲染器的宽高

    4.初始化函数

    在这个函数中进行一系列的初始化操作。

    function init() {  //用来初始化的函数
       scene.add(group); //把组都添加到场景里
    
       scene.add(groupParent1);
       scene.add(groupParent2);
       scene.add(groupParent3);
       scene.add(groupParent4);
       scene.add(groupParent5);
       scene.add(groupParent6);
       scene.add(groupParent7);
       scene.add(groupParent8);
       
       var loader = new THREE.TextureLoader();/*材质 纹理加载器*/
       // 太阳
       loader.load('./images/sun1.jpg', function (texture) {  
        var geometry = new THREE.SphereGeometry(250, 20, 20) //球体模型 
        var material = new THREE.MeshBasicMaterial({ map: texture }) //材质 将图片解构成THREE能理解的材质
        var mesh = new THREE.Mesh(geometry, material);  //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
        group.add(mesh);//添加到组里
       })
       // 水星
       loader.load('./images/water.jpg', function (texture) {
        var geometry = new THREE.SphereGeometry(25, 20, 20) //球型 
        var material = new THREE.MeshBasicMaterial({ map: texture }) //材质 将图片解构成THREE能理解的材质
        var mesh = new THREE.Mesh(geometry, material);
        group1.position.x -= 300;
        group1.add(mesh);
        groupParent1.add(group1);
       })
       //其它7颗行星参数因为太长了在这里就不给出了,但参数的设置原理都是一样的
       }

    简要解释一下:

    var loader = new THREE.TextureLoader();是定义了一个材质纹理加载器。

    var geometry = new THREE.SphereGeometry(250, 20, 20);建立一个球体模型,球体半径为250,水平分割面的数量20,垂直分割面的数量20。

    var mesh = new THREE.Mesh(geometry, material);网孔对象。

    具体作用就是创建一个球体元素,先构建框架,在用行星的平面图将它包裹起来,就形成了一颗行星,再把这颗行星添加到组里,之后再把组添加到场景里。这里就构建单个元素的过程。

    那么为什么太阳直接添加到组里,而水星要用两个组层级添加,且给它的位置设偏移呢。我们来到第三节。

    三. 自转同时公转

    旋转方式:我们要实现旋转功能有三种方式

    1.旋转照相机  2.旋转整个场景(Scene)  3.旋转单个元素。

    因为我们这里每个行星的自转速度,公转速度都不一样。所以设置整体旋转并不可行,所以要给每个元素设置不同的旋转属性。

    旋转机制:这里介绍物体的rotation属性,相对于自身旋转。

    例如:

    scene.rotation.y += 0.04; //整个场景绕自身的Y轴逆时针旋转

    进入正题

    怎么使用Three.js实现太阳系八大行星的自转公转

    Scene中的所有元素使用rotation.y属性,默认旋转轴都为这根Y轴,因为它们初始化Y轴就是这根轴。
    所以让太阳旋转直接让它的组旋转就行了group.rotation.y += 0.04;

    而其它行星需要让它们围绕着太阳转,就要先给它们自身设置一个位置偏移。例如水星:group1.position.x -= 300;  而此时设置group1.rotation.y属性,它就会实现自转。因为它的Y轴位置已经改变了。

    怎么使用Three.js实现太阳系八大行星的自转公转

    那么此时要想再实现公转,在这个对象中是找不到默认Y轴这根线的。所以我们给group1再设置了一个“父元素”groupParent1。groupParent1.add(group1);

    当我们移动了group1时,groupParent1的位置是没有变的,自然它的Y轴也不会变,又因为groupParent1包含了group1,所以旋转groupParent1时,group1也会绕着初始的默认Y轴旋转。所以设置那么多组,是为了实现每颗行星不同的速度和公转的同时自转。

    怎么使用Three.js实现太阳系八大行星的自转公转

    四. 其他实现函数

      function render() {
       renderer.render(scene, camera);
       camera.lookAt(scene.position); //让相机盯着场景的位置 场景始终在中间
      }
      //设置公转
      function revolution(){
       groupParent1.rotation.y += 0.15;
       groupParent2.rotation.y += 0.065;
       groupParent3.rotation.y += 0.05;
       groupParent4.rotation.y += 0.03;
       groupParent5.rotation.y += 0.001; 
       groupParent6.rotation.y += 0.02;
       groupParent7.rotation.y += 0.0005;
       groupParent8.rotation.y += 0.003;
      }
      //设置自转
      function selfRotation(){
       group.rotation.y += 0.04;
       group1.rotation.y += 0.02;
       group2.rotation.y -= 0.005;
       group3.rotation.y += 1;
       group4.rotation.y += 1;
       group5.rotation.y += 1.5;
       group6.rotation.y += 1.5;
       group7.rotation.y -= 1.5;
       group8.rotation.y += 1.2;
      }
      function Animation() {
       render();
       selfRotation();
       revolution();
       requestAnimationFrame(Animation); 
      }

    最后再调用一下 init()Animation()函数就OK了。

    关于“怎么使用Three.js实现太阳系八大行星的自转公转”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


    标题名称:怎么使用Three.js实现太阳系八大行星的自转公转
    分享地址:http://xwwzsj.com/article/gsecjj.html

    其他资讯

    售后响应及时

    7×24小时客服热线

    数据备份

    更安全、更高效、更稳定

    价格公道精准

    项目经理精准报价不弄虚作假

    合作无风险

    重合同讲信誉,无效全额退款