GLTF 模型加载器
一个加载器,用于将 glTF 模型加载到 Threejs 场景中。 glTF 是用于高效传输和加载 3D 场景和模型的规范。 glTF 最大限度地减少了 3D 资产的大小,以及解压缩和使用这些资产所需的运行时处理。
推荐:使用NSDT场景编辑器快速搭建3D应用场景
一个glTF文件可以包含一个或多个场景,网格,材料,纹理,皮肤,骨架,变形目标,动画,灯光和相机。
资产可以以 JSON (.gltf) 或二进制 (.glb) 格式提供。
资源
本课程中使用的3D模型可以使用Blender轻松创建。如果您不想使用Blender来创建模型,则可以从名为的zip文件下载它们。将内容解压缩到文件夹中。models3.zipmodels3.zip./dist/client/models/
启动脚本
./src/client/client.ts
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import Stats from 'three/examples/jsm/libs/stats.module'
const scene = new THREE.Scene()
scene.add(new THREE.AxesHelper(5))
const light = new THREE.SpotLight()
light.position.set(5, 5, 5)
scene.add(light)
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
camera.position.z = 2
const renderer = new THREE.WebGLRenderer()
// Since Three r150, and Blender 3.6, lighting has changed significantly.
//
// renderer.physicallyCorrectLights = true // is now deprecated since Three r150. Use renderer.useLegacyLights = false instead.
//
// If exporting lights from Blender, they are very bright.
// lights exported from blender are 10000 times brighter when used in Threejs
// so, you can counter this by setting renderer.useLegacyLights = false
// renderer.useLegacyLights = false // WebGLRenderer.physicallyCorrectLights = true is now WebGLRenderer.useLegacyLights = false
// however, they are now still 100 times brighter in Threejs than in Blender,
// so to try and match the threejs scene shown in video, reduce Spotlight watts in Blender to 10w.
// The scene in blender will be lit very dull.
// Blender and Threejs use different renderers, they will never match. Just try your best.
//
renderer.shadowMap.enabled = true
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const loader = new GLTFLoader()
loader.load(
'models/monkey.glb',
function (gltf) {
// gltf.scene.traverse(function (child) {
// if ((child as THREE.Mesh).isMesh) {
// const m = (child as THREE.Mesh)
// m.receiveShadow = true
// m.castShadow = true
// }
// if (((child as THREE.Light)).isLight) {
// const l = (child as THREE.SpotLight)
// l.castShadow = true
// l.shadow.bias = -.003
// l.shadow.mapSize.width = 2048
// l.shadow.mapSize.height = 2048
// }
// })
scene.add(gltf.scene)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
},
(error) => {
console.log(error)
}
)
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
render()
}
const stats = new Stats()
document.body.appendChild(stats.dom)
function animate() {
requestAnimationFrame(animate)
controls.update()
render()
stats.update()
}
function render() {
renderer.render(scene, camera)
}
animate()
最终脚本
./src/client/client.ts
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import Stats from 'three/examples/jsm/libs/stats.module'
const scene = new THREE.Scene()
scene.add(new THREE.AxesHelper(5))
// const light = new THREE.SpotLight();
// light.position.set(5, 5, 5)
// scene.add(light);
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
camera.position.z = 2
const renderer = new THREE.WebGLRenderer()
// Since Three r150, and Blender 3.6, lighting has changed significantly.
//
// renderer.physicallyCorrectLights = true // is now deprecated since Three r150. Use renderer.useLegacyLights = false instead.
//
// If exporting lights from Blender, they are very bright.
// lights exported from blender are 10000 times brighter when used in Threejs
// so, you can counter this by setting renderer.useLegacyLights = false
renderer.useLegacyLights = false // WebGLRenderer.physicallyCorrectLights = true is now WebGLRenderer.useLegacyLights = false
// however, they are now still 100 times brighter in Threejs than in Blender,
// so to try and match the threejs scene shown in video, reduce Spotlight watts in Blender to 10w.
// The scene in blender will be lit very dull.
// Blender and Threejs use different renderers, they will never match. Just try your best.
//
renderer.shadowMap.enabled = true
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const loader = new GLTFLoader()
loader.load(
'models/monkey.glb',
function (gltf) {
gltf.scene.traverse(function (child) {
if ((child as THREE.Mesh).isMesh) {
const m = child as THREE.Mesh
m.receiveShadow = true
m.castShadow = true
}
if ((child as THREE.Light).isLight) {
const l = child as THREE.SpotLight
l.castShadow = true
l.shadow.bias = -0.003
l.shadow.mapSize.width = 2048
l.shadow.mapSize.height = 2048
}
})
scene.add(gltf.scene)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
},
(error) => {
console.log(error)
}
)
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
render()
}
const stats = new Stats()
document.body.appendChild(stats.dom)
function animate() {
requestAnimationFrame(animate)
controls.update()
render()
stats.update()
}
function render() {
renderer.render(scene, camera)
}
animate()
由3D建模学习工作室 整理翻译,转载请注明出处!