这是我参与更文挑战的第3天,活动详情查看: 更文挑战
前边两篇文字简单介绍了一下怎么搭建Oasis-vue项目,和Oasis基本参数的介绍。本文我们来讲一下用Oasis来实现VR效果。
看到三种前端实现VR全景看房的方案!说不定哪天就用得上!里介绍了3种前端实现VR的方法,受益匪浅。我这里也来介绍一种,使用Oasis Engine天空盒实现VR的方法。
安装controls组件
那么本文就来演示下如果做到这个功能,我们先做一下准备工作,安装Oasis Engine 官方提供的扩展包 @oasis-engine/controls 控制器
npm i @oasis-engine/controls --save
安装完成后,在项目中引用
import { OrbitControl } from '@oasis-engine/controls'
OrbitControl是Oasis控制视角的一个组件,和其他的组件使用方法一样:绑定在实体上
我们这里将OrbitControl绑定在相机实体上
const cameraEntity = rootEntity.createChild('camera_entity')
cameraEntity.transform.setPosition(0, 0, 1)
cameraEntity.addComponent(Camera)
cameraEntity.addComponent(OrbitControl)
复制代码
准备工作到这里就准备完成了,接下来就是Oasis的天空盒
天空盒
什么是天空盒
在实时渲染中,如果想要绘制非常远的物体,例如远处的山,天空等,随着观察者的距离的移动,物体大小是几乎没有变换的。这类场景就非常适合用天空盒技术实现。
天空盒原理
天空盒本质就是一个立方体,每个面上贴一张图片,实际渲染的时候,立方体始终罩在相机周围,这样无论相机怎么转动,始终能够看到背景,基于此我们也可以使用天空盒来很容易实现VR效果
对应关系 | |
---|---|
px | right |
nx | left |
py | up |
ny | down |
pz | front |
nz | back |
天空盒示例
const cubeTextureResource = {
type: AssetType.TextureCube,
urls: [
//图片顺序: px nx py ny pz nz
require('../assets/px.png'),
require('../assets/nx.png'),
require('../assets/py.png'),
require('../assets/ny.png'),
require('../assets/pz.png'),
require('../assets/nz.png')
]
}
复制代码
我们首先需要按顺序加载6张立方体贴图,并申明类型为AssetType.TextureCube
在Oasis V0.4 中将背景相关的设置从相机组件中移动到场景属性中,所以使用如下代码获取到 background
const scene = engine.sceneManager.activeScene;
const { background } = scene;
复制代码
调用引擎 ResourceManager 实例的 load 方法将贴图加载到天空盒模型上,如下:
engine.resourceManager.load<TextureCubeMap[]>(cubeTextureResource)
.then((cubeMap: any) => {
background.mode = BackgroundMode.Sky
const skyMaterial = (background.sky.material = new SkyBoxMaterial(engine))
skyMaterial.textureCubeMap = cubeMap
background.sky.mesh = PrimitiveMesh.createCuboid(engine, 2, 2, 2)
})
复制代码
完整代码
import {
Camera,
PrimitiveMesh,
WebGLEngine,
AssetType,
TextureCubeMap,
SkyBoxMaterial,
BackgroundMode
} from 'oasis-engine'
import { OrbitControl } from '@oasis-engine/controls'
export function createOasis (): void {
// 初始化Engine
const engine = new WebGLEngine('canvas')
engine.canvas.resizeByClientSize()
// 获取场景根实体
const scene = engine.sceneManager.activeScene
const { background } = scene
const rootEntity = scene.createRootEntity()
// 创建一个相机实体
const cameraEntity = rootEntity.createChild('camera_entity')
cameraEntity.transform.setPosition(0, 0, 1)
cameraEntity.addComponent(Camera)
cameraEntity.addComponent(OrbitControl)
// 启动引擎
engine.run()
// 天空盒模型
const cubeTextureResource = {
type: AssetType.TextureCube,
urls: [
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*5w6_Rr6ML6IAAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*TiT2TbN5cG4AAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*8GF6Q4LZefUAAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*D5pdRqUHC3IAAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*_FooTIp6pNIAAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*CYGZR7ogZfoAAAAAAAAAAAAAARQnAQ'
]
}
engine.resourceManager.load<TextureCubeMap[]>(cubeTextureResource)
.then((cubeMap: any) => {
background.mode = BackgroundMode.Sky
const skyMaterial = (background.sky.material = new SkyBoxMaterial(engine))
skyMaterial.textureCubeMap = cubeMap
background.sky.mesh = PrimitiveMesh.createCuboid(engine, 2, 2, 2)
})
}
复制代码
最终效果
end
good good study, day day up!!
respect by myself