前言
📃前几天加入了原宇宙我的项目的学习,奈何是 blender 老手,工作工夫不能学习,只能忙里偷闲,先先做一个记录,我的项目用到的和没用到的文件都在 src 目录下的 resources
文件夹外面。想着做不同的,那么就用框架不一样吧,利用 vite 搭建的 react 我的项目,下载 threeJs 安装包书写。
筹备工作
1,工具
应用的是 blender
- 因为 blender 对于 mac 和 windows 都是能够应用的,3dMax 只实用于 windows 零碎(不过因为我之前学过 3dMax 的,所以,尽管我是 mac,然而也装置了一个 windows 的虚拟机,3dMax 跑起来还是能够应用的。)
2,网址
- blender 下载地址:https://www.blender.org/thanks/
- 下载贴图或者材质的:https://www.textures.com/library
- 一些根本模型:https://sketchfab.com/ (在 sketchfab 上能够拿模型,实现模型的小局部自在)(qq 邮箱,google 邮箱能够,163 邮箱注册如同不行)
-
用于模型绑定骨骼:https://www.mixamo.com/(无动画的角色,演示的时候用的 glb 不反对,没提醒。用 fbx 格局的能够)
3,blender 中的一些快捷键
在 blender 中应用的的右手坐标系
性能 | 快捷键 | ||||||
---|---|---|---|---|---|---|---|
全选: | A | 勾销全选: | AA | 复制物体: | Shift+D | ||
挪动: | G | 缩放: | S | 挪动视角: | 鼠标滚轮键 | ||
旋转: | R | 搜寻: | F3 | 删除: | X | ||
填充面: | F | 合并顶点: | M | 编辑模式: | Tab | ||
前视图: | 1 | 右视图: | 3 | 顶视图: | 7 | ||
切换视图: | Alt+ 鼠标中键 | 透视显示模式: | Alt+Z | 拆散: | P | ||
属性栏: | N | 左侧工具栏: | T | 环选: | Alt+A | ||
反选: | Ctrl+I | 暗藏物体: | H | 勾销暗藏: | Alt+H | ||
查看全副: | Shift+C | 父子链接: | Ctrl+P | 相机视图: | 0 | ||
着色模式: | Z | 弹出上次的渲染窗口: | F11 | 创立汇合: | M | ||
设置游标: | Shift+S | 最大化以后窗口: | Ctrl+ 空格 | 物体交互模式设置: | Ctrl+Tab | ||
进入 / 退出三视图: | Ctrl+Alt+Q | 挤出: | F9 | 游标回到原点: | Shift+C | ||
开启 / 敞开吸附性能: | Shift+Tab | 抉择相连元素: | L | 一般复制: | Shift+D | ||
去除父子关系: | Alt+P | 创立父子关系: | Ctrl+P | 挪动物体: | M | ||
连贯节点: | F | 断开节点: | Ctrl+ 鼠标左键 | 增加转换点: | Shift+ 鼠标左键 | ||
暂停 / 播放: | Alt+A | 上一帧 / 下一帧: | 左右箭头 | 删除关键帧: | Alt+I | ||
切换点线面: | Ctrl+Tab | 撕开后填充: | Alt+V | 倒角工具: | Ctrl+B | ||
切割工具: | K | 挤出工具: | E | 细分物体: | 按住 S + 鼠标中键 | ||
渲染: | F12 | 保留用户设置: | Ctrl+U |
有些快捷键我没有试过,能够本人入手尝试做一下
4,代码实现时可能遇到的几个坑
- 动画为什么不动,
须要在动画中设置帧的播放程序
- 为什么依照操作,整个画面是黑的,
因为相机在外部,须要将相机的地位进行设置
-
为什么底部的材质是黑的,
能够用一个环境光,将四周的亮度调亮
5,代码
1,应用 vite 搭建我的项目
这里抉择的是 react 版本
npm create vite@latest
2, 下载 three.js 安装包
下载后查看文档对应下载的版本进行查看,因为不同的版本相应的文件可能存在的文件夹不一样,这里我用的是 0.145.0
npm install three@0.145.0
3, 具体代码
-
1,引入相干文件
import {useState, useEffect, useRef} from 'react' import * as THREE from 'three'; // 引入 three.js 其余扩大库,对应版本查看文档,最新扩大库在 addons 文件夹下,eg:'three/addons/controls/OrbitControls.js'; // OrbitControls 控件反对鼠标左中右键操作和键盘方向键操作 import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"; import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader"; import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader';
-
2, 设置盒子宽高
function App() {const [width, setWidth] = useState(window.innerWidth) const [height, setHeight] = useState(window.innerHeight) return (<div id="container" style={{ width: width, height: height}}></div> ) } export default App
-
3,若窗口扭转,则对窗口进行重置
const resizeUpdate = (e) => { // 通过事件对象获取浏览器窗口的高度 let h = e.target.innerHeight; let w = e.target.innerWidth; // 对利用大小进行重置 renderer.setSize(w, h); setHeight(h); setWidth(w) }; // 重置窗口大小 useEffect(() => { // 页面刚加载实现后获取浏览器窗口的大小 let h = window.innerHeight; setHeight(h) let w = window.innerWidth; setWidth(w) // 页面变动时获取浏览器窗口的大小 window.addEventListener('resize', resizeUpdate); return () => { // 组件销毁时移除监听事件 window.removeEventListener('resize', resizeUpdate); } }, [])
-
4, 对相应的变量进行命名
let scene, camera, renderer, controls // 场景,相机,渲染器,控制器 let donuts; // 前面甜甜圈旋转时的变量 let mixer; // 甜甜圈播放动画是的变量
-
5,初始化 / 销毁 利用
useEffect(() => { // 创立场景 scene = new THREE.Scene(); // // 创立相机 camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10); renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(width, height); // 设置渲染器尺寸 document.getElementById('container').appendChild(renderer.domElement); camera.position.set(0.3, 0.3, 0.5); // 设置相机地位 controls = new OrbitControls(camera, renderer.domElement); const directionLight = new THREE.DirectionalLight(0xffffff, 0.4); // 增加平行光 scene.add(directionLight); gltfLoader() // 场景增加 glb 文件 rgbeLoader() // 增加背景天空 animate() // 动画循环 // 组件销毁时移除 app 利用 return () => {document.getElementById('container').removeChild(renderer.domElement); } }, [])
-
6,三个分离出来的办法
// 场景增加 glb 文件 const gltfLoader = () => {new GLTFLoader().load('../src/resources/models/donuts.glb', (gltf) => {scene.add(gltf.scene); donuts = gltf.scene; mixer = new THREE.AnimationMixer(gltf.scene); const clips = gltf.animations; // 播放所有动画 clips.forEach((clip) => {const action = mixer.clipAction(clip); action.loop = THREE.LoopOnce; // 停在最初一帧 action.clampWhenFinished = true; action.play();}); }) } // 增加背景天空 const rgbeLoader = () => {new RGBELoader() .load('../src/resources/sky2.hdr', function (texture) { scene.background = texture; texture.mapping = THREE.EquirectangularReflectionMapping; scene.environment = texture; renderer.outputEncoding = THREE.sRGBEncoding; renderer.render(scene, camera); }); } // 动画循环 const animate = () => {requestAnimationFrame(animate); renderer.render(scene, camera); controls.update(); if (donuts) {donuts.rotation.y += 0.01;} if (mixer) {mixer.update(0.02); } }
6,代码地址
代码在以后 github 地址,点击可进入查看
7,总结
不论做什么还是要保持,保持才会迎来胜利。
如果你有趣味的话,也能够退出猿创营 (v:dashuailaoyuan),一起交流学习