这是一篇关于blender+threejs学习的记录
之前在群里看到胖达老师做的NBA项目,炫酷的3D场景和交互特效让人眼花缭乱,虽然平时嘴上挂着说要学习3d开发,学习动效,实际行动起来还是困难重重,我们温柔体贴大帅就找胖达老师做了一期[实训课](https://space.bilibili.com/352979041),通过几个实例带大家入门threejs开发,day1是带大家入门了解blender,做个掉落甜甜圈的例子,day2是在blender编辑器里添加物体,通过挤压,拉伸的方式,给需要做的展厅做立体建模,day3是在day2基础上添加运动的角色,实现控制人物在展厅中自由游览
day2跟day3中关于建模方面内容比较多,新的blender工具实在苦手,就拿day1的案例做个学习记录
关于blender
百度百科中的blender,这里用到的blender是为了方便建立一个3d的模型
官网下载blender
无奈建模水平有限,这里写几个常用的blender视图操作(windows系统)
| 快捷键 | 视图操作 |
|---|---|
| A | 全选 |
| AA | 取消全选 |
| Shift + D | 复制物体 |
| Shift + 鼠标中键 | 移动视角 |
| 鼠标滚轮 | 推拉视角 |
| 鼠标中键按住 | 旋转视角 |
| G grap | 移动 |
| S scale | 缩放 |
| 小键盘 . | 聚焦选中物体 |
| X或Delete | 删除 |
| Shift + A | 添加模型 |
| TAB | 编辑模式/物体模式切换 |
| TAB模式下123 | 切换 点 线 面 几种选择模式 |
| 环选边 | 全选Alt + 点击边(编辑模式——边模式下) |
| Ctrl + B | 切角 |
| M | 合并(焊接)顶点 |
| / | 独立显示选中物体,恢复显示全部 |
代码部分
threejs
基础场景三大件
- scence 场景 new Three.Scene()
- camera 相机 new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10)
- renderer 渲染器 new THREE.WebGLRenderer({ antialias: true })
代码
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
调整相机位置
camera.position.set(0.3, 0.3, 0.5);
ps:抗锯齿antialias: true,默认为false
环境光
环境光,让所有地方都亮起来
const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);
几何体
- BoxGeometry 立方体
- SphereGeometry 球体
- CylinderGeometry 圆柱体
创建几何体三部曲
const boxGeometry = new THREE.BoxGeometry(1,1,1);
const boxMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00});
const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
scene.add(boxMesh);
帧循环
让场景动起来
function animate(){
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
threejs中不会做代码类型检查,当无法实现预期效果时,需要对代码进行一步步走查
让物体能够操作,官方控制方法
轨道控制相机
const controls = new OrbitControls(camera, renderer.domElement); //轨道控制器
...
function animate(){
...
controls.update();
}
加载模型(添加甜甜圈)
加载glft/glb模型
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {
scene.add(gltf.scene);
})
打印看看gltf里面都有什么
单个的甜甜圈
存储有用信息的userData
获取所有模型个体
gltf.scene.traverse((child)=>{
console.log(child.name);
})
添加投影
gltf.scene.traverse((child)=>{
//阴影投影
child.receiveShadow = true; // 产生阴影
child.castShadow = true;// 接受阴影
})
Animation 动画
AnimationMixer 动画混合器 添加动画,让甜甜圈掉落,并且停留在最后一帧
const mixer = new THREE.AnimationMixer(gltf.scene);
const clips = gltf.animations; // 播放所有动画
clips.forEach(function (clip) {
const action = mixer.clipAction(clip);
action.loop = THREE.LoopOnce;
// 停在最后一帧
action.clampWhenFinished = true;
action.play();
});
动画的轨迹
添加背景,使整个场景亮起来
scene.background = new THREE.Color(0.6, 0.6, 0.6);
new RGBELoader()
.load('../resources/sky.hdr', function (texture) {
scene.background = texture;
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = texture;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.render(scene, camera);
});
修改animate函数
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
controls.update();
if (mixer) {
mixer.update(0.02);
}
}
完成效果
掉落甜甜圈效果
添加背景旋转
添加代码 donuts.rotation.y += 0.01;
完成效果
文章小结
作为threejs开发小白,掉落甜甜圈这个案例作为入门的案例真是再合适不过了,平时最大的学习阻力大概就是代码写出来了,运行不起来,或者中间遇到各种各样困难,自己代码陷入奇怪的地方,无法继续下去,幸运的是,这几天的学习,胖达老师全程在线解答,更棒的是,群里的小伙伴也会积极帮忙解答,要感谢群里一帮志同道合的小伙伴,大家都是奔着学习3D开发来的,虽然之后展厅的案例比较复杂,没有完成文章的记录,相信后面随着学习的深入还是能够独立完成这种复杂的场景项目开发,在这里想宣传下大帅老师的猿创营 ,也欢迎想要了解学习3D开发,动效开发的小伙伴们加入猿创营 (v:dashuailaoyuan),一起交流学习