Three.js入门_纹理贴图,载入.glb模型

2,698 阅读1分钟

这一次来实现一个加入纹理贴图和.glb格式模型的场景。 最后的效果基本如下:

IMG_2486 (2).GIF

最初我想做的时直升飞机在绿色的草坪起飞,由于经费和时间有限就先实现一个低配版的场景但也不妨碍我使用API 😂 来继续进行。

前期场景准备基础场景

 this.scene = new Three.Scene() //构建场景
this.scene.fog = new Three.FogExp2(0xefd1b5, 0.0025) //场景的雾化效果
  var camera = new Three.PerspectiveCamera(
        120,
        window.innerWidth / window.innerHeight,
        0.1,
        2000
      )
         //  定位相机 指向场景中心
      camera.position.set(-20, 40, 30) //设置相机位置
      camera.lookAt(this.scene.position) //设置相机方向(指向的场景对象)
      this.camera = camera
        //  创建渲染器
      var renderer = new Three.WebGLRenderer()
      // 渲染器初始颜色
      renderer.setClearColor(new Three.Color(0xb9d3ff))
      // 输出canvas画面大小
      renderer.setSize(window.innerWidth, window.innerHeight)
      this.renderer = renderer
        var pointLight = new Three.PointLight(0xffffff)
      pointLight.position.set(-60, 100, 100)
      this.scene.add(pointLight)
     
        this.addGrassGem() //加入草地
        //将渲染器加载到dom里
        document.getElementById('contanier').appendChild(this.renderer.domElement)
        
        


1.使用(Texture)纹理贴图加入一片草地
addGrassGem(){
 const geometry = new Three.PlaneGeometry(10000, 10000)
      const texture = new Three.TextureLoader().load(
        'https://img0.baidu.com/it/u=3054322455,2150588617&fm=253&fmt=auto&app=120&f=JPEG? w=500&h=333'
      )
      // 纹理在水平和垂直方向的扩展方式
      texture.wrapS = Three.RepeatWrapping
      texture.wrapT = Three.RepeatWrapping
      texture.repeat.set(100, 100) //贴图阵列
      const grassMaterial = new Three.MeshBasicMaterial({ map: texture })
      const grass = new Three.Mesh(geometry, grassMaterial)
      grass.rotation.x = -0.5 * Math.PI
      this.scene.add(grass)
      }

构造函数Texture(image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding)

THREE.ClampToEdgeWrapping(超出的部分取纹理边缘的颜色)

THREE.RepeatWrapping(超出后重复填充)

THREE.MirroredRepeatWrapping(镜像,当纹理的整数部分是奇数是重复平铺,偶数是对应翻转)

  • wrapT : 定义贴图在垂直方向如何包裹(可选属性值参照wrapS)

  • repeat :定义切图两个方向上重复的次数仅 wrapS ,wrapT 为THREE.RepeatWrapping/THREE.MirroredRepeatWrapping有效

  • rotation :纹理沿着中心点转动的弧度(rad)正值为逆时针方向。

  • center :设置旋转中心点默认(0,0)

还有一些矩阵变化属性 这里没有用到暂时不记录

2.加载GLB模型

GLB模型是一种场景动画集合模型

    loadGltf() {
      // vue加载glb模型通过DRACOLoader压缩
      const loader = new GLTFLoader()
      // DRACOLoader压缩模型
      const dracoLoader = new DRACOLoader()
      // 压缩方法路径
      dracoLoader.setDecoderPath('./moduler/draco/')
      dracoLoader.preload()
      console.log(dracoLoader, 'dracoLoader')
      loader.setDRACOLoader(dracoLoader)
      loader.load(
        'https://10.54.14.123:8084/mapData/CesiumAir/Cesium_Air.glb',
        (gltf) => {
          // 将模型的整个 scene 添加到我们的场景里。虽然它的名字是 scene,实际上是一个 Three.Group
          console.log(gltf, 'gltfgltfgltf')
          gltf.scene.position.set(0, 2, 0)
          gltf.scene.rotation.y = 110
          this.scene.add(gltf.scene)
          this.airPlane = gltf.scene
          this.renderer.render(this.scene, this.camera)
          this.animate()
        },
        (xhr) => {
          console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
        },
        (error) => {
          console.error(error)
        }
      )
    },

微信图片_20220913134138.jpg

3.由于模型没有动画先加入简单位移动画

  animate() {
      //   // 使用动画效果,浏览器全新的动画效果
      window.requestAnimationFrame(this.animate)
      //   // 设置模型网格的坐标
      this.airPlane.position.z -= 0.5
      if (this.airPlane.position.z <= -20) {
        this.airPlane.position.y += 0.1
      }
      // 将场景和图形动态的渲染到渲染器上去
      this.renderer.render(this.scene, this.camera)
    },