Three.js初识

307 阅读3分钟

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

1,three.js 介绍

​ 再次学习three.js, 心中感慨良多,之前是因为接到一个私人项目,需要实现Web3D功能,当时因为项目赶的急,没有系统的,全局的把学习的过程做下总结,这次回过头认认真真的总结一下。

Three.js是基于原生的WebGL API 和 着色器封装得到的3D引擎,也就是一个js库。 大家知道,如果想通过原生的WebGL直接编写程序,会比较麻烦,于是就有很多牛人封装了它,目前大家使用最多的就是Three.js, 总而言之,如果想彻底学透Three.js, 必须学习WebGL, 而且想成为高手,必须要补充自己的3D知识。

github下载地址: github.com/mrdoob/thre…

相关库:

库名描述
stats.jsJavaScript性能监控器,可测试WebGL的渲染性能
dat.gui控制WebGL中一个物体的尺寸,颜色等
tween.js控制机械,游戏角色运动
Physijs模拟物理想象,比如重力下落,物体碰撞等等,是一款物理引擎
ThreeBSP可以作为Three.js的插件,完成几何模型的布尔

2, three.js结构

在熟悉结构之前,先熟悉几个单词,

  • Geometry 几何体

    # 创建一个立方体几何对象, 
    var geometry == new THREE.BoxGeometry(100, 100, 100)
    

    任何几何体都有三个参数:分包在坐标系中表示:(x, y, z)

​ 其中,在Geometry前面添加什么单词,表示几个体是什么形状, 常见的几何体如下:

BoxGeometry:  立方体几何对象
CircleGeometry: 圆体几何对象
PlaneGeometry: 地面几何对象
SphereGeometry: 球体几何对象
ConeGeometryCylinderGeometryDodecahedronGeometryEdgesGeometry
ExtrudeGeometryIcosahedronGeometryLatheGeometryOctahedronGeometry
PolyhedronGeometryRingGeometryShapeGeometryTetrahedronGeometryTorusGeometryTorusKnotGeometryTubeGeometryWireframeGeometry

比如:创建一个球体几何对象

var geometry = new THREE.SphereGeometry(60, 40, 40)
  • Meterial 材质
# 创建一个可以用于立方体的材质对象
var meterial = new MeshLambertMaterial({color: 0xeeeeee})

注意:这个材质对象包含了颜色,透明度,其中颜色使用的是16进制

其中,在Material前面添加什么单词,就表示是什么材质,常见的材质如下:

LineBasicMaterial, 
LineDashedMaterial,
MeshBasicMaterial, 
MeshDepthMaterial, 
MeshDistanceMaterial,
MeshLambertMaterial,
MeshMatcapMaterial, 
MeshNormalMaterial
MeshPhongMaterial,
MeshPhysicalMaterial,
MeshStandardMaterial
MeshToonMaterial, 
PointsMaterial,
RawShaderMaterial,
ShaderMaterial,
ShadowMaterial, 
SpriteMaterial
  • Light 光源
# 创建一个点光源对象
var point = new THREE.PointLight(0xffffff)

注意:这里的光源对象有一个参数,可以表示光照强度,常见的还有哪些光源对象:

AmbientLight, 
AmbientLightProbe,
DirectionalLight, 
DirectionalLightShadow,
HemisphereLight,
HemisphereLightProbe,
LightProbe,
LightShadow,
PointLight,
PointLightShadow
RectAreaLight,SpotLight,SpotLightShadow
  • Camera 相机

    # 创建一个正射投影的相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)
    

    注意:这里的参数控制着拍照窗口的大小,还有取景范围大小,后续会详细介绍

    常见的相机对象如下:

    OrthographicCamera,
    ArrayCamera,
    Camera,
    CubeCamera,
    PerspectiveCamera,
    StereoCamera
    

    借用网上的一幅图片,记忆一下整个程序的结构

1642951161728.png

总结一下: 立方体网格模型和光照组成了一个虚拟的三维常见,相机对象,通过设置相机的位置和角度,创建一个三维场景,最后通过渲染器进行拍照显示。

场景—相机—渲染器

3, 创建一个地面,并添加三维坐标系

新建项目three, 引入three.js文件, 创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three.js</title>
  <script src="./lib/three.js"></script>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>
<body>
   <!-- 页面容器显示画面 -->
   <div id="webgl"></div>
   <script>
      function init() {
        // 创建场景
        const scene = new THREE.Scene();
        // 设置摄像机
        const camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 2000)
        // 创建渲染器
        const renderer = new THREE.WebGLRenderer()
        // 设置渲染器的初始颜色
        renderer.setClearColor(new THREE.Color(0xeeeeee))
        // 设置输出canvas画面大小
        renderer.setSize(window.innerWidth, window.innerHeight)
        // 方便学习,显示三维坐标系
        const axes = new THREE.AxisHelper(20)

        // 添加坐标系到场景中
        scene.add(axes)
        // 创建几何体
        const planeGeometry = new THREE.PlaneGeometry(60, 20)
        // 给地面物体上色
        var planeMaterial = new THREE.MeshBasicMaterial({color: 0xcccccc})
        // 创建地面
        const plane = new THREE.Mesh(planeGeometry, planeMaterial)
        // 物体移动位置
        plane.rotation.x = -0.5 * Math.PI
        plane.position.x = 15;
        plane.position.y = 0;
        plane.position.z = 0;
        // 将地面添加到场景中
        scene.add(plane)
        // 定位相机,并且指向场景中心
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position)
        
        // 将渲染器添加到html元素
        document.getElementById('webgl').appendChild(renderer.domElement)
        renderer.render(scene, camera)
      }
      window.onload = init
   </script>
</body>
</html>

效果图如下:

1642951620843.png

4, 项目源码

项目代码地址和文档中的截图都是同步的,都已经实现

[持续更新中]

gitee.com/jamiedawn/t…