从0开始的Oasis Engine学习笔记(三) —— VR实现

这是我参与更文挑战的第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

image.png

天空盒示例

  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)
    })
}

复制代码

最终效果

CPT2106191703-878x534.gif

end

good good study, day day up!!

respect by myself

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享