我们决定踏入一个真实的世界。要理解如何画那个世界,我们需要准确地理解如何描述它。
本章描述了我们如何在数学意义上做到这一点。别担心,这不是高中数学的回归!(好吧,也许是几何。好吧,也许有一点。好吧,也许很多。我会尽量让它无痛。)
有许多不同的方式来描述世界;不管我们怎么做,世界还是一样。正如莎士比亚在《罗密欧与朱丽叶》中所说:
"What's in a name? That which we call a rose by any other name would smell as sweet."
有趣的是,在我们的例子中,情况并非如此:一个描述错误的盒子看起来会完全不同。你需要学习这门语言。不仅如此,您还需要了解 React VR 如何描述世界,因为不同的 3D 图形程序都使用不同的数字(缩放)、方向(向量)和旋转。
对于虚拟世界,软件和硬件的类型都需要不同的方式来描述所看到的事物。例如,坐标可以是左手坐标或右手坐标。如果您将它们混合在一起,对象将以不同于您预期的方向移动!
特别是,up 在 3D 中有不同的含义;更具体地说,向上方向通常不是不同 3D 程序之间的标准方向。在 React VR 中,Y 向上。为什么 Y 向上?请继续阅读以了解:
- 坐标:这些是空间中的固定点
- 点:这些是多边形的构建块
- 向量:这些是方向
- 变换:这些是将东西移动到你想要的地方
- 渲染:这将把对点和变换的讨论变成了真实的东西
为了用 3D 表示事物,我们必须将我们看到的东西转换成计算机可以用来生成图像的东西。这些方法将涉及具有 3D 几何图形、图片和代码的文件。首先,让我们讨论一下如何在 3D 中定位物体。
要在 3D 中表示对象,我们需要它们的位置。Excel 之类的电子表格使用 A-Z(交叉)和 1-66 向下(实际上是 A-XFD 和 1-1048576)。计算机图形学对所有三个轴都使用数字。但是,有不同的方法来编码这些坐标。
这适用于刻度(什么是 1,1 英寸?1 英里?)和它们的方向(向上是 Y 还是 Z?)。为了解决这个问题,我们需要讨论坐标系。
我们都习惯于用X和Y网格绘制纸张、网格和发光的电子表格,或者在您使用的任何电子表格程序中使用 A1 和 B1 等数字和字母。进入第三维度可能会让人困惑,即使那是我们生活的地方。这就是为什么我把这部分叫做超越平原。
我们认为在二维或一般数学中理所当然的数学运算,结果只是在三维中有所不同。例如,如果将X和Y相乘,得到的答案与将Y和X相乘得到的答案相同。然而在三维空间中,旋转并不是这样的。若要看到这一点,请尝试同时复制这本书。(我买了两本,是吗?妈妈,你在看吗?)
好的,说真的,请随便拿两本书,真正的纸质书。如果你有两台 Kindle,你可以用它们。
- 第一本书:
- 从左向右(朝向右手)翻转四分之一圈(关闭时)。
- 然后,将后缘朝您翻转(翻转)。
- 您现在可以从侧面查看后面的页面。
- 对于第二本书,按相反顺序翻转:
- 将后缘朝你的方向翻转(翻转)。
- 然后顺时针从左向右(朝向右手)旋转四分之一圈。
这两本书面向不同的方向,尽管两次旋转的方式相同,只是顺序略有不同。
三维数学可能令人困惑。通常,如果将A和B相乘,得到的结果与将B乘以A得到的结果相同。
当涉及到平移、旋转和缩放时,这个概念非常重要。对象在世界中的最终位置以及它们的外观取决于编码顺序。
我们将使用三个数字为 3D 中的所有内容指定一个位置,具体为X、Y和Z。
This is called a Cartesian coordinate system. There are other types of coordinate systems, but nearly every computer system uses a Cartesian system for spatial locations. Rotations and vectors will sometimes use other systems. This is a Euclidean space.
为了让 3D 更加混乱,一些人使用了X和Y,其中Z是新的维度,而另一些人说Y向上。为什么会这样?在处理屏幕时,您习惯于使用X和Y。一张纸是类似的,尽管纸通常是水平的,屏幕是垂直的。
这导致了一个有趣的转换为 3D 的问题。在 3D 中,我们使用了X、Y和Z。如果你习惯于使用X和Y,那么Z必须是新的三维空间,并且它将向上。然而,如果你习惯于将X和Y视为一张图表,那么Y已经向上,因此Z最终会进进出出。每个 3D 系统似乎略有不同。
WebGL, which React VR is based on, uses the familiar X and Y as right/left and up/down; so Z has to be in/out. However, one difference is that in React VR, Y is up; in standard HTML, Y is down. In other words, HTML and React use a coordinate of (zero by zero) as the upper left-hand corner. Is Y is up? Most 3D programs use Y or Z as up, meaning in our case positive Y is up.
WebGL 和 HTML 与 React 不同,可能需要一些时间才能习惯。要把一个物体向前推,这样你就能看到它,你需要给它一个负 Z。
在 3D 中,坐标可以是左手坐标或右手坐标。正如我们在X、Y和Z中所看到的,有时箭头不会指向您期望的方向。为什么 VR(实际上是 OpenGL)没有决定让 Z 进入屏幕?那么坐标将是左手的。相反,大多数图形系统使用右手坐标系
My brother is left handed. Nothing wrong with a south paw. (Actually, he's right handed, but why spoil a good story with the facts?)
右手和左手到底意味着什么?它是一种帮助记忆箭头方向和旋转的助记符。如果你握住任意一只手,将前三个数字展开,它们会拼出X、Y和Z方向。一张图表会有帮助;您的前三个手指(拇指、食指、中指)指向正X、Y和Z:
在这个图表中,有几件事需要注意。相机在左边代表我们,看着屏幕(透明地描绘)。因为Y向上(为什么?),而X在右边,OpenGL 使用的坐标系与 HTML 或一张图纸不同,但它或多或少是 web 的标准。
选择此选项是为了更容易地映射到 3D 模型、计算机辅助设计(CAD)和建模程序(如 Blender、Maya、3DSMax)的构建方式。这与 React 的工作方式相反-Y与 React 一起下降为正值。这是一个惯用右手的系统;如果你试着用左手来做这件事,你会得到不同顺序的X、Y和Z轴
使用 React VR 和 OpenGL 绕任意轴旋转也是右手操作。这意味着围绕任何轴的正旋转将沿着拇指指向和手指弯曲的方向进行。例如:
你是不是看着你的右手卷曲手指?没关系,这有助于形象化。是的,这些是箭头,显示了沿各自轴的正方向。
Honestly, Y is up and Z is up seem to be pretty commonly mixed in the 3D CAD world. Your CAD system may work differently. It's OK, we can flip and invert it - just be aware that when importing models, you may find them on their side, or even inside out. In particular, in Blender Z is up and X and Y are in the flat plane; however, it can substitute Y for up when you export. Why? Because it's on the up and up.
这些数字是无量纲的;一个 1×1×1 的立方体可以被认为是 1 英里或 1 英尺。然而,在 WebVR 和 React VR 中,单位通常以米为单位。
Blender can use dimensionless units, metric, or imperial, so you'll need to fiddle with scaling when importing things. The program Poser uses odd units—you will need to scale anything coming from it. OBJ files, commonly used for importing models, have no unit information; they are dimensionless: 1 is 1, not 1 meter.
点指空间中的 3D 位置,通常通过X、Y和Z位置识别。除非进行本机渲染,否则在 React VR 中很少直接描述点,但空间中的位置通常被描述为点。例如,变换节点可能会说:
transform: [{
translate: [0, 400, 700]
}]
应用变换的对象的中心将位于位置X=0、Y=400、Z=700。
向量指的是一个方向。在航空业,飞行员谈论矢量。在电影飞机的场景中,克拉伦斯·奥维尔、罗杰·默多克、维克多·巴斯塔和控制塔讨论航向:(http://bit.ly/WhatsOurVector
"Roger Murdock: Flight 2-0-9'er, you are cleared for take-off. Captain Oveur: Roger! Roger Murdock: Huh? Tower voice: L.A. departure frequency, 123 point 9'er. Captain Oveur: Roger! Roger Murdock: Huh? Victor Basta: Request vector, over. Captain Oveur: What? Tower voice: Flight 2-0-9'er cleared for vector 324. Roger Murdock: We have clearance, Clarence. Captain Oveur: Roger, Roger. What's our vector, Victor? Tower voice: Tower's radio clearance, over! Captain Oveur: That's Clarence Oveur. Over."
从我们 VR 人的角度来看,他们真正的意思是前进。在三维空间中,也可以向上或向下瞄准。这三个方向对我们都很重要
正确地说,翻译使用向量;如果将变换属性赋予[0,2,0]的对象,则告诉该对象在*+Y方向上移动2 个*单位,而不必移动到绝对位置 0,2,0。但是,请注意,如果对象的原点位于 0,0,0,则它是相同的。重要的是要考虑你的 3D 对象在翻译它们时的原点,以及对象是否采取绝对或相对定位。
这不是一本关于奇怪的可折叠机器人的书,所以我们谈论的是变换,而不是变形金刚
变换是放置、定位、移动和缩放对象的方法,本质上是变换对象、点的X、Y、Z坐标等的任何东西
在 React VR 中,变换通常是样式的一部分。例如:
style={{
transform: [
{rotateZ : this.state.rotation},
{translate: [0, 2, 0]},
{scale : 0.01 },
],
}
变换顺序非常重要。正如我们前面所讨论的,在 3D 中,如果你先平移,然后旋转,那么变换是不可传递的。如果你先旋转,然后再平移,那么变换最终会出现在不同的位置。还记得书中的例子吗?
在 React VR 中,变换是大多数具有物理存在的对象的标准道具节点。(见附录及第 4 章、反应 VR 库)
转换实际上有三个主要参数(和许多不推荐的道具);转换或矩阵参数。
是的,我说的是矩阵。
一段时间以来,矩阵一直是一个数学概念。它也拍了一部很棒的电影。由于版权限制,我不能在这里包含矩阵的图片,但上面是我在矩阵中查看的 VR 控制器场景的表示。无论如何,我不是指电影。我们将使用矩阵创建我们自己的 3D 场景。
矩阵是描述平移(向量)、旋转、缩放和倾斜的数学方法。我的一些朋友在周末会发生歪斜,但歪斜是一个数学术语,意思是移动,比如说,物体的顶部超过底部。你可能会认为它是倾斜的。
为了充分理解矩阵,让我们谈谈非基努·里夫斯的方法。
任何时候有一个物理对象,比如一个盒子、一个模型、一盏灯或一个 VR 按钮,你都有各种各样的风格道具,其中之一就是变换。变换节点可以使用矩阵,或者有时更简单的直接转换属性。例如,如果您在 React VR 中定义了一个Cylinder
,您可能会将其转换为:
<Cylinder
radiusTop={0}
radiusBottom={2.20}
dimHeight={2.8}
segments={10}
style={{
transform: [
{rotateX: -45},
{translate: [0,1, -4]}
{scale: .4}
]
}}
/>
转换顺序很重要。以下是三个圆柱体的示例,除了颜色和变换外,它们是相同的:
<Cylinder
radiusTop={2}
radiusBottom={2.20}
dimHeight={5}
segments={10}
lit = {true }
style={{
color: 'red',
transform: [
{translate: [1,.5, -6]},
{rotateZ: -90},
{scale: .2}
]
}}
/>
<Cylinder
radiusTop={2}
radiusBottom={2.20}
dimHeight={5}
segments={10}
lit = {true }
style={{
color: 'blue',
transform: [
{rotateZ: -90},
{translate: [1,.5, -6]},
{scale: .2}
]
}}
/>
<Cylinder
radiusTop={2}
radiusBottom={2.20}
dimHeight={5}
segments={10}
lit = {true }
style={{
color: 'green',
transform: [
{scale: .2},
{rotateZ: -90},
{translate: [1,.5, -6]}
]
}}
/>
这就是虚拟现实世界的结果:
矩阵是一个四列乘四行的数列(数组)。
您也可以在变换节点中使用matrix
。关于矩阵数学的完整讨论超出了本书的范围。网上有很多参考资料。基本概念相当简单,但旋转编程可能有点困难(尽管是确定性的)。
翻译存储为:
[1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
Tx,Ty,Tz,1].
缩放由以下内容表示:
[Sx,0, 0, 0,
0, Sy,0, 0,
0, 0, Sz,0,
0, 0, 0, 1].
旋转可以用以下公式中的 R 值表示:
[R00,R01,R02,0,
R10,R11,R12,0,
R20,R21,R22,0,
0, 0, 0, 1].
Rotations via matrix math are very precise, but also very complicated. As we saw earlier, the order of rotations will change the location of the resulting object. A matrix does not have these problems as the order is baked into the matrix itself. Calculating the rotations can be messy. Generally speaking, you'll want to use the transform styles instead of the matrix math, when moving an object by hand (manual coding).
You'll want to use matrices when copying an object's position and orientation or programmatically moving it.
将所有轴缩放十分之一并平移[3,2,1]的matrix
可以作为matrix
应用,如下所示:
style={{
transform: [
{matrix : [0.1,0,0,0, 0,0.1,0,0, 0,0,0.1,0, 3,2,1,1]},
],
}}
不能同时使用变换矩阵和变换样式(单独平移、旋转、缩放)。实际上没有必要这样做,因为您可以通过指定单个变换来使用矩阵完成所有操作。如果你真的使用矩阵,那你就是铁杆!在任何情况下,您创建的任何变换都将在幕后转换为矩阵。
欢迎来到矩阵-现在您可以创建它了。
Bing 将渲染定义为:
嗯,这很有趣,但显然不是我们的意思。渲染是指将我们讨论过的所有数学描述都提取出来,并将其可视化。
React VR 使用的渲染引擎是 three.js(http://bit.ly/2wHI8S9 ),通常使用 WebGL 进行渲染(http://bit.ly/2wKoKCe )。WebGL 是用于生成高性能图形的健壮 JavaScript API。它将在您的系统中使用任何高性能图形硬件(GPU),并且在大多数浏览器中都是本机的,允许在不需要插件的情况下使用 3D 图形
然而,通常情况下,网络可能是一个疯狂的地方。你可能认为浏览器制造商会从 20 年前的兼容性问题中学到教训,但遗憾的是,事实并非如此。某些浏览器可能会出现皱纹或问题,尤其是在移动设备上。
我们就不能和睦相处吗?
这将影响 React VR 的工作效果。如果您想查看您的浏览器和硬件是否支持 WebGL,请转到位于的 WebGL 测试页面 http://bit.ly/WebGLTestPage 。页面将显示旋转立方体;如果您使用的浏览器不是百分之百兼容的,它也可能会显示一些警告。WebGL 维基百科页面(http://bit.ly/2wKoKCe 很好地描述了哪些浏览器做了什么,但情况发生了变化。
你需要测试一下。
在第二次世界大战中,海军陆战队在太平洋战前对两栖登陆进行了广泛的试验。他们制定了战术和战略。
他们第一次登陆时就撞上了珊瑚礁。圣地亚哥/彭德尔顿营地没有珊瑚礁。结果,虽然这是一次成功的着陆,但灾难性比他们想象的要大。因此,海军陆战队有一句谚语:
"Train as you would fight."
这显然是一个由来已久的说法。罗马军团曾经说过:
"Training should be a bloodless battle, so that in battle, it will be just like bloody training." -Roman Legion Training Maxim
如果你习惯使用 Firefox,将你的 React VR 解决方案发送到世界各地,而你的佩妮阿姨则使用管弦乐队浏览器查看你的世界,这可能不起作用,佩妮阿姨仍会认为你是她漫无目的的兄弟姐妹的无能后代。请注意,据我所知,虽然我使用 Opera,但 Orchestra 并不是真正的浏览器。
如果这是一个仅限公司内部使用的应用,并且您只有一个浏览器的标准(并且可以强制执行!),那么您可以使用该浏览器进行测试和开发。
然而,如果你想让很多人使用你的 React VR 应用,你真的应该用各种浏览器进行测试。如果你有一台 Mac、一台 PC 和一台 Linux 机器,那就更好了。这些可以是虚拟机(特别是具有适当许可证的 Windows 和 Linux),否则您需要测试人员。
你需要测试它,就像你期望人们使用它一样,否则你会认为它工作得很好,但人们不会对你的虚拟世界感到满意。您需要使用尽可能多的浏览器和硬件平台进行测试。当然,这并不实际,但却是必要的。这就是 beta 测试人员可以派上用场的地方。
我们在讨论渲染。这是一个获取数学模型并表达属性的过程,然后将其转换为您可以在屏幕上看到的内容。
要在 VR 中渲染模型,React VR 使用基于 OpenGL 的 WebGL。WebGL 是一种 JavaScript 实现,如果大多数平台在浏览器中具有相当功能的实现,那么 WebGL 在大多数平台上的外观应该是相同的。如果你描述一个直立的红色箭头,那么在所有浏览器中它看起来都像一个指向上的箭头。关于测试的建议通常是确保它能工作,而不是确保向上箭头不会突然指向右侧。
在游戏行业,人们通常不得不在 DirectX 和 OpenGL 之间做出决定。尽管 WebGL 基于 OpenGL 的设计,但 WebVR 两者都不使用。与 OpenGL 不同,它还包括 HTML 元素,如 HTML5 画布和 DOM(文档对象模型)。如果您使用的是 WebVR,那么您就是在使用 WebGL。
If a browser you are testing doesn't show your scene right, but does in other browsers, please file a bug report. Many of these applications are, like most cool things on the internet, bleeding edge.
You want these bugs fixed — so tell people. Programmers can't fix what they don't know about. You'll be contributing to a saner, cleaner, more effective web.
Be part of the solution!
WebGL 通常通过 OpenGL 或 DirectX 使用高性能 GPU。您不需要担心,也无法控制 React VR 使用的是什么(除非使用本机),尽管这是一个优势。web 浏览器通常会做正确的事情,并使用手机(手机、平板电脑)、笔记本电脑或台式机上的任何可用硬件。
如果要更精确地控制渲染,该怎么办?这在 React VR Native 中是可能的,我们将在后面的章节中详细介绍。
在本章中,我们学习了描述虚拟现实世界的重要方法。如果你想这样想,我们正在学习矩阵的语言,它甚至涉及到矩阵。我们学习了 3D 坐标、点、向量、右手和左手世界以及变换
我们了解了所有这些概念是如何组合在一起并呈现的,以及不同的网页如何获取这些信息并从中创建视觉空间。我们也学会了测试!
为了能够进行测试,我们需要浏览器中的一些东西。要做到这一点,我们不仅需要知道如何用数字和旋转来描述世界,还需要知道这些数字是如何用于构建模块的。下一节将介绍 VR 用来描述世界的关键字、组件和对象。