Threejs系列--7游戏开发加载glb模型之牛刀小试
Posted 小猴子喝牛奶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Threejs系列--7游戏开发加载glb模型之牛刀小试相关的知识,希望对你有一定的参考价值。
Threejs系列--7游戏开发加载glb模型之牛刀小试
终极效果展示
目标如下,先来熟悉下threejs吧~~
开发环境搭建
- emmmmmm ~~~ 一台非常攒劲的电脑
- 编辑器vscode
- js运行环境nodejs
- 浏览器chrome
目录结构
|-- src 源代码
|-- assets 资源目录
|-- model
|-- 630cfe7e8388bff5bfda6692ce4ca40b.glb 一看就是网上随便巴拉的文件^^
|-- js 核心目录
|-- events.ts 事件
|-- helper.ts 辅助工具
|-- role.ts 角色
|-- main.ts 游戏主场景
|-- index.ts 入口文件
|-- index.html 模板文件
|-- webpack.config.js webpack配置
重要依赖
//通过npm直接下载
"dependencies": {
"three": "^0.134.0"
},
"devDependencies": {
"@types/three": "^0.133.1",
"copy-webpack-plugin": "^9.0.1",
"html-webpack-plugin": "^5.5.0",
"ts-loader": "^9.2.6",
"typescript": "^4.4.4",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0"
}
代码
html模板内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {margin: 0; padding: 0;}
html,body,#webgl {height: 100%;}
body {overflow: hidden;}
</style>
</head>
<body>
<canvas id="webgl"></canvas>
</body>
</html>
main.ts游戏主场景
import * as THREE from 'three';
import LightHelper from './helper';
export default class Main {
public mesh: THREE.Mesh;
public scene: THREE.Scene;
public camera: THREE.PerspectiveCamera;
public renderer: THREE.WebGLRenderer;
private geometry: THREE.PlaneGeometry;
private material: THREE.Material;
public width: number = window.innerWidth;
public height: number = window.innerHeight;
constructor() {
this.initScent();
this.createGeometry();
this.setCamera();
this.setLight();
this.setRenderer();
}
createGeometry() {
this.geometry = new THREE.PlaneGeometry(600, 600);
this.material = new THREE.MeshLambertMaterial({
color: 0xeaeaea,
side: THREE.DoubleSide
});
//网格模型
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.rotation.x = -Math.PI / 2;
this.mesh.position.x = Math.PI/2
this.mesh.receiveShadow = true;
this.scene.add(this.mesh);
}
initScent() {
//创建场景
this.scene = new THREE.Scene();
}
setCamera() {
const k: number = this.width / this.height;
const s: number = 75;
//创建相机对象
this.camera = new THREE.PerspectiveCamera(s, this.width / this.height, 0.1, 10000);
this.camera.position.set(0, 300, 400);
this.camera.lookAt(this.scene.position);
}
setLight() {
const offset = 160
const Helper:LightHelper = new LightHelper(this.scene);
//头顶四方四盏灯 增加无尽神秘感
Array(4).fill(0).forEach((item: any, index: number) => {
//灯光与位置
let spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.x = index>1 ? (index%2?offset:~offset) : 0;
spotLight.position.z = index<2 ? (index%2?offset:~offset) : 0;
spotLight.position.y = 400
//阴影与大小
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1200;
spotLight.shadow.mapSize.height = 1200;
//载入场景
this.scene.add( spotLight );
Helper.spointLightHelper(spotLight);
})
}
setRenderer() {
//渲染器
this.renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('webgl'),
antialias: true,
alpha: true
});
this.renderer.setSize(this.width, this.height);//设置渲染区域尺寸
this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
this.renderer.shadowMap.enabled = true;
}
render() {
this.renderer.render(this.scene,this.camera);//执行渲染操作
}
}
role.ts角色构建
import * as THREE from 'three';
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader';
import Main from './main'
export default class Role {
main: Main;
mixer: THREE.AnimationMixer = null;
constructor(main: Main) {
this.main = main;
this.loader();
}
loader() {
// const loader = new FBXLoader();//创建一个FBX加载器
const loader = new GLTFLoader();//创建一个GLTF加载器
var dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'draco/' );
loader.setDRACOLoader( dracoLoader );
loader.load('model/630cfe7e8388bff5bfda6692ce4ca40b.glb', (obj) => {
obj.scene.traverse( child => {
if (child.type == 'Mesh') {
child.castShadow = true
child.receiveShadow = true
}
})
obj.scene.receiveShadow = true
obj.scene.rotation.x = - Math.PI / 2
this.main.scene.add(obj.scene)
//this.mixer = new THREE.AnimationMixer(obj);
//AnimationAction.play();//播放动画
})
}
}
helper.ts辅助线
import * as THREE from 'three';
export default class LightHelper {
private scene: THREE.Scene;
constructor(scene: THREE.Scene) {
this.scene = scene;
}
/**
* 聚光灯辅助线
*/
spointLightHelper(spotLight: THREE.SpotLight) {
var sphereSize = 1;
var spointLightHelper = new THREE.PointLightHelper( spotLight, sphereSize );
this.scene.add( spointLightHelper );
}
}
events.ts事件
import Main from './main'
export default class Events {
main: Main;
constructor(main: Main) {
this.main = main;
window.addEventListener('resize', this.resize.bind(this));
window.addEventListener('dblclick', this.fullScreen.bind(this));
}
resize() {
this.main.camera.aspect = window.innerWidth / window.innerHeight;
this.main.camera.updateProjectionMatrix();
this.main.renderer.setSize(window.innerWidth, window.innerHeight);
}
fullScreen() {
if(document.fullscreen) {
document.exitFullscreen();
}else{
document.documentElement.requestFullscreen();
}
}
}
代码运行
项目根目录下执行 webpack
作者的话
emmm~~ 准备工作已经完成,顺便熟悉了程序,下节将开始正式的游戏开发。
以上是关于Threejs系列--7游戏开发加载glb模型之牛刀小试的主要内容,如果未能解决你的问题,请参考以下文章
vite+vue3+threejs实现一个3D模型的展示案例