0.1.97 • Published 9 months ago

lsd-renderer-3d v0.1.97

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

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特效

文字转贴图

全景图、全景视频

阴影

人物表情控制

0.1.96

9 months ago

0.1.97

9 months ago

0.1.90

12 months ago

0.1.91

11 months ago

0.1.92

11 months ago

0.1.93

11 months ago

0.1.94

10 months ago

0.1.95

10 months ago

0.1.86

1 year ago

0.1.87

1 year ago

0.1.88

12 months ago

0.1.89

12 months ago

0.1.85

1 year ago

0.1.84

1 year ago

0.1.83

1 year ago

0.1.82

1 year ago

0.1.81

1 year ago

0.1.80

1 year ago

0.1.78

1 year ago

0.1.79

1 year ago

0.1.77

1 year ago

0.1.76

1 year ago

0.1.75

1 year ago

0.1.74

1 year ago

0.1.70

1 year ago

0.1.71

1 year ago

0.1.72

1 year ago

0.1.73

1 year ago

0.1.67

1 year ago

0.1.68

1 year ago

0.1.69

1 year ago

0.1.65

1 year ago

0.1.66

1 year ago

0.1.64

1 year ago

0.1.63

1 year ago

0.1.62

1 year ago

0.1.61

1 year ago

0.1.59

1 year ago

0.1.60

1 year ago

0.1.58

1 year ago

0.1.56

1 year ago

0.1.57

1 year ago

0.1.55

1 year ago

0.1.53

1 year ago

0.1.54

1 year ago

0.1.52

1 year ago

0.1.51

1 year ago

0.1.50

1 year ago

0.1.49

1 year ago

0.1.47

1 year ago

0.1.46

2 years ago

0.1.44

2 years ago

0.1.45

2 years ago

0.1.42

2 years ago

0.1.43

2 years ago

0.1.40

2 years ago

0.1.38

2 years ago

0.1.39

2 years ago

0.1.37

2 years ago

0.1.36

2 years ago

0.1.35

2 years ago

0.1.34

2 years ago

0.1.33

2 years ago

0.1.32

2 years ago

0.1.31

2 years ago

0.1.30

2 years ago

0.1.29

2 years ago

0.1.28

2 years ago

0.1.27

2 years ago

0.1.26

2 years ago

0.1.25

2 years ago

0.1.24

2 years ago

0.1.23

2 years ago

0.1.22

2 years ago

0.1.21

2 years ago

0.1.20

2 years ago

0.1.19

2 years ago

0.1.18

2 years ago

0.1.17

2 years ago

0.1.16

2 years ago

0.1.15

2 years ago

0.1.14

2 years ago

0.1.13

2 years ago

0.1.12

2 years ago

0.1.11

2 years ago

0.1.10

2 years ago

0.1.9

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago