使用Primrose和WebVR在VR中构建虚拟现实

  • Post author:
  • Post category:其他


随着VR头戴设备在全球各地的热销,虚拟现实今年确实在大步向前。 当虚拟现实开发开始迎合这些急切的开发人员时,它们正在稳步吸引着开发平台的更多关注。 Unity和Unreal Engine都引入的最令人兴奋的功能之一就是能够在虚拟现实中编辑虚拟现实场景。 使用WebVR和JavaScript的开发人员将很高兴地知道,他们也出现了一个框架,该框架为WebVR原型设计和实验带来了这种功能-Primrose。

什么是樱草花?

他们的

官方网站

最能描述樱草花,

Primrose是一个跨浏览器的多设备框架,用于在WebVR应用程序中构建生产力工具。

Primrose为开发人员提供了一个不错的框架,使他们可以在浏览器中打开,尝试新想法并探索他们在VR中的外观。 它是开源的,仍然很新,并且正在积极开发中。

您需要什么

要跟随并开始使用Primrose进行WebVR向导的旅程,您将需要:

  • 支持WebGL的浏览器,最好是具有WebVR支持的浏览器,例如

    最新的Chromium WebVR构建



    Firefox Nightly

  • Oculus Rift耳机(也可能是HTC Vive)或Google Cardboard-但是,您也可以在没有耳机的情况下在浏览器中进行实验和工作!
  • 某种Web服务器-本地Web服务器(例如WAMP / MAMP / static Node服务器/ static Python服务器)都可以!
  • 能够打字的功能-在VR中您将看不到键盘!

入门

您可以在

Primrose的网站上

试用完整版本的实时编码

(确保您使用支持WebGL的浏览器(如上述浏览器)进行访问,否则只能看到静态屏幕截图)

如果您希望自己的副本在本地运行,则可以从Primrose GitHub存储库中

下载/克隆最新版本及其示例

我们在GitHub上的简化版本

在本文中,我整理了实时编码演示的简化版本。 它使用与Primrose演示相同的代码,但功能有所减少,以使事情在早期就易于解释。 要继续阅读本文,请

转到该

版本的

GitHub存储库

运行我们的简化版本

要运行我们的实时编码演示程序的简化版,请将其复制到您的Web服务器上,然后在启用了WebGL的浏览器中打开该位置(例如,如果将

http://localhost/primrose

放在您的浏览器中,甚至只是

http://localhost

服务器的根目录。



注意:

这不会从您的文件系统运行!


如果您尝试从

file:///Users/yourname/primrose/index.html

类的位置运行该

file:///Users/yourname/primrose/index.html

,则该

file:///Users/yourname/primrose/index.html

将中断,因为浏览器不会授予JavaScript这样的访问纹理文件的权限。

运行此命令后,您应该看到如下所示的内容:

我们最初的运行演示

如果您在此场景中四处张望,就会看到代码编辑器已准备就绪,正在等待您的到来。 您可以将光标指向代码中的行,单击以将光标放在此处,然后像在常规文本编辑器中一样键入。 如果我们仅仅后点击

10



for (var i = 0; i < 10; i++)

并将其更改为

for (var i = 0; i < 100; i++)

,如下所示:

在演示中更新我们的代码

我们的场景将实时更改,现在随机移动了100个块!

我们的演示有100块

如果要从各个角度更好地看待它,可以看一下地板,然后单击要移动到的位置:

进行演示

您也可以使用键盘通过箭头键在场景中四处走动。

怎么运行的

在大多数情况下,您将不需要重建Primrose的实时代码编辑器示例的大部分内容,只需插入它们在GitHub上提供的示例代码并将其适应您自己的场景即可。 但是,我想我会提供一个简化的版本,以探究幕后发生的事情的一些概念,同时展示Primrose在其框架内能够实现的功能。

我们的Primrose应用程序的启动看起来像这样:

var BRICK = "images/brick.png",
    GROUND = "images/deck.png",
    SKY = "images/bg2.jpg",
    app = new Primrose.BrowserEnvironment("Our Simplified 3D Editor", {
      skyTexture: SKY,
      groundTexture: GROUND
    }),

这些代码行定义了我们的三个纹理文件,然后在

app

变量中实例化Primrose应用

app



Primrose.BrowserEnvironment()

方法通过天空和地面纹理设置场景。

我们还有一个

editorFrame

变量,用于将

2048

x

2048

区域设置为放置在内部的编辑器:

editorFrame = new Primrose.Surface({
  bounds: new Primrose.Text.Rectangle(0, 0, 2048, 2048)
});

所有Primrose应用程序(以及许多与此相关的JavaScript框架)的另一个常见方面是在

addEventListener("ready", function() {});

初始化我们的元素

addEventListener("ready", function() {});

。 在这里,我们添加:


  • subScene

    –我们将可以通过实时代码编辑器在其中添加和更改元素。

  • editor

    –我们场景中的实时代码编辑器

    (我们将在下面对此进行更详细的介绍!)

  • 来自

    getSourceCode()

    初始代码–在我的简化版本中,这将检索Primrose编辑器随附的默认代码,并显示在我们的VR文本编辑器中。 在更为复杂的Primrose编辑器中,它可以对本地存储进行更多处理。
app.addEventListener("ready", function() {
  app.scene.add(subScene);

  editor = new Primrose.Text.Controls.TextBox({
    bounds: new Primrose.Text.Rectangle(
      0, 0,
      editorFrame.surfaceWidth, 
      Math.floor(editorFrame.surfaceHeight)
    ),
    tokenizer: Primrose.Text.Grammars.JavaScript,
    value: getSourceCode(isInIFrame),
    fontSize: 45
  });

  editorFrame.appendChild(editor);
});

Primrose最近发布了一个新版本,该编辑器使用

Primrose.Text

的一系列新框架对象进行了改进:


  • Primrose.Text.Controls.TextBox

    默认情况下,这将设置文本区域并提供全部功能。

  • Primrose.Text.Rectangle

    —这使我们可以为要放置在其中的文本区域定义矩形边界。 当我们也定义了

    editorFrame

    时,您可能已经注意到了。

  • Primrose.Text.Grammars.JavaScript



    tokenizer

    键中用于设置JavaScript代码突出显示。 您可以通过

    Primrose.Text.Grammars.PlainText

    进行明文突出显示。

当使用Primrose应用程序时,除了

"ready"

,您还需要注意一些事件,其中包括:


  • "update"

    –这是我们在示例编辑器代码中使用的唯一其他事件,它每帧运行一次。 您可以在Primrose中使用它来运行动画并检查场景中的更新。

  • "keydown"



    "keyup"



    "keypress"

    –分别在按下,释放以及按下和释放键时运行。

  • "mousedown"



    "mouseup"

    –与上面相同,但使用鼠标。

  • "mousemove"

    –检测鼠标移动。

  • "wheel"

    –检测用户何时移动鼠标滚轮。

  • "touchstart"



    "touchend"



    "touchmove"

    –使用触摸屏检测手指何时向下触摸场景中的某个元素,将手指从屏幕上抬起并在屏幕上滑动手指。

  • "unload"

    –在关闭应用程序时运行。 我的简化版编辑器不使用此功能,但是完整的Primrose编辑器使用此功能将编辑器内容保存到本地存储中。

  • "load"

    –在应用再次加载时运行。

  • "pointerstart"



    "pointerend"



    "pointermove"

    –响应对象上的单击和触摸事件,因此您无需单独注意这两个事件。

  • "gazestart"

    –响应用户

    "gazestart"

    对象的那一刻。

  • "gazecomplete"

    –响应于用户默认情况下看对象一秒钟。

  • "gazecancel"

    –响应于用户在默认值一秒过去之前将

    "gazecancel"

    移开。 您可以通过

    gazeLength

    更改一秒钟的默认值,但这超出了本文的范围。

我不会在本文中粘贴所有简化的代码(它会变得很长而且很笨拙!)。 您可以在上面链接的GitHub存储库中进行检查。 但是,我们将介绍一些事件响应和功能所包含的内容。

在我们简化的应用程序的

"update"

事件中,它将检查编辑器中的所有代码更改,并在每个

scriptUpdateTimeout

(每

scriptUpdateTimeout

运行一次超时)上更新它们,并运行它已经知道的动画。

在对

"keydown"

事件的响应内部,它清除了

scriptUpdateTimeout

超时,从而延迟了我们的应用尝试更新内容的时间!

每当

scriptUpdateTimeout

完成时,

scriptUpdateTimeout

运行

updateScript()

函数。 这将检查编辑器的脚本是否已更改,并在看到更新后替换正在运行的脚本。 它

subScene

从上方清除

subScene

并根据VR编辑器的代码更改元素。

设置按钮功能

为了能够体验适当的,身临其境的实时编码体验(或您构建的任何其他由Primrose支持的应用程序),我们希望它能够全屏显示。 这对于VR是必不可少的,因为它将无法以其他方式起作用! 为此,我们添加了触发这些模式的按钮。 报春花已大部分的本公约所涵盖的是,我们只是在一个按钮来添加与一个ID

goVR

和一个与

goRegular

,则称

app.setFullScreenButton

传递的ID名称,它是一个click事件,要么

true

的VR或

false

对于常规的全屏模式:

app.setFullScreenButton("goVR", "click", true);
app.setFullScreenButton("goRegular", "click", false);

使报春花魔术发生

当前,在调整代码时,我们有各种各样的多维数据集可以实时漫游和实时更改-但是我们可以在Primrose中构建哪些其他功能? 您可以在

app.js


testDemo()

或VR中的场景中添加以下元素!


轴为您提供了一组红色,绿色和蓝色的条形,分别显示了x,y和z的方向。 这通过

axis(length, width)

起作用,例如:

put(axis(5,0.1)).on(start);

生成此最终结果:

轴对象

点云

可以通过

cloud(verts, color, size)



cloud(verts, color, size)

使用许多小的正方形点生成点云。

verts

变量是一个顶点数组。 点云的示例如下所示:

var verts = [];

for (var i = 0; i < 5000; ++i) {
  verts.push(
    v3(Primrose.Random.number( -0.5 * WIDTH, 0.5 * WIDTH),
      Primrose.Random.number(-0.5 * HEIGHT, 0.5 * HEIGHT),
      Primrose.Random.number(-0.5 * DEPTH, 0.5 * DEPTH)
    )
  );
}

put(cloud(
  verts, this.options.backgroundColor, 0.05)
).on(start).at(MIDX, MIDY, MIDZ);


MIDX



MIDY



MIDZ

是示例代码中已经存在的变量,它们为场景指定了焦点。 您可以在其位置使用任何数字。

这将在我们的场景中生成以下内容:

我们场景中的点云


在上面的示例中,您可能已经注意到的一件事是,我们正在添加名为

start

。 实际上,这是一个

hub()

-我们场景中的一个特殊点,我们可以在其中组合其他对象。 我们的

start

中心尤其如此定义:

start = put(hub())
          .on(scene)
          .at(-MIDX, 0, -DEPTH - 2);


可以通过

light(color, [intensity, [distance, [decay]]])

定义

light(color, [intensity, [distance, [decay]]])

。 我们场景中的默认照明是白光,看起来像这样:

put(light(0xffffff, 1, 500))
  .on(start)
  .at(MIDX + 5, 8, MIDZ + 20);


框以及其后的形状需要进行纹理处理,然后才能出现在我们的场景中。 它们被包装在Texture

textured()

函数中,该函数为它们提供了来自我们图像文件的纹理。 框的格式如下所示:

box(width, height, length)

put(textured(box(2, 2, 2), BRICK))
  .on(start).at(MIDX, MIDY, MIDZ);

这将在我们的场景中创建一个大型的

Three.js BoxGeometry对象

我们场景中的一个简单盒子

圆筒

气缸可以通过以下方式实现:

cylinder(
  radiusTop,
  radiusBottom,
  height,
  radiusSegments,
  heightSegments,
  openEnded,
  thetaStart,
  thetaEnd
)

这将创建

Three.js CylinderGeometry对象

。 例如,这是一个圆柱体,其顶部和底部半径为

1

。 其高度为

5

,半径/高度段为

40

put(textured(cylinder(1, 1, 4, 40, 40), BRICK))
    .on(start).at(MIDX, MIDY, MIDZ);

看起来像这样:

我们场景中的圆柱体

其他

您可以在

Primrose文档的“脚本功能”下

找到许多其他选项,包括

quad()



shell()



sphere()

等。 探索和实验!

结论

Primrose是一个功能强大的WebVR框架,将来肯定会为某些非常有用的VR应用程序提供支持。 尽管在框架和WebVR本身中都处于早期状态,但随着时间的推移,随着WebVR的日趋成熟,它似乎已经以一种很好的方式进行了扩展和发展。

喜欢这里的潜力吗? 请记住,这也是您可以参与的早期项目! 与它的创建者

Sean McBeth联系

,并参与其中!

如果您将Primrose用于自己的VR应用程序,我很乐意看到您组装在一起的东西! 在下面的评论中让我知道,或者在Twitter上通过

@thatpatrickguy

与我

联系

如果您发现虚拟现实和WebVR令人着迷,我

在Dev Diner网站上

与Sean McBeth谈过有关为VR和Primrose

进行开发的事情

。 这是我做过的最喜欢的采访之一! 肖恩是一个鼓舞人心的人。

From:

https://www.sitepoint.com/build-virtual-reality-with-primrose-and-webvr/