Three.js 入门认识基础自学

Three.js 认识

  1. 英文文档

  2. 中文文档 / 教程

  3. 初级使用,无须深究原理、根着文档调用接口 、new对象 就OK

  4. 编辑器选择 vscode 接着安装插件 live server 然后右击文件 选择open with live server 打开

淘宝教育某课程demo

code

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="JS/three.js"></script>
    <script src="JS/MTLLoader.js"></script>
    <script src="JS/OBJLoader.js"></script>
</head>
<body>
  <script>
      //创建场景,相机,渲染器,网格
      var scene,camera,renderer,mesh;
      var meshfloor,ambientLight,light;
      var crate,crateTexture,crateNormalMap,crateBumpMap;
      //diffuse texture 漫反射贴图 normal texture 法线贴图  Bump Mapping 凹凸贴图
      var keyboard={};
      //是否射击的变量
      var player={height:1.8,speed:0.2,turnSpeed:Math.PI*0.05,canShoot:0};
      // 创建一个对象,用于存放加载场景所需的所有内容
      var loadingScreen={
          scene:new THREE.Scene(),
          camera:new THREE.PerspectiveCamera(90,1280/720,0.1,100),
          box:new THREE.Mesh(
                  new THREE.BoxGeometry(1,1,1),
                  new THREE.MeshBasicMaterial({
                      color:0x4444ff,
                      wireframe:true
                  })
          )
      }

      //创建一个加载管理器
      var loadingManager=null;
      //创建下载是否完成的布尔值
      var Resource_Loaded=false;

      // 模型索引
      var models={
          female:{
              obj:"Models/female02.obj",
              mtl:"Models/female02.mtl",
              mesh:null
          } ,
          zombie:{
              obj:"Models/zombie.obj",
              mtl:"Models/zombie.mtl",
              mesh:null
          },
          zombieBlue:{
              obj:"Models/zombie_blue.obj",
              mtl:"Models/zombie_blue.mtl",
              mesh:null
          },
          //添加武器模型及材质
          gun:{
              obj:"Models/gun.obj",
              mtl:"Models/gun.mtl",
              mesh:null,
              castShadow:false
          }
      }

      // 网格索引
      var meshes={};

      //创建一个数组来保存子弹
      var bullets=[];

      //设置加载场景对象的一些属性
      loadingScreen.box.position.set(0,0,5);
      loadingScreen.camera.lookAt(loadingScreen.box.position);
      loadingScreen.scene.add(loadingScreen.box);

      scene=new THREE.Scene();
      camera=new THREE.PerspectiveCamera(90,1280/720,0.1,100);

      //实例化加载管理器
      loadingManager=new THREE.LoadingManager();

      //加载过程
     loadingManager.onProgress=function(item,loaded,total){
         console.log(item,loaded,total);
     }
      //加载完成
      loadingManager.onLoad=function() {
          console.log("已下载所有资源!");
          Resource_Loaded=true;
          onResourceLoaded();
      }

      mesh=new THREE.Mesh(
              new THREE.BoxGeometry(1,1,1),
              //new THREE.SphereGeometry(1,20,20),
              //MeshBasicMaterial 对光照无反应
              new THREE.MeshPhongMaterial({color:0x0000ff,wireframe:false})
              // 0xff0000 红色
              // 0x00ff00 绿色,
              // 0x0000ff 蓝色.
              // 0xffffff 黑色
              // 0x000000 白色
      )
      mesh.receiveShadow=true;
      mesh.castShadow=true;
      mesh.position.y+=1;

      meshfloor=new THREE.Mesh(
              new THREE.PlaneGeometry(20,20,10,10),
              new THREE.MeshPhongMaterial({color:0xffffff,wireframe:false})
      )
      meshfloor.rotation.x -=Math.PI/2;
      meshfloor.receiveShadow=true;

      //加载贴图 在参数中添加加载管理器
      var textureLoader=new THREE.TextureLoader(loadingManager);
      crateTexture=textureLoader.load("Img/01.jpg");
      crateNormalMap=textureLoader.load("Img/02.jpg");
      crateBumpMap=textureLoader.load("Img/03.jpg");

      crate=new THREE.Mesh(
              new THREE.BoxGeometry(3,3,3),
              new THREE.MeshPhongMaterial({
                  color:0xffffff,
                  map:crateTexture,
                  normalMap:crateNormalMap,
                  bumpMap:crateBumpMap
              })
      )
      crate.position.set(2.5,3/2,2.5);
      crate.receiveShadow=true;
      crate.castShadow=true;

      scene.add(mesh);
      scene.add(meshfloor);
      scene.add(crate);

      // 加载模型
      for(var _key in models){
          (function(key){
              //加载模型和材质
              var mtlLoader=new THREE.MTLLoader(loadingManager);
              mtlLoader.load(models[key].mtl,function(materials){
                  materials.preload();
                  var objLoader=new THREE.OBJLoader(loadingManager);
                  objLoader.setMaterials(materials);
                  objLoader.load(models[key].obj,function(mesh){
                      //给加载的人物模型加上阴影
                      mesh.traverse(function(node){
                          if(node instanceof THREE.Mesh){
                              if('castShadow' in models[key])
                                  node.castShadow=models[key].castShadow;
                              else
                                  node.castShadow=true;
                              if('receiveShadow' in models[key])
                                  node.receiveShadow=models[key].receiveShadow;
                              else
                                  node.receiveShadow=true;
                              //node.castShadow=true;
                              //node.receiveShadow=true;
                          }
                      });
                      models[key].mesh=mesh;
                  });
              });
          })(_key)
      }

     //环境光
      ambientLight=new THREE.AmbientLight(0xffffff,0.5);
      scene.add(ambientLight);
      //点光
      light=new THREE.PointLight(0xffffff,0.8,18);
      light.position.set(0,2,0);
      light.castShadow=true;

      light.shadow.camera.near=0.1;
      light.shadow.camera.far=25;

      scene.add(light);

      camera.position.set(0,player.height,-5);
      camera.lookAt(new THREE.Vector3(0,player.height,0))
      renderer=new THREE.WebGLRenderer()
      renderer.setSize(1280,720);
      //给渲染器添加阴影效果
      renderer.shadowMap.enabled=true;
      renderer.shadowMap.type=THREE.BasicShadowMap;
      //把画面插入HTML中的body标签下显示
      document.body.appendChild(renderer.domElement);
      animate();
     function onResourceLoaded(){
         // 将模型克隆到网格中
         meshes["female"]=models.female.mesh.clone();
         meshes["female2"]=models.female.mesh.clone();
         meshes["zombie"]=models.zombie.mesh.clone();
         meshes["zombie2"]=models.zombieBlue.mesh.clone();

         meshes["female"].position.set(-5,0,4);
         meshes["female"].scale.set(0.03,0.03,0.03);
         meshes["female"].rotation.y = -Math.PI/1;
         scene.add (meshes["female"]);

         meshes["female2"].position.set(-8,0,4);
         meshes["female2"].scale.set(0.03,0.03,0.03);
         meshes["female2"].rotation.y = -Math.PI/1;
         scene.add(meshes["female2"]);

         meshes["zombie"].position.set(-5,0,6);
         meshes["zombie"].scale.set(0.08,0.08,0.08);
         meshes["zombie"].rotation.y = -Math.PI/1;
         scene.add (meshes["zombie"]);

         meshes["zombie2"].position.set(-1,0,6);
         meshes["zombie2"].scale.set(0.08,0.08,0.08);
         meshes["zombie2"].rotation.y = -Math.PI/1;
         scene.add(meshes["zombie2"]);

         //玩家的武器
         meshes["gun"]=models.gun.mesh.clone();
         meshes["gun"].position.set(-1,1,10);
         meshes["gun"].scale.set(15,15,15);
         //meshes["zombie2"].rotation.y = -Math.PI/1;
         scene.add(meshes["gun"]);

    }
      function animate() {
          // 在加载资源时运行此块代码
          if(Resource_Loaded==false){
              requestAnimationFrame(animate);
              loadingScreen.box.position.x-=0.05;
              if(loadingScreen.box.position.x<-10)
              loadingScreen.box.position.x=10;
              loadingScreen.box.position.y=Math.sin(loadingScreen.box.position.x);
              renderer.render(loadingScreen.scene,loadingScreen.camera);
              return;
          }

          requestAnimationFrame(animate);
         var time=Date.now()*0.0005;

          mesh.rotation.x+=0.01;
          mesh.rotation.y+=0.02;
          renderer.render(scene,camera);

          //子弹更新位置
          //删除消失的子弹
          for(var index=0; index<bullets.length;index+=1){
              if(bullets[index]===undefined) continue;
              if(bullets[index].alive==false){
                  bullets.splice(index,1);
                  continue;
              }
              bullets[index].position.add(bullets[index].velocity);
          }
          //键盘移动输入
          if(keyboard[87]){ //W key
              //Math.sin(x)    x 的正玄值。返回值在 -1.0 到 1.0 之间;
              //Math.cos(x)    x 的余弦值。返回的是 -1.0 到 1.0 之间的数;
              camera.position.x+=Math.sin(camera.rotation.y)*player.speed;
              camera.position.z+=Math.cos(camera.rotation.y)*player.speed;
          }
          if(keyboard[83]){ //S key
              camera.position.x-=Math.sin(camera.rotation.y)*player.speed;
              camera.position.z-=Math.cos(camera.rotation.y)*player.speed;
          }

          if(keyboard[65]){ //A key
              camera.position.x+=Math.sin(camera.rotation.y+Math
                      .PI/2)*player.speed;
              camera.position.z-=Math.cos(camera.rotation.y+Math.PI)*player.speed;
          }

          if(keyboard[68]){ //D key
              camera.position.x+=Math.sin(camera.rotation.y-Math
                      .PI/2)*player.speed;
              camera.position.z-=Math.cos(camera.rotation.y-Math.PI)*player.speed;
          }

          if(keyboard[37]) { //左边箭头键
              camera.rotation.y-=player.turnSpeed;
          }

          if(keyboard[39]) { //右边箭头键
              camera.rotation.y+=player.turnSpeed;
          }

          //射击
          if(keyboard[32] && player.canShoot<=0) { //空格键
              //创建一个子弹的网格和几何体
              var bullet =new THREE.Mesh(
                      new THREE.SphereGeometry(0.05,8,8),
                      new THREE.MeshBasicMaterial({color:0xfffffff})
              )
              //子弹产生的位置
              bullet.position.set(
                      meshes["gun"].position.x,
                      meshes["gun"].position.y+0.025,
                      meshes["gun"].position.z
              )
              //子弹的速度
              bullet.velocity=new THREE.Vector3(
                      -Math.sin(camera.rotation.y),
                      0,
                      Math.cos(camera.rotation.y)
              )
              //到一定时间后让子弹消失
              bullet.alive=true;
              setTimeout(function(){
                  bullet.alive=false;
                  scene.remove(bullet);
              },1000);

              bullets.push(bullet);
              scene.add(bullet);
              player.canShoot=30;
          }

          if(player.canShoot>0)
          player.canShoot-=1;

          //var time=Date().now()*0.0005;
          //将枪放在相机前面
          meshes["gun"].position.set(
                  camera.position.x-Math.sin(camera.rotation.y+Math
                          .PI/6)*0.75,
                  camera.position.y-0.4+Math
                          .sin(time*4+camera.position.x+camera.position.z)*0.01,
                  camera.position.z+Math
                          .cos(camera.rotation.y+Math
                                  .PI/6)

          );

          meshes["gun"].rotation.set(
                  camera.rotation.x,
                  camera.rotation.y-Math.PI,
                  camera.rotation.z
          );

      }

      function keyDown(event){
          keyboard[event.keyCode]=true;
      }

      function keyUp(event) {
          keyboard[event.keyCode]=false;
      }

      window.addEventListener('keydown',keyDown);
      window.addEventListener(('keyup'),keyUp);
  </script>
</body>
</html>

个人博客停止维护,部分博客转载到这

  • 彼特城
  • 2020-11-04 15:22:41
本作品采用《CC 协议》,转载必须注明作者和本文链接
滴水穿石,石破天惊----晓疯子
zhaocrazy
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!