【问题标题】:How do you use Processing for Android to display a stereoscopic image in a Google Cardboard device?您如何使用 Processing for Android 在 Google Cardboard 设备中显示立体图像?
【发布时间】:2015-05-01 00:28:43
【问题描述】:

Processing 旨在使使用 Java 进行绘图变得更加容易。 Android 处理具有其桌面兄弟的强大功能以及来自传感器的信息。将这些东西放在一起,显示立体图像并像 Oculus Rift 或 Google Cardboard 一样在其周围移动不是很容易吗?

【问题讨论】:

    标签: android processing stereo-3d google-cardboard virtual-reality


    【解决方案1】:

    很容易显示不好的立体图像。 Oculus 团队有理由花这么长时间来实现它;)

    首先,您需要知道人们会不同程度地交叉眼睛,以便将视线集中在靠近/远离他们的物体上。如果您将相机设置为完全平行,那么只有当用户专注于无穷远时,一切才会看起来不错。如果你以固定的方式转动每台摄像机,没有眼球追踪,你会得到前束立体,用于 3D 电影,会受到梯形失真效应的影响。如果没有正确的眼动追踪,最好的办法是使用倾斜的相机截头体 - 离轴投影。更多信息可以在here找到。

    还有其他问题。例如,当你转头时,你不仅改变了你眼睛的方向——你也改变了它们在 3D 空间中的绝对位置。如果您只是将手机旋转应用于相机,效果将关闭。这就是为什么您应该至少使用一个头部模型。当前版本的 CardboardSDK 支持对颈部进行建模,以考虑向上/向下看时的垂直平移。

    还有许多其他问题,例如由于耳机镜头造成的图像枕形失真、头部跟踪、将所有内容校准到特定手机、耳机、镜头、用户瞳孔间距...名单还在继续。

    总而言之,不,VR 不是一件小事或简单的事情。问题是,如果做得不好,它并不是立即显而易见的。用户可能不会有意识地知道有什么问题,但他们的大脑会知道。他们一生都在训练它与周围的现实进行交互,并且擅长知道什么时候出了问题。做得不好的虚拟现实应用程序可能会导致迷失方向、头痛、眼睛疲劳、恶心或只是提供不令人满意的体验。 VR 世界的一些大玩家担心,许多做得不好的 VR 应用会给很多人带来糟糕的体验,从而使他们远离这项技术并阻止其流行。

    总而言之,如果你想做 VR,要么确保你真的知道自己在做什么,要么使用专家制作的 SDK/框架

    【讨论】:

      【解决方案2】:

      下面的代码在两个视口中显示图像 - 一个用于左眼,一个用于右眼。结果是从 Google Cardboard 设备查看时,图像看起来像 3D。当头部四处移动时,加速度计和陀螺仪数据用于移动 3D 图像。唯一的错误是在横向模式下的 Processing for Android 会导致程序崩溃,如果您不在此模式下启动它。我使用的是 Processing 2.0.3 和 Android 4.3,所以这个问题可能已经在当前版本中得到解决。 (尽管我确实在 Github 上的 Processing-Bugs 讨论中看到它仍然是一个未解决的问题)。纹理图像是最喜欢的卡通人物的 100 x 100 像素图像。您可以使用任何您想要的 - 只需将图像存储在数据文件夹中。

      //Scott Little 2015, GPLv3
      //pBoard is Processing for Cardboard
      
      import android.os.Bundle; //for preventing sleep
      import android.view.WindowManager;
      import ketai.sensors.*; //ketai library for sensors
      KetaiSensor sensor;
      
      float ax,ay,az,mx,my,mz; //sensor variables
      float eyex = 50; //camera variables
      float eyey = 50;
      float eyez = 0;
      float panx = 0;
      float pany = 0;
      PGraphics lv; //left viewport
      PGraphics rv; //right viewport
      PShape s; //the object to be displayed
      
      //********************************************************************
      // The following code is required to prevent sleep.
      //********************************************************************
      void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      // fix so screen doesn't go to sleep when app is active
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      }
      //********************************************************************
      
      void setup() {
      sensor = new KetaiSensor(this);
      sensor.start();
      
      size(displayWidth,displayHeight,P3D); //used to set P3D renderer
      orientation(LANDSCAPE); //causes crashing if not started in this orientation
      
      lv = createGraphics(displayWidth/2,displayHeight,P3D); //size of left viewport
      rv = createGraphics(displayWidth/2,displayHeight,P3D);
      
      PImage img = loadImage("jake.jpg");  //texture image
      s = createShape();
      TexturedCube(img, s, 50, 50);
      }
      
      void draw(){
      //draw something fancy on every viewports
      panx = panx-mx*10;
      pany = 0;
      eyex = 0;
      eyey = -20*az;
      
      ViewPort(lv, eyex, eyey, panx, pany, -15); //left viewport
      ViewPort(rv, eyex, eyey, panx, pany, 15);  //right viewport
      
      //add the two viewports to your main panel
      image(lv, 0, 0);
      image(rv, displayWidth/2, 0);
      }
      
      //sensor data
      void onAccelerometerEvent(float x, float y, float z){
      ax = x;
      ay = y;
      az = z;
      }
      
      void onGyroscopeEvent(float x, float y, float z){
      mx = x;
      my = y;
      mz = z;
      }
      
      //
      void ViewPort(PGraphics v, float x, float y, float px, float py, int eyeoff){
      v.beginDraw();
      v.background(102);
      v.lights();
      v.pushMatrix();
      v.camera(x+eyeoff, y, 300, px, py, 0, 0.0, 1.0, 0.0);
      v.noStroke();
      //v.box(100);
      v.shape(s);
      v.popMatrix();
      v.endDraw();
      }
      
      //put a texture on PShape object, 6 faces for a cube
      void TexturedCube(PImage tex, PShape s, int a, int b) {
      s.beginShape(QUADS);
      s.texture(tex);
      
      // +Z "front" face
      s.vertex(-a, -a, a, 0, b);
      s.vertex( a, -a, a, b, b);
      s.vertex( a, a, a, b, 0);
      s.vertex(-a, a, a, 0, 0);
      
      // -Z "back" face
      s.vertex( a, -a, -a, 0, 0);
      s.vertex(-a, -a, -a, b, 0);
      s.vertex(-a, a, -a, b, b);
      s.vertex( a, a, -a, 0, b);
      
      // +Y "bottom" face
      s.vertex(-a, a, a, 0, 0);
      s.vertex( a, a, a, b, 0);
      s.vertex( a, a, -a, b, b);
      s.vertex(-a, a, -a, 0, b);
      
      // -Y "top" face
      s.vertex(-a, -a, -a, 0, 0);
      s.vertex( a, -a, -a, b, 0);
      s.vertex( a, -a, a, b, b);
      s.vertex(-a, -a, a, 0, b);
      
      // +X "right" face
      s.vertex( a, -a, a, 0, 0);
      s.vertex( a, -a, -a, b, 0);
      s.vertex( a, a, -a, b, b);
      s.vertex( a, a, a, 0, b);
      
      // -X "left" face
      s.vertex(-a, -a, -a, 0, 0);
      s.vertex(-a, -a, a, b, 0);
      s.vertex(-a, a, a, b, b);
      s.vertex(-a, a, -a, 0, b);
      
      s.endShape();
      }
      

      【讨论】:

      • 我通过删除orientation(LANDSCAPE) 行并在XML 文件中添加android:screenOrientation="landscape" 找到了方向问题的解决方案,如下所述:forum.processing.org/two/discussion/157/…
      • 嗨。你有这方面的 github 仓库吗?
      • 我是纸板新手。我无法使用上面的代码来显示这个立体图像。您能否提供任何示例项目或一些链接类来使用您的代码?我也检查了 github 链接,但是除了这个相同的代码之外没有别的了。如果您提供一些示例项目的链接或参考,将会很有帮助。谢谢
      • 让它工作的一切都在 Github 上。我没有明确提及的依赖项包括 Ketai 库及其依赖项。如果您有 OS X Mavericks,我建议您使用 Processing 2.0.3。即使您没有 Mac,您也可能想要使用该版本。另外,我应该提到这不是 Cardboard,但它适用于 Cardboard 设备。
      • @scottlittle 谢谢我必须在 Android 上做。我应该怎么做才能开始为 Android 开发 Cardboard 应用程序?有什么建议会有所帮助吗?
      猜你喜欢
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 2016-05-11
      • 2015-08-13
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多