lsd-renderer-3d v0.1.97
lsd-renderer-3d是什么?
lsd-renderer-3d是用于开发web3D应用程序的工具包,隐藏了专业的图形学、数学等和业务逻辑无关的细节,用于快速搭建一个3D场景。另外lsd-renderer-3d会封装一些基础功能和特效,比如Character:用于创建一个人物模型,包含行走、动作等功能;CameraControl:用于控制视角变换,最常见的功能比如跟随人物移动、旋转、第一人称和第三人称切换等;目前lsd-renderer-3d还在初期阶段,为了不断权衡易用性和灵活性,会不断地快速迭代,api变动可能会很大。 本文是案例文档,通过一些案例场景来讲解sdk的使用方法,api细节请参考sdk文档。 为了方便,以下示例均基于vue3开发。
安装
npm i lsd-renderer-3d
环境要求:node14+
线上demo和目录一一对应,建议先去体验一波,然后回来看文档里的讲解,然后再去看源代码。
在线demo,需要魔法上网
目录
准备工作
加载模型
创建人物
精灵
点击事件
在3D场景中播放视频
视频控制器
bloom特效*
ssr特效*
文字转贴图
全景图、全景视频
阴影*
人物表情控制
目录中打星号部分为可选部分,通常是优化视觉效果的特效、实验性功能等,有可能会有设备兼容性问题和性能问题,资源管理不当会导致显存爆满程序崩溃,谨慎使用。
准备工作
要在网页中渲染3D场景,需要做一些前置工作。
1.1初始化物理引擎
物理引擎用于控制3D空间的物理模拟,例如人物行走,碰撞,皮球滚动掉落,旗帜飘动等。 物理引擎在一次页面加载只能初始化一次,vue-router使用pushState进行路由更新,页面不会重新加载,所以可以在main.ts中进行初始化;location.href会触发浏览器,页面重新加载一次,所以只需要在代码开头初始化完成即可。
//将物理引擎初始化到全局
import { PhysicEngine } from "lsd-renderer-3d";
//@ts-ignore
window.physicEngine = new PhysicEngine({ softWorld: false });
1.2创建画布容器
在网页中任意位置创建一个div,且width和height不为0,这个画布的大小可以是动态的,但是需要在画布尺寸更改后更新渲染器,后续会在案例中说明。
1.3初始化相机和场景
Camera:相机就像我们的眼睛,相机指向哪里,哪里的画面就会被渲染到屏幕中,相机旋转移动,屏幕中的画面就会旋转移动。如果没用相机,屏幕中就不会有画面渲染,所以创建相机放在第2节讲解。 Scene:场景是一个3D对象的容器,所有3D对象如果要被渲染和交互,必须添加到Scene中 ScreenSize:这个对象用于控制屏幕尺寸变化,浏览器被拉伸是很正常的事情,但是每一帧渲染的画面长宽都是固定的,如果没更新尺寸,渲染的画面将和画布的父容器无法匹配等问题。
dom = doc1RootRef.value
screenSize = new ScreenSize({dom})
cameraControl = new CameraControl({
screenSize:screenSize,
fov:75,
near:0.1,
far:100000
})
cameraControl.setRadius(7)//设置相机旋转半径,半径>0
sceneControl = new SceneControl({ hdrUrl: 'https://yiverse-resource.obs.cn-south-1.myhuaweicloud.com/web/cndreamAssets/sky.hdr' })
1.4初始化渲染器
threeRender = new ThreeRender({
camera: cameraControl.camera,
scene: sceneControl.scene,
screenSize:screenSize,
})
//threeRender.update()
到这一步,只要调用threeRender.update(),浏览器已经可以渲染出一帧画面了。 但我们需要让画面动起来,就需要不断地渲染画面,也就是说要重复调用threeRender.update()
function animate() {
requestAnimationFrame(animate);
//@ts-ignore
window.physicEngine.update(threeRender.deltaTime)//刷新物理引擎状态
threeRender.update()//刷新渲染器
}
animate();
这时候我们声明一个函数animate,然后在函数内部调用requestAnimationFrame(animate),然后调用animate函数,这时候animate就会被浏览器不断地调用。然后我们就可以在函数内更新物理引擎和渲染器了。不出意外,页面中将会渲染出一片蓝色的天空,这个蓝色的天空来自hdr文件,也就是在初始化SceneControl时设置的那个url地址,专业术语通常称之为“skybox”。 现在尝试用鼠标左键拖拽画布,你会发现什么事情都没有发生,理想状态是,拖动画布,视野内的景物会移动,这部分的功能需要依靠CameraControl相机控制器。
//首先定义一个三维矢量,三个参数分别对应坐标x,y,z。这个点将是相机注视的位置,也就是我们盯着看的地方
let cameraFollowPosition:any = new LVector3(0,2,5)
...
animate();
...
//在这里更新相机控制器,并设置坐标。
threeRender.newFrameCallback = () =>{
cameraControl.update(cameraFollowPosition,[])
}
这时候,就可以再次尝试拖动画布,你会发现画面动起来了,旋转起来了。到这一步为止,渲染一个3D场景最基本的准备工作已经完成。
但是还有一个工作要做,就是资源销毁。3D资源如果没有手动销毁的话,只有在页面被关闭或者跳转后才会销毁被占用的“内存”和“显存”,资源销毁非常关键,尤其是显存,稍不注意就会爆显存,如果显存报了,就必须重启浏览器了,否则浏览器的WebGL整个功能报废,刷新页面也没用。
const disposeAll = ()=>{
threeRender?threeRender.dispose():null
cameraControl?cameraControl.dispose():null
sceneControl?sceneControl.dispose():null
screenSize?screenSize.dispose():null
dom.innerHTML = ""
}
//资源销毁
onUnmounted(()=>{
disposeAll()
})
这样就销毁了相关的资源了。 需要额外说明threeRender.newFrameCallback这个函数,这个函数会在物理引擎和渲染器更新之后回调,也就是说这个函数也会不断地被调用,所以如果涉及到一些业务逻辑,应该放在newFrameCallback里,而不是animate里,否则会出现一些无法控制的事情。 还有,这个函数会被无限反复地调用,直到页面被关闭或者animate函数被取消,所以,除非有特殊情况,否则不要在里面创建对象,否则内存会爆掉。 最后说明一点,不要想着用setInterval代替requestAnimationFrame,具体原因可以自行搜索。
加载模型
目前只推荐使用gltf或glb模型,这个格式的模型适合web端使用,关于gltf和glb相比其他格式的模型的有点可自行搜索了解。
2.1使用GltfObject加载模型
2.2使用PhysicEngine将模型物理化
2.3模型的销毁
创建人物
精灵
点击事件
在3D场景中播放视频
视频控制器
bloom特效
ssr特效
文字转贴图
全景图、全景视频
阴影
人物表情控制
9 months ago
9 months ago
12 months ago
11 months ago
11 months ago
11 months ago
10 months ago
10 months ago
1 year ago
1 year ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago