前言

前几天加入了原宇宙我的项目的学习,奈何是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),一起交流学习