【问题标题】:Why does stereo 3D rendering require software written especially for it?为什么立体 3D 渲染需要专门为其编写的软件?
【发布时间】:2012-09-23 15:37:10
【问题描述】:

考虑到对 3D 图形渲染的幼稚看法,立体 3D 渲染似乎对开发人员来说本质上应该是透明的,并且完全是图形硬件和驱动程序的一项功能。无论 OpenGL 窗口在何处显示场景,它都会获取几何、光照、相机和纹理等信息来渲染场景的 2D 图像。

在场景中添加立体 3D 似乎本质上意味着使用两个横向偏移的摄像机,而所有其他场景变量保持不变。唯一的附加信息是使相机相距多远以及使它们的中心光线会聚多远。鉴于此,采用 GL 命令序列并在驱动程序级别交错适当的命令来驱动 3D 渲染似乎是微不足道的。

似乎需要专门编写应用程序才能使用特殊的 3D 硬件架构,这使得实现起来既麻烦又令人望而却步。我们会期望这会成为立体 3D 实现的未来,还是我忽略了太多重要的细节?

在我的具体情况下,我们使用的是 .net OpenGL 视口控件。我最初希望仅仅拥有支持立体的硬件和驱动程序就足以支持立体 3D。

【问题讨论】:

  • using two laterally offset cameras 横向到什么?旧相机? OpenGL 没有相机和物体变换的区别。在较新的版本中,它根本不关心这些转换,因为由用户来处理它们。应该如何提取这些信息?另外,您如何处理屏幕外缓冲区?例如,阴影贴图在立体中没有意义。
  • 但是:developer.download.nvidia.com/whitepapers/2010/… Using heuristics, the stereoscopic driver decides which objects need to be rendered per-eye and which do not, building the full left and right eye image in a manner that is transparent to the developer. 这叫Passive Stereoization。
  • @Nobody 我会说横向是屏幕的 x 轴,在空间上垂直于相机方向,与 2D 投影中的水平对齐。关于屏幕外缓冲区和阴影贴图,这些是我不完全掌握也不了解其复杂性的东西。也感谢您的论文。
  • 其实我可能误解了你的初衷,你是说 OpenGL 不再有或从未有过带有位置、目标和旋转矩阵的相机吗?当然,它至少对与相机视角一致的几何图形应用了一些透视变换?我的印象是 OpenGL 在虚拟 3D 场景中支持 3D 顶点、3D 三角形和任意定位的摄像机。
  • 您应该接受 Bahbar 的回答。补充一点,想想基本 GL 1.0 是如何用于进行透视、正交或只是简单的 2d 渲染的。并混合所有这些。你怎么知道什么是什么?

标签: opengl stereo-3d


【解决方案1】:

遗憾的是,立体 3D 渲染比仅添加横向摄像机偏移更复杂。

您可以从原始“单声道”渲染帧和深度缓冲区创建立体 3D。给定场景中(现实世界)深度的范围,每个值的深度缓冲区会告诉您相应像素的距离。给定所需的眼睛分离值,您可以根据距离向左或向右滑动每个像素。但是……

您想要两个摄像机最终会聚的平行轴立体(偏移不对称平截头体)还是“前束”立体?如果是后者,您将需要逐个场景调整摄像机角度,以避免“反转”超出会聚点的几何形状。

对于非常靠近观察者的物体,左眼和右眼看到相同物体的完全不同的图像,甚至左眼看到物体的一侧而右眼看到另一侧 - 但单视图会将这些平均到前面。如果您想要一个准确的立体 3D 图像,它确实必须从不同的眼睛视点进行渲染。这有关系吗? FPS射击游戏,可能不是。人体手术训练模拟器,你敢打赌。

如果观看者将头向一侧倾斜,则会出现类似问题,因此一只眼睛比另一只眼睛高。同样,对于游戏来说可能并不重要,对于外科医生来说真的很重要。

哦,你在场景中有抗锯齿或透明度吗?现在你有了一个真正代表不同深度的两个像素值的像素。横向移动一个抗锯齿像素,它可能看起来更糟,因为“下面”的颜色已经改变。侧向移动一个大部分透明的像素,后面的像素会移动得太远。

你如何处理瞄准具十字和类似的 HUD 元素?如果它们是在禁用深度缓冲区的情况下绘制的,深度缓冲区的值可能会使它们在数百米之外。

考虑到所有这些潜在的问题,OpenGL 明智地并没有试图说明应该如何进行立体 3D 渲染。根据我的经验,修改 OpenGL 程序以进行立体渲染比一开始就编写它要省力得多。

无耻的自我推销:这可能会有所帮助 http://cs.anu.edu.au/~Hugh.Fisher/3dteach/stereo3d-devel/index.html

【讨论】:

  • 感谢 Hugh 的详细回答,尽管我一直想知道 mono+depth 是如何工作的。在所有情况下,两只眼睛都看到了包含被另一只眼睛遮挡的信息的视野,而完全双重渲染是唯一的答案。很多其他的东西看起来可能是用户设置的变量,比如眼睛间距、眼睛优势、对中性深度的偏好等,并且可能有一些非常有意义的默认值。重新头部倾斜,我认为这是一个最好留给下一代工具(例如头部/眼睛跟踪)的问题。
【解决方案2】:

你的假设是错误的。 OpenGL 不会“使用几何体、照明相机和纹理信息来渲染 2D 图像”。 OpenGL 使用命令来操作其状态机并使用命令来执行绘图调用。

正如没人在评论中提到的那样,核心配置文件甚至根本不关心转换。它现在唯一真正为您提供的是向顶点着色器提供任意数据的方法,以及向任意 3D 立方体提供渲染的方法。是否对应实际视图,GL不关心,也不应该关心。

请注意,有些人已经注意到驱动程序可以尝试猜测什么是视图,什么不是,这就是 nvidia 驱动程序在进行自动立体渲染时尝试做的事情。这需要一些特定的猜测工作,这相当于对游戏渲染进行实际分析以调整算法,以便驾驶员猜对。因此,它通常是按标题、驱动程序内的更改。一些开发人员已经注意到驱动程序可能会猜错,当这种情况发生时,它开始变得混乱。见一些first-hand account of those questions。

我真的建议您阅读该演示文稿,因为它进一步说明了相机应该指向的位置(两个视图方向是否应该平行等等)。

此外,事实证明,对于依赖于视图的所有内容,渲染成本基本上是其两倍。一些开发人员(包括,例如,Crytek guys, see Part 2)发现,在很大程度上,您可以进行一次渲染,并用额外的数据伪造图片以生成左眼和右眼图片。 这里节省的工作量本身就很有价值,让开发人员自己做。

【讨论】:

  • 我从字面上知道它不会使用这些东西并绘制图片,而是使用命令流的引擎。事实上,当我了解到 OpenGL 到底有多低级时,我感到非常震惊。我知道有很多与 3D 无关的图形方法和效果完全属于图形库,但在几何方面仍然感觉非常初级。
  • 我想我的观点又回到了在命令流中识别与从相机位置绘制三角形并截取它们相关的那些事情,只修改相机。我会阅读演示文稿,但似乎对于如何处理相机会有一个很好的答案,那就是将它们汇聚在虚拟屏幕平面上,这样 2D 元素就会出现在“中性”偏移处。感谢您的详细回答。
  • 从演示文稿来看,他们似乎提供了收敛/并行的替代方案,但没有明显的原因。
  • 参考您上面的“仅修改相机”评论,相机本质上是一个矩阵。在 Core 4.4 中,MAX_VERTEX_UNIFORM_COMPONENTS 必须至少为 1024,即最少 256 个 4 分量向量,即最少 64 个 mat4x4,因此驱动程序需要从至少 64 个可能的矩阵中选择一个相机矩阵。那是假设他们将其作为统一矩阵传递,尽管其他任何事情都会很疯狂。正如你所说,OpenGL 是低级的,因为它只是为了抽象出不同 GPU 的微架构细节,并为硬件提供一个通用接口
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多