Three.js - 场景(Scene)(十)

2,352 阅读2分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

右手坐标系

  • three.js中使用的是右手坐标系,原因是webGL默认的就是这种坐标系。
  • 简单理解就是,x轴正方向向右,y轴正方向向上,z轴正方向由屏幕从里向外
  • 在场景中所有的物体在容器的位置都是依靠这个坐标系设置的。

image.png

场景

image.png

  • 正如之前说的,它就相当于一个大容器,我们需要展示的所有物体都要放入场景
  • 它又被称为场景图,因为它是一个树形结构数据。
  • 能放入场景中的对象都继承了Object3D对象,所以每一个子节点都有自己的局部空间。简单理解就是场景中有一个空间可以添加组、Object3D、网格等物体类型,子节点也是一个小容器,同样可以添加组、Object3D、网格等物体类型。区别就是,子节点设置的坐标位置是相对于父节点的局部空间坐标来改变的。

常用属性

  1. .background 设置场景的背景。
  2. .fog 控制场景中的每个物体的雾的类型。
  3. .environment 设置场景中没有纹理物体的默认纹理,如物体有纹理不会修改其纹理。
  4. .children 返回场景的所有子对象。

常用方法

  1. .add() 添加对象。
  2. .remove() 删除已添加对象。
  3. .getObjectByName(name,recursive) 在创建对象时可以指定唯一的标识name,使用该方法可以查找特定名字的对象。recursive布尔对象,false:子元素上查找。true:所有后代对象上查找。

实例

  • 基础模板
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>学习</title>
  </head>
  <body>
    <canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
    <script type="module">
      import * as THREE from 'https://threejs.org/build/three.module.js'
      import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'

      const canvas = document.querySelector('#c2d')
      // 渲染器
      const renderer = new THREE.WebGLRenderer({ canvas })

      const fov = 40 // 视野范围
      const aspect = 2 // 相机默认值 画布的宽高比
      const near = 0.1 // 近平面
      const far = 1000 // 远平面
      // 透视投影相机
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
      camera.position.set(0, 10, 20)
      camera.lookAt(0, 0, 0)

      // 控制相机
      const controls = new OrbitControls(camera, canvas)
      controls.update()

      // 场景
      const scene = new THREE.Scene()
      scene.background = new THREE.Color('white')

      {
        // 光源
        const color = 0xffffff
        const intensity = 1
        const light = new THREE.DirectionalLight(color, intensity)
        scene.add(light)
      }

      {
        // 几何体
      }

      // 渲染
      function render() {
        renderer.render(scene, camera)
        requestAnimationFrame(render)
      }

      requestAnimationFrame(render)
    </script>
  </body>
</html>
  • 为了更好的区别局部坐标和全局坐标,这里使用了类型。在类型添加两个物体,各自上下移动。
      // 球
      const radius = 1
      const widthSegments = 36
      const heightSegments = 36
      const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments)

      // 立体体
      const boxWidth = 6
      const boxHeight = 6
      const boxDepth = 6
      const boxGeometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)

      // 材质
      const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 })
      {
        // 添加全局坐标位置
        const axes1 = new THREE.AxesHelper()
        scene.add(axes1)

        // 网格1
        const mesh1 = new THREE.Mesh(sphereGeometry, material)
        // 相对坐标 x 移动5
        mesh1.position.x = 5
        // 全局坐标 移动
        scene.add(mesh1)

        // 创建组
        const group = new THREE.Group()
        group.position.x = -5
        // 旋转
        group.rotation.x = 1
        // 全局坐标 移动
        scene.add(group)

        // 添加局部坐标系位置
        const axes2 = new THREE.AxesHelper()
        group.add(axes2)

        // 网格2
        const mesh2 = new THREE.Mesh(sphereGeometry, material)
        // 相对坐标 x 移动5
        mesh2.position.y = 5

        // 网格3
        const mesh3 = new THREE.Mesh(boxGeometry, material)
        // 相对坐标 x 移动5
        mesh3.position.y = -5
        // 组 局部坐标移动
        group.add(mesh2)
        group.add(mesh3)
      }

1.gif

  • 这里使用了.AxesHelper()给全局坐标和局部坐标都添加了坐标系。局部坐标的位置和坐标的方向都是group对象的改变后的。能清楚的看见,网格2、网格3位置都是在group改变后的坐标上变化的。