1 Star 0 Fork 5

王飞/vue2-threejs

forked from 沈绪哲/vue2-threejs 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
2年前
2年前
Loading...
README

vue2-threejs

新手入门教程(本工程以此书为导向书写):http://www.yanhuangxueyuan.com/Three.js/

本项目版本为: "three": "^0.146.0" 新手入门教程不能完全的适用本项目(部分 API 改名或者删除)

需要配合原文档及代码 一起看

文档

相关资源库

资源

打开预览 Three.js 案例(跨域问题)

vue 工程将模型数据 放在 public 文件夹下

不需要加载外部贴图和模型文件的 three.js 案例,可以直接使用浏览器打开.html 案例文件,通常一个 threejs 项目案例往往都会加载一些外部模型,因此打开 threejs 案例要搭建一个本地的静态服务器,否则的话,threejs 案例无法正常打开,浏览器控制台会提示跨域问题。

如果你知道怎么搭建本地静态服务器,自己用任何方式搭建都可以。如果不了解的话,建议使用 nodejs 去快速搭建一个本地静态服务器,对于一个 WebGL 工程师或前端工程师来说,肯定是要学习 Nodejs 的。

Nodejs 本地静态服务器 使用 Nodejs 搭建本地静态服务器很简单,首先是你要先百度 Nodejs 安装的相关文章,先在你的电脑上安装配置好 Nodejs,熟悉下 NPM 的使用,然后使用 npm 执行 npm install -g live-server 安装 live-server 模块,如果你想通过安装好的 live-server 模块开启一个静态服务器,打开命令行,进入 threejs 案例所在的文件目录,然后执行 live-server 命令就可以。

通过浏览器访问 http://localhost:8080http://127.0.0.1:8080 地址,找到 threejs 案例的.html 文件直接打开就可以看到三维场景渲染效果。

开发调试-热更新 在学习 threejs 的过程中,往往需要频繁的代码测试,查看 threejs 代码的渲染效果。这时候你肯定希望代码修改之后,threejs 渲染效果立即热更新。

如果通过 live-server 模块搭建的本地静态服务器,你可以实现代码的热加载。也就是说你修改一段代码,然后保存.html 代码文件,.html 对应的 threejs 案例就会重新渲染。

兼容性问题

参考文档: http://www.webgl3d.cn/threejs/docs/#manual/zh/introduction/WebGL-compatibility-check

views/demo02/index.vue 中有使用

项目控制台报错

Unchecked runtime.lastError: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

网上说是浏览器插件问题

1.项目介绍

1.1 运行第一个 threejs

代码位置:demo01/index01.vue

image

1.2 添加浏览器兼容性判断

代码位置:demo01/index02.vue

1.3 鼠标操作三维场景(引入轨道控制器)

代码位置:demo01/index03.vue

1.4 场景新增多个几何体、新增辅助坐标轴

代码位置:demo01/index04.vue

1.5 设置材质效果

代码位置:demo01/index05.vue

1.6 光源

代码位置:demo01/index06.vue

2.1 顶点数据结构解析

代码位置:demo02/index01.vue

2.2 顶点颜色插值计算

代码位置:demo02/index02.vue

2.3 顶点法向量数据光照计算

代码位置:demo02/index03.vue

2.4 顶点索引复用顶点数据

代码位置:demo02/index04.vue

2.5 顶点索引复用顶点数据

代码位置:demo02/index05.vue

2.6 访问几何体对象的数据

代码位置:demo02/index06.vue

2.7 几何体旋转、缩放、平移变换

代码位置:demo02/index07.vue

3.1 常用材质介绍、及对应模型关系

代码位置:demo03/index01.vue

3.2 材质共有属性、私有属性

代码位置:demo03/index02.vue

4.1 点、线、网格模型介绍(及渲染模式)

代码位置:demo04/index01.vue

4.2 模型对象旋转平移缩放变换

代码位置:demo04/index02.vue

4.3 对象克隆 clone 和复制 copy

代码位置:demo04/index03.vue

5.1 常见光源类型、光源辅助、光源颜色计算

代码位置:demo05/index01.vue

5.2 光照阴影实时计算(平行光源投影)

代码位置:demo05/index02.vue 需要新建两个模型: 一个 模型是物体, 另一个模型是地面 用来接收投影

// 这个版本需要开启 以下代码
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  • 模型.castShadow 属性

    • .castShadow 属性值是布尔值,默认 false,用来设置一个模型对象是否在光照下产生投影效果。具体查看 threejs 文档 Object3D
    • // 设置产生投影的网格模型
      mesh.castShadow = true;
      
  • 模型.receiveShadow 属性

    • .receiveShadow 属性值是布尔值,默认 false,用来设置一个模型对象是否在光照下接受其它模型的投影效果。具体查看 threejs 文档 Object3D
    • // 设置网格模型planeMesh接收其它模型的阴影(planeMesh作为投影面使用)
      planeMesh.receiveShadow = true;
      
  • 光源.castShadow 属性

    • 如果属性设置为 true, 光源将投射动态阴影. 警告: 这需要很多计算资源,需要调整以使阴影看起来正确. 更多细节,查看 DirectionalLightShadow. 默认值 false.
    • // 设置用于计算阴影的光源对象
      directionalLight.castShadow = true;
      // spotLight.castShadow = true;
      
  • 光源.shadow 属性

    • 平行光 DirectionalLight 的.shadow 属性值是平行光阴影对象 DirectionalLightShadow,聚光源 SpotLight 的.shadow 属性值是聚光源阴影对象 SpotLightShadow。关于 DirectionalLightShadow 和 SpotLightShadow 两个类的具体介绍可以参考 Three.js 文档 Lights / Shadows 分类,
  • 阴影对象基类 LightShadow

    • 平行光阴影对象 DirectionalLightShadow 和聚光源阴影对象 SpotLightShadow 两个类的基类是 LightShadow

    • LightShadow 属性.camera

      • 观察光源的相机对象. 从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中。
      • // 聚光源设置
        spotLight.shadow.camera.near = 1;
        spotLight.shadow.camera.far = 300;
        spotLight.shadow.camera.fov = 20;
        
    • LightShadow 属性.mapSize

      • 定义阴影纹理贴图宽高尺寸的一个二维向量 Vector2.
      • 较高的值会以计算时间为代价提供更好的阴影质量. 宽高分量值必须是 2 的 幂, 直到给定设备的 WebGLRenderer.capabilities.maxTextureSize, 尽管宽度和高度不必相同 (例如,(512, 1024)是有效的). 默认值为 ( 512, 512 ).
      • directionalLight.shadow.mapSize.set(1024, 1024);
        
    • LightShadow 属性.map

      • 该属性的值是 WebGL 渲染目标对象 WebGLRenderTarget,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中。 在渲染期间内部计算。

5.3 光照阴影实时计算(聚光光源投影)

代码位置:demo05/index03.vue 需要新建两个模型: 一个 模型是物体, 另一个模型是地面 用来接收投影

// 这个版本需要开启 以下代码
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  • 模型.castShadow 属性

    • .castShadow 属性值是布尔值,默认 false,用来设置一个模型对象是否在光照下产生投影效果。具体查看 threejs 文档 Object3D
    • // 设置产生投影的网格模型
      mesh.castShadow = true;
      
  • 模型.receiveShadow 属性

    • .receiveShadow 属性值是布尔值,默认 false,用来设置一个模型对象是否在光照下接受其它模型的投影效果。具体查看 threejs 文档 Object3D
    • // 设置网格模型planeMesh接收其它模型的阴影(planeMesh作为投影面使用)
      planeMesh.receiveShadow = true;
      
  • 光源.castShadow 属性

    • 如果属性设置为 true, 光源将投射动态阴影. 警告: 这需要很多计算资源,需要调整以使阴影看起来正确. 更多细节,查看 DirectionalLightShadow. 默认值 false.
    • // 设置用于计算阴影的光源对象
      directionalLight.castShadow = true;
      // spotLight.castShadow = true;
      
  • 光源.shadow 属性

    • 平行光 DirectionalLight 的.shadow 属性值是平行光阴影对象 DirectionalLightShadow,聚光源 SpotLight 的.shadow 属性值是聚光源阴影对象 SpotLightShadow。关于 DirectionalLightShadow 和 SpotLightShadow 两个类的具体介绍可以参考 Three.js 文档 Lights / Shadows 分类,
  • 阴影对象基类 LightShadow

    • 平行光阴影对象 DirectionalLightShadow 和聚光源阴影对象 SpotLightShadow 两个类的基类是 LightShadow

    • LightShadow 属性.camera

      • 观察光源的相机对象. 从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中。
      • // 聚光源设置
        spotLight.shadow.camera.near = 1;
        spotLight.shadow.camera.far = 300;
        spotLight.shadow.camera.fov = 20;
        
    • LightShadow 属性.mapSize

      • 定义阴影纹理贴图宽高尺寸的一个二维向量 Vector2.
      • 较高的值会以计算时间为代价提供更好的阴影质量. 宽高分量值必须是 2 的 幂, 直到给定设备的 WebGLRenderer.capabilities.maxTextureSize, 尽管宽度和高度不必相同 (例如,(512, 1024)是有效的). 默认值为 ( 512, 512 ).
      • directionalLight.shadow.mapSize.set(1024, 1024);
        
    • LightShadow 属性.map

      • 该属性的值是 WebGL 渲染目标对象 WebGLRenderTarget,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中。 在渲染期间内部计算。

5.4 基类 Light 和 Object3d

image

// 光源对象继承父类Object3D的位置属性.position。

/**
 * 光源颜色属性.color和强度属性.intensity
 * 你查看光源光源Light文档,可以看到该类定义了光源颜色属性.color和强度系数属性intensity。
 *
 * 光源颜色属性.color默认值是白色0xffffff,强度属性.intensity默认1.0,光照计算的时候会把两个属性值相乘。
 * 比如环境光颜色设置为0xffffff,强度系数设置为0.5,把0.5设置为0.8,threejs场景中模型会变得更明亮。调节环境颜* 色你可以直接设置不同颜色值,比如0x44444、0xddddddd,也可以使用更为方便的强度系数去调节。对于点光源、聚光源和* 环境光一样继承基类Light强度系数属性.intensity。
 *
 * */

6 Threejs 层级模型、树结构

比如一辆车,在 Threejs 中你可以使用一个网格模型去描述车上面的一个零件,多个零件就需要多个网格模型表示,这些网格模型之间就会构成父子或兄弟关系,从而形成一个层级结构。在机械、建筑相关的 Web3D 应用中,通常会用到层级模型的知识,一个层级模型就是一本书的目录一样。

本章主要目的是帮助你建立 Threejs 层级模型的概念,通过 Threejs 的组对象 Group 可以组织各个模型,构成一个层级结构。学习本节课你也可以参考前端中 DOM 树去理解,Threejs 一个一个的模型对象就像 HTML 元素一样可以组成一个树结构,可以通过特定 id 或 name 属性选择某个或某些模型对象。

在具体开发过程中,3D 美术给你一个包含多个网格模型对象的层级模型,你可能需要操作某个网格模型,这时候 3D 美术只要通过对模型命名标记模型,那么对于程序员来说,直接调用 Threejs 的某个方法就可以遍历整个模型,找到某个你想要操作的模型对象。

image

6.1 组对象 group 和层级模型

  • 层级关系

    • scene:{ group:[ mesh1:{} mesh2:{} ],gourp2:[],light:[] }

    • scene 有 children 字段 , scene.children 字段里有 gourp、light 等对象, group 具有 children 字段 ,group.children 里面存在的 所有的子对象
    • 构成了一个树形结构
    • console.log(group.children); ------- (查看子对象)

    场景对象 Scene、组对象 Group、网格模型对象 Mesh、光源对象 Light 的.add()方法都是继承自它们共同的基类 Object3D。

    • .add()方法可以单独插入一个对象,也可以同时插入多个子对象。
      • group.add(mesh1) ------- (新增父对象 group 的子对象网格模型 mesh1)
      • scene.add(light,group) ---- (一次新增场景中多个对象)
    • .remove()方法
      • group.remove(mesh1) ------- (删除父对象 group 的子对象网格模型 mesh1)
      • scene.remove(light,group) ---- (一次删除场景中多个对象)
  • 6.2 层级模型节点命名-查找-遍历

    • group.name = 'group1' 命名
    • scene.traverse((obj)=>{}) 递归遍历
    • scene.getObjectById(4); 根据 id 查找
    • scene.getObjectByName("group1") 根据定义的 name 查找
    • Threejs 同样可以通过一些方法查找一个模型树中的某个节点。更多的查找方法和方法的使用细节可以查看基类 Object3D
    //* traverse 递归遍历属性结构 查找到 子模型
      this.scene.traverse(function (obj) {
        if (obj.type === "Group") {
          console.log(obj.name);
        }
        if (obj.type === "Mesh") {
          console.log("  " + obj.name);
          obj.material.color.set(0xffff00);
        }
        if ((obj.name === "左眼") | (obj.name === "右眼")) {
          obj.material.color.set(0x000000);
        }

        console.log("打印id属性", obj.id);
        console.log("打印该对象的父对象", obj.parent);
        console.log("打印该对象的子对象", obj.children);
      });

      //
      // 遍历查找scene中复合条件的子对象,并返回id对应的对象
      var idNode = this.scene.getObjectById(4);
      console.log(idNode);
      // 遍历查找对象的子对象,返回name对应的对象(name是可以重名的,返回第一个)
      var nameNode = this.scene.getObjectByName("左腿");
      nameNode.material.color.set(0xff0000);
    }

6.3 本地位置坐标-世界位置坐标

  • .getWorldPosition() 获取模型的世界坐标

    • 模型对象的方法.getWorldPosition()方法和位置属性.position 一样继承自基类 Object3D。
  • 建立世界坐标系概念

    • 蓝色方块 ,通过位置属性.position 和.getWorldPosition()分别返回模型的本地位置坐标和世界坐标,查看两个坐标 x 分量有什么不同。你可以看到网格模型 mesh 通过位置属性.position 返回的坐标 x 分量是 50,通过.getWorldPosition()返回的坐标 x 分量是 100,也就是说 mesh 的世界坐标是 mesh 位置属性.position 和 mesh 父对象 group 位置属性.position 的累加。
    • 总结一下就是 .position 属性是参考的本地坐标系 ,而本地坐标系 的参照物是其父模型, 子模型的世界坐标 就是 子模型与父模型.positon 的累加
    • 类比可知: 本地缩放系数.scale .getWorldScale() 获取世界缩放系数
  • image

7.1 常见几何体和曲线 api 介绍

7.1.1 几何体

关于 Threejs 常见的几何体类下面通过一个脑图进行了简单的分类,并附上了 threejs 文档连接。

几何体本质上就是 threejs 生成顶点的算法,如果有兴趣你可以打开 threejs 几何体部分的源码查看 threejs 具体如何通过程序生成顶点位置、法线方向等顶点数据。

所有几何体的基类分为 Geometry 和 BufferGeometry 两大类,两类几何体直接可以相互转化。

image

7.1.2 曲线

曲线和几何体同样本质上都是用来生成顶点的算法,曲线主要是按照一定的规则生成一系列沿着某条轨迹线分布的顶点。当你把曲线、几何体看成顶点的时候,查考文档很多属性和方法自然很同意理解。

image

8.1 stat 性能测试

8.1.1

代码位置 src/views/test01/indexPage.vue

空文件

简介

Three.js零基础入门教程(郭隆邦):http://www.yanhuangxueyuan.com/Three.js/ 使用vue2 框架 学习threejs , 做一些笔记 本项目的目录 与入门教程一致 方便参考学习 展开 收起
取消

发行版

暂无发行版

贡献者 (1)

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ningwuyu/vue2-threejs.git
git@gitee.com:ningwuyu/vue2-threejs.git
ningwuyu
vue2-threejs
vue2-threejs
master

搜索帮助