共计 1880 个字符,预计需要花费 5 分钟才能阅读完成。
本文将介绍如果应用 Threejs 开发制作一个 3D 展馆,成果如图:
首先,咱们须要一个展馆模型。我是通过 Blender 做进去的,在 Blender 中将模型导出为 glb 格局。
接下来,咱们通过代码将模型加载到网页中。
在 3D 图形开发中,最根本的概念就是场景、相机和光源。这三个是形成 3D 世界的基本要素。所以,咱们须要先创立一个场景、设置相机和光源。
const scene = new THREE.Scene();
// 设置相机
const camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 10, 10000);
camera.position.set(5, 10, -40);// 设置相机地位
camera.lookAt(0,0,0);// 让相机看相原点
// 光源, 平行光
var light2 = new THREE.DirectionalLight(0xffffff, 1);
scene.add(light2);
而后,咱们应用 Threejs 提供的 GLTFLoader 将模型加载进来。
const loader = new GLTFLoader();
loader.load(
'../resources/models/zhanguan2.glb',
function (gltf) {scene.add(gltf.scene);// 将模型增加到场景中
})
这时候咱们会发现,整个场馆有点暗,而且只有场馆外面是亮的,围墙是黑乎乎的。因为咱们用的是平行光,有些中央会照不到,所以就是黑的了。接下来,咱们用环境贴图的形式,照亮整个场馆。咱们应用这张图片:
new RGBELoader().load('../resources/sky.hdr', function (texture) {
texture.mapping = THREE.EquirectangularReflectionMapping
scene.environment = texture
renderer.outputEncoding = THREE.sRGBEncoding
renderer.render(scene, camera)
})
接下来,咱们将人物角色加载进来,同样应用的是 GLTFLoader.
new GLTFLoader().load('../resources/models/player.glb', (gltf) => {
playerMesh = gltf.scene
scene.add(playerMesh)
}
角色加载进来后,如何让她挪动呢?应用 playerMesh.translateZ() 办法,让其在 Z 轴方向挪动,对应到场景中,就是在高空上挪动了。那如果碰到墙壁,是不是就不应该让角色继续前进了呢?所以要实现碰撞检测性能,这里应用 Threejs 中的 Raycaster 射线检测来实现。
window.addEventListener('keydown', (e) => {if (e.key === 'w') {const curPos = playerMesh.position.clone(); // 获取角色以后地位
playerMesh.translateZ(1);// 让角色往前走一步
const frontPos = playerMesh.position.clone();// 在获取当初的地位
playerMesh.translateZ(-1);// 退回原来的地位
const frontVector3 = frontPos.sub(curPos).normalize()// 让后面地位的向量减去前面地位的向量
const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight), frontVector3);
const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);
if (collisionResultsFrontObjs && collisionResultsFrontObjs[0] && collisionResultsFrontObjs[0].distance > 1) { // 间隔大于 1 才能够继续前进
playerMesh.translateZ(0.1);
}
}
if (e.key === 's') {// 后退
playerMesh.translateZ(-0.1);
}
})
到这里,展馆的基本功能就实现完了。
正文完