nodejs渲染glb模型
更新时间: 2024-12-05 15:35:35
上一篇用threejs加载了简单的几何体构成的场景,今天我们加载3d模型,这次加载glb格式
来先看效果:
# 库文件改造
# 安装并改造xmlhttprequest
首先npm i xmlhttprequest
因为nodejs不支持XMLHttpRequest,但threejs.module.js会用到XMLHttpRequest,所以先安装然后将 /node_modules/xmlhttprequest/lib/XMLHttpRequest.js 复制一份出来放到项目的lib文件夹下
修改XMLHttpRequest.js 304行开始的代码:
// ....
// 下面一行是309行
// 先是去掉readFile中间的参数“utf8”,此处转utf8会出问题
fs.readFile(url.pathname, function(error, data) {
if (error) {
self.handleError(error);
} else {
self.status = 200;
if(self.responseType == 'arraybuffer') {
// 然后将Buffer转为arrayBuffer并放入response属性中
var buf = Buffer.from(data)
var ab = new ArrayBuffer(buf.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
self.response = ab
}else{
self.response = data;
}
self.responseText = data;
setState(self.DONE);
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 改造three.module.js
复制 /node_modules/three/lib/three.module.js 到 项目的lib文件夹下
在/lib/three.module.js开头加上两行
var xml = require("./XMLHttpRequest.js");
var XMLHttpRequest = xml.XMLHttpRequest
1
2
3
2
3
# 改造GLTFLoader.js 和 DRACOLoader.js
复制 three/examples/jsm/loaders/DRACOLoader.js 和 three/examples/jsm/loaders/GLTFLoader.js,将它们改成CommonJS模块
# 客户端代码
<template>
<div class="main">
<button @click="next">下一帧</button>
<div class="img-wrapper">
<img :src="imageSrc" alt="">
</div>
</div>
</template>
<script setup>
import {ref, onMounted} from "vue"
import {io} from "socket.io-client/dist/socket.io.js"
let socket = null
const imageSrc = ref('')
onMounted(() => {
socket = io("http://192.168.2.122:3000")
socket.on('img',(data) => {
const blob = new Blob([data])
imageSrc.value = URL.createObjectURL(blob)
})
})
function next() {
socket.emit('next')
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 复制draco文件夹
将 /node_modules/three/examples/js/libs/draco 这个文件夹整体复制到 项目的lib文件夹下
现在我们的lib文件夹长这样
# 服务端代码
需要注意,服务端加载模型地址需要加上 file://
const express = require('express')
const {createServer} = require('node:http')
const {Server} = require('socket.io')
const THREE = require('three');
const { GLTFLoader } = require('./lib/GLTFLoader.js')
const { DRACOLoader } = require('./lib/DRACOLoader.js')
const {createCanvas} = require('node-canvas-webgl/lib');
require('events').EventEmitter.defaultMaxListeners = 0
const app = express()
const server = createServer(app)
const io = new Server(server,{
cors: {
origin: "*"
}
})
const width = 1000,
height = 600;
io.on('connection', (socket) => {
const scene = new THREE.Scene();
let horse = null
scene.background = new THREE.Color( 0xf6eedc );
camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
camera.position.set( 500, 500, 0 );
camera.lookAt(0,0,0)
const canvas = createCanvas(width, height);
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true
});
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 2 );
hemiLight.color.setHSL( 0.6, 1, 0.6 );
hemiLight.groundColor.setHSL( 0.095, 1, 0.75 );
hemiLight.position.set( 0, 50, 0 );
scene.add( hemiLight );
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( __dirname + '/lib/draco/gltf/' );
const loader = new GLTFLoader();
loader.setDRACOLoader( dracoLoader );
loader.setPath( "file://"+__dirname + '/models/' );
loader.load( 'Horse.glb', function ( gltf ) {
console.log("gltf",gltf)
horse = gltf.scene
scene.add( horse );
update();
} );
function update() {
horse && (horse.rotation.x += 0.1 )
horse && (horse.rotation.y += 0.1 )
renderer.render(scene, camera);
socket.emit('img', canvas.toBuffer())
}
socket.on('next', () => {
update()
})
})
server.listen(3000, () => {
console.log('server running at http://localhost:3000')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73