【Three.js】3D模型项目实践

简介: 【Three.js】3D模型项目实践

1.基本设置

1.初始化场景,相机

import * as THREE from "three";
// 初始化场景
const scene = new THREE.Scene();

// 初始化相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  2000
);

// // 设置相机位置
camera.position.set(-50, 50, 130);
scene.add(camera);

2.初始化渲染器

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器添加到页面
document.body.appendChild(renderer.domElement);

// 实例化控制器
const controls = new OrbitControls(camera, renderer.domElement);

3.添加轨道控制器并循环渲染图画

// 导入控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 实例化控制器
const controls = new OrbitControls(camera, renderer.domElement);

function render() {
  // 渲染场景
  renderer.render(scene, camera);
  // 引擎自动更新渲染器
  requestAnimationFrame(render);
}
render();

4.监听窗口并实现画布自适应

// 监听屏幕的大小改变,修改渲染器的宽高,相机的比例
window.addEventListener("resize", () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  // 修改属性后需要刷新来使改变生效
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

2.要点步骤

1.为场景添加平行光

平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果;
太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

构造函数:

DirectionalLight( color : Integer, intensity : Float )

color - (可选参数) 16进制表示光的颜色。 缺省值为 0xffffff (白色)。
intensity - (可选参数) 光照的强度。缺省值为1。

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(-100, 100, 10);
scene.add(light);

2.为背景添加天空球体

TextureLoader

加载texture的一个类。 内部使用ImageLoader来加载文件。

.load ( url : String, onLoad : Function, onProgress : Function, onError :
Function ) : Texture

url — 文件的URL或者路径,也可以为 Data URI.
onLoad — 加载完成时将调用。回调参数为将要加载的texture.
onProgress — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含total和loaded字节。
onError — 在加载错误时被调用。

注意: 此处的url的默认目录当前目录是项目打包生成的dist文件夹,所有资源文件均需放置到此文件夹下方可访问

.map : Texture

颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。

.scale ( x : Float, y : Float, z : Float ) : this

缩放几何体。该操作一般在一次处理中完成,不会循环处理。典型的用法是通过调用 Object3D.scale 实时旋转几何体。

// 创建一个巨大的天空球体
let texture = new THREE.TextureLoader().load("./textures/water/sky.jpg");
const skyGeometry = new THREE.SphereGeometry(1000, 60, 60);
const skyMaterial = new THREE.MeshBasicMaterial({
  map: texture,
});
skyGeometry.scale(1, 1, -1);
const sky = new THREE.Mesh(skyGeometry, skyMaterial);

scene.add(sky);

3.添加视频纹理

VideoTexture

创建一个使用视频来作为贴图的纹理对象。
它和其基类Texture几乎是相同的,除了它总是将needsUpdate设置为 true
,以便使得贴图能够在视频播放时进行更新。自动创建mipmaps也会被禁用。

// 视频纹理
const video = document.createElement("video");
video.src = "./textures/sky.mp4";
video.loop = true;

window.addEventListener("click", (e) => {
  // 当鼠标移动的时候播放视频
  //   判断视频是否处于播放状态
  if (video.paused) {
    video.play();
    let texture = new THREE.VideoTexture(video);
    skyMaterial.map = texture;
    skyMaterial.map.needsUpdate = true;
  }
});

4.创建水面

CircleGeometry是欧式几何的一个简单形状,它由围绕着一个中心点的三角分段的数量所构造,由给定的半径来延展。
同时它也可以用于创建规则多边形,其分段数量取决于该规则多边形的边数。

CircleGeometry(radius : Float, segments : Integer, thetaStart : Float,
thetaLength : Float)

radius — 圆形的半径,默认值为1
segments — 分段(三角面)的数量,最小值为3,默认值为8。
thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
thetaLength — 圆形扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆。

// 导入水面
import { Water } from "three/examples/jsm/objects/Water2";

// 创建水面
const waterGeometry = new THREE.CircleBufferGeometry(300, 64);
const water = new Water(waterGeometry);
water.position.y = -80;
// 水面旋转至水平
water.rotation.x = -Math.PI / 2;
scene.add(water);

5.导入实例模型

draco

draco是谷歌出的一款模型压缩工具,可将gltf格式的模型进行进一步压缩提高页面加载速的一种方法

github官网:https://github.com/google/draco

下载后将javascript文件夹复制到本项目dist目录下

sketchfab(3d模型网站)

Explore 3D Models -
Sketchfab

同样下载的模型也需要放置到dist目录下,我的模型在model文件夹下

// 导入gltf载入库
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";

// 添加小狗模型
// 实例化gltf载入库
const loader = new GLTFLoader();
// 实例化draco载入库
const dracoLoader = new DRACOLoader();
// 添加draco载入库
dracoLoader.setDecoderPath("./javascript/");
// 添加draco载入库
loader.setDRACOLoader(dracoLoader);

loader.load("./model/shiba.glb", (gltf) => {
  gltf.scene.scale.set(100,100,100)
  scene.add(gltf.scene);
});

package.json

{
  "name": "ch02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "parcel": "^2.4.1"
  },
  "dependencies": {
    "dat.gui": "^0.7.9",
    "gsap": "^3.10.3",
    "three": "^0.139.2"
  }
} 


参考视频:手把手教你用three.js开发水天一色小岛_哔哩哔哩_bilibili

目录
相关文章
|
3月前
|
存储 JavaScript 前端开发
使用JavaScript构建动态交互式网页:从基础到实践
【10月更文挑战第12天】使用JavaScript构建动态交互式网页:从基础到实践
216 1
|
1天前
|
缓存 NoSQL JavaScript
Vue.js应用结合Redis数据库:实践与优化
将Vue.js应用与Redis结合,可以实现高效的数据管理和快速响应的用户体验。通过合理的实践步骤和优化策略,可以充分发挥两者的优势,提高应用的性能和可靠性。希望本文能为您在实际开发中提供有价值的参考。
21 11
|
1月前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
1月前
|
Web App开发 移动开发 HTML5
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码。画面中心是悬浮于空的梅花鹿,其四周由白色线段组成了一个6边形将中心的梅花鹿包裹其中。四周漂浮的白雪随着多边形的转动而同步旋转。建议使用支持HTML5与css3效果较好的火狐(Firefox)或谷歌(Chrome)等浏览器预览本源码。
91 2
|
2月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
2月前
|
JavaScript 前端开发 API
Vue.js 3:深入探索组合式API的实践与应用
Vue.js 3:深入探索组合式API的实践与应用
|
2月前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
82 4
|
2月前
|
CDN
如何在项目中使用Moment.js库?
如何在项目中使用Moment.js库?
|
2月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
3月前
|
JavaScript 测试技术 API
跟随通义灵码一步步升级vue2(js)项目到vue3版本
Vue 3 相较于 Vue 2 在性能、特性和开发体验上都有显著提升。本文介绍了如何利用通义灵码逐步将 Vue 2 项目升级到 Vue 3,包括备份项目、了解新特性、选择升级方式、升级依赖、迁移组件和全局 API、调整测试代码等步骤,并提供了注意事项和常见问题的解决方案。
138 4