以下基于OSVR-Core 0.6-1962-g59773924
简介:
OSVR为多种设备创建一个抽象层,包括头显。也就是说,启动OSVR Server,只需要修改配置文件,就可以使同一个APP运行在不同头显设备上。
以下是添加一个新HMD到OSVR的关键步骤:
1>.创建一个json显示描述符文件。这里会指定头显的关键属性比如视场角。
2>.提供畸变信息。OSVR可对头显作畸变校正。可选。
3>.支持直连模式渲染。如果显卡支持直连模式,OSVR也可直接渲染到头显,并且这部分涉及了如果通过OSVR与头显实现直连渲染。
4>.集成追踪信息。通过HMD还包括外设比如方位追踪器。OSVR会一并将这些信息传给APP,用来更新虚拟世界的视角。
5>.确认HMD在OSVR上工作正常。确保显示没有畸变并且追踪器工作正常。
6>.发布HMD插件。发布OSVR插件以便全世界的开发者和游戏玩家能够在他们的OSVR软件和游戏上使用兼容的新头显。
显示集成:
对于让HMD在OSVR上能正常显示所需要做的事情,仅仅是从一个显示描述的json文件开始。可以从一个最简单的文件开始,OSVR HDK 1.1的json文件:
{
"meta": {
"schemaVersion": 1
},
"hmd": {
"device": {
"vendor": "OSVR",
"model": "HDK",
"num_displays": 1,
"Version": "1.2",
"Note": "Suitable for HDK 1.0-1.2"
},
"field_of_view": {
"monocular_horizontal": 90,
"monocular_vertical": 96.73,
"overlap_percent": 100,
"pitch_tilt": 0
},
"resolutions": [
{
"width": 1920,
"height": 1080,
"video_inputs": 1,
"display_mode": "horz_side_by_side",
"swap_eyes": 0
}
],
"distortion": {
/* Requires up to 27% overfill */
"distance_scale_x": 1,
"distance_scale_y": 1,
"polynomial_coeffs_red": [0, 1, 0, 0.5, 0, -1.15, 0, 9.25, 0, -5 ],
"polynomial_coeffs_green": [0, 1, 0, 0.5, 0, -1.15, 0, 9.25, 0, -5 ],
"polynomial_coeffs_blue": [0, 1, 0, 0.5, 0, -1.15, 0, 9.25, 0, -5 ]
},
"rendering": {
"right_roll": 0,
"left_roll": 0
},
"eyes": [
{
"center_proj_x": 0.5,
"center_proj_y": 0.5,
"rotate_180": 0
},
{
"center_proj_x": 0.5,
"center_proj_y": 0.5,
"rotate_180": 0
}
]
}
}
修改它用来适配我们新的HMD。
文档解释规范:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "OSVR Display Descriptor (v1)",
"description": "This schema documents and guides creation of a display descriptor, that describes properties of a head-mounted display",
"type": "object",
"properties": {
"meta": {
"title": "JSON Schema metadata",
"description": "Details about the JSON display descriptor schema.",
"type": "object",
"properties": {
"schemaVersion": {
"title": "Schema Version",
"description": "Version number of the display descriptor JSON schema. If you're using this schema, the value should be 1",
"type": "number",
"default": 1
}
}
},
"hmd": {
"title": "HMD",
"description": "Properties of a head-mounted display.",
"type": "object",
"properties": {
"device": {
"title": "HMD Device Description",
"description": "Describes HMD hardware and metadata.",
"type": "object",
"properties": {
"vendor": {
"title": "Device vendor/manufacturer",
"type": "string"
},
"model": {
"title": "Device model",
"type": "string"
},
"Version": {
"title": "Device version",
"type": "string"
},
"num_displays": {
"title": "Number of physical screens (NOT USED)",
"description": "This is redundant with information elsewhere in the schema and should not be used.",
"type": "integer",
"default": 1
},
"Note": {
"title": "Notes about the device",
"type": "string"
}
},
"required": [
"vendor",
"model"
]
},
"field_of_view": {
"title": "HMD Field of View Description",
"description": "Defines the optical parameters of the HMD. Since some HMDs have partial overlap – meaning that the viewing direction of the left and right eye are not identical – we define the field of view of just one eye and then the overlap between them.",
"type": "object",
"properties": {
"monocular_horizontal": {
"title": "Monocular Horizontal FOV in degrees",
"type": "number"
},
"monocular_vertical": {
"title": "Monocular Vertical FOV in degrees",
"type": "number"
},
"overlap_percent": {
"title": "Percentage of horizontal FOV that is 'overlapped'.",
"type": "number"
},
"pitch_tilt": {
"title": "Pitch tilt in degrees (NOT HANDLED)",
"description": "Some HMDs have their field of view tilted downwards. In this case, pitch_tilt would have a non-zero value in degrees, where positive is a downward tilt.",
"type": "number",
"default": 0
}
},
"required": [
"monocular_horizontal",
"monocular_vertical",
"overlap_percent"
]
},
"resolutions": {
"title": "Supported resolutions",
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {
"title": "HMD Resolution Description",
"description": "Describes HMD properties related to resolution.",
"type": "object",
"properties": {
"width": {
"title": "Horizontal size, in pixels, of a video input.",
"type": "integer"
},
"height": {
"title": "Vertical size, in pixels, of a video input.",
"type": "integer"
},
"video_inputs": {
"title": "Number of distinct video inputs",
"description": "Some HMDs have 2 separate inputs, one for each eye.",
"type": "integer",
"default": 1
},
"display_mode": {
"title": "Display Mode",
"description": "If a single input is used in side-by-side mode, width and height show the entire width and height of both sides combined.",
"enum": [
"horz_side_by_side",
"vert_side_by_side",
"full_screen"
],
"default": "horz_side_by_side"
}
},
"required": [
"width",
"height",
"video_inputs",
"display_mode"
]
}
},
"distortion": {
"title": "HMD Distortion Description",
"description": "Describes HMD properties related to distortion shader.",
"type": "object",
"properties": {
"k1_red": {
"title": "K1 Red distortion value",
"type": "number",
"default": 0
},
"k1_green": {
"title": "K1 Green distortion value",
"type": "number",
"default": 0
},
"k1_blue": {
"title": "K1 Blue distortion value",
"type": "number",
"default": 0
}
},
"required": [
"k1_red",
"k1_green",
"k1_blue"
]
},
"rendering": {
"title": "HMD Rendering Description (NOT HANDLED)",
"description": "Describes HMD properties related to rendering. These parameters are not used - please use the per-eye rotate_180 parameter for now",
"type": "object",
"properties": {
"right_roll": {
"title": "Right eye roll amount (degrees)",
"type": "number",
"default": 0
},
"left_roll": {
"title": "Left eye roll amount (degrees)",
"type": "number",
"default": 0
}
},
"required": [
"right_roll",
"left_roll"
]
},
"eyes": {
"title": "HMD Eyes Description",
"description": "Describes HMD properties related to eyes.",
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"center_proj_x": {
"title": "Horizontal center of projection",
"type": "number",
"minimum": 0,
"maximum": 1
},
"center_proj_y": {
"title": "Vertical center of projection",
"type": "number",
"minimum": 0,
"maximum": 1
},
"rotate_180": {
"anyOf": [
{
"title": "Flip Display Rotation",
"description": "Indicates if the view needs to flipped 180 degrees on the z axis (that is, in the plane of the screen) - 1 for true, 0 for false.",
"type": "integer",
"minimum": 0,
"maximum": 1
},
{
"title": "Flip Display Rotation",
"description": "Indicates if the view needs to flipped 180 degrees on the z axis (that is, in the plane of the screen)",
"type": "boolean",
"default": false
}
]
}
},
"required": [
"center_proj_y",
"center_proj_x"
]
}
},
"required": [
"device",
"field_of_view",
"resolutions",
"distortion",
"rendering",
"eyes"
]
}
}
}
}
适配新的HMD需要修改的字段为:
1.元数据字段-主要用于标识厂商,以及Render Manager也会使用到vendor字段:
1>.hmd.device.vendor
2>.hmd.device.model
3>.hmd.device.Version
4>.hmd.device.Note
2.基本光学参数:
1>.hmd.field_of_view.monocular_horizontal
2>.hmd.field_of_view.monocular_vertical
3>.hmd.field_of_view.overlap 如果屏幕没有对齐()
3.基本显示控制、输入数据
在resolution入口,width和height。并且,若不是单个输入的horizontal side-by-side模式,还有display_mode和潜在的video_inputs需要设置
如果要在OSVR server的server config 文件使用显示描述符JSON文件,需要添加或编辑"display":"???.json"行。例如以下是一个指定了senscis的dSight显示JSON文件的OSVR server config文件:
{
"plugins": [],
"drivers": [
{
"plugin": "com_osvr_Multiserver",
"driver": "YEI_3Space_Sensor"
}
],
"routes": [
{
"destination": "/me/head",
"source": {
"child": {
"changeBasis": {
"x": "y",
"y": "-z",
"z": "x"
},
"child": "/com_osvr_Multiserver/YEI_3Space_Sensor0/tracker/1"
}
}
}
],
"display": "displays/Sensics_dSight_landscape.json"
}
若没有指定显示行,则使用默认的,
一个简单有用的例子OpenGLSample可用来测试显示描述JSON文件(不能测试畸变),它位于OSVR-Core发布的文件内(需要使用到SDL)。该例子让人置身于一个盒子内。
校正镜头和显示畸变:
大多数情况下,显示会有一些畸变的度数,这些畸变的度数应该通过预矫正来补偿。OSVR有大量的畸变参数来适配不同类型的畸变,以及不同工具来测量它。所有这些模式可以在server配置文件内设定,在OSVR-core库文件中读出,并且其中一些在OSVR-RenderManager接口中实现。
一个理论上的畸变校正描述以及它与投影和视口关系的文章可参考:https://github.com/OSVR/OSVR-Docs/blob/master/Configuring/distortion.md
一个基于角度到屏幕坐标映射来构造的畸变参数可参考:https://github.com/OSVR/distortionizer/blob/master/angles_to_config/doc/anglesToConfig.md
OSVR-Core模式(在OSVR-Unity上实现的非RenderManager路径)自2016/1/25日起包括:
1.K1-parameter-based畸变-对红绿蓝的从一个中心点基于平面校正
RenderManager模式自自2016/1/25日起包括:
1.彩色基于一般多项式的畸变-基于径向畸变由红绿蓝环绕的一个已知的投射中心点。想要知道如何规定的需参考Rendermanager.h中的详细描述。
2.单色点样例-基于一个任意映射,这个映射来自角度到屏幕空间位置的,常常来自于一个在光学上的镜头仿真。参考详细:https://github.com/OSVR/OSVR-Docs/blob/master/Configuring/distortion.md
3.彩色点样例--基于一个任意映射,这个映射来自角度到屏幕空间位置的,常常来自于一个在光学上的镜头仿真。参考详细:https://github.com/OSVR/OSVR-Docs/blob/master/Configuring/distortion.md
使用一个点样例畸变矫正构建一个配置文件流程的描述,在该链接文章接近结束位置的地方https://github.com/OSVR/distortionizer/blob/master/angles_to_config/doc/anglesToConfig.md。最基本的方法是构建一个合适的服务端配置文件(如果需要还可以匹配一个客户端文件)然后使用该配置文件运行标准OSVR服务。任何基于Render Manager的客户端在渲染期间都将会处理指定的畸变矫正。
以下是一个基于一般多项式畸变矫正的配置文件的片段:
{
"display": {
"hmd": {
"distortion": {
"type": "rgb_symmetric_polynomials",
"distance_scale_x": 1,
"distance_scale_y": 1,
"polynomial_coeffs_red": [ 0, 1, 0.25 ],
"polynomial_coeffs_green": [ 0, 1, 0.32 ],
"polynomial_coeffs_blue": [ 0, 1, 0.40 ]
}
}
}
}
支持直连渲染:
下一步是直接到HMD的渲染:避免操作系统和窗口管理在顶部可见,删除它们的显示(扩展桌面的一部分),并且直接使用显卡驱动画它们。OSVR的RenderManager既处理非直连高级渲染(时间扭曲,先进的预失真等),只要一个在上面介绍的常规显示描述符文件即可起到该作用,和直连模式支持一样。
在一个新的HMD上使用直连渲染需要做三件事:
1.构建一个带屏幕分辨率和旋转参数的RenderManager配置文件以匹配其中一种该HMD支持的模式
2.添加EDID Vendor ID到RenderManager以及创建一个pull请求使它包含在Render Manager中
3.联系显卡厂商让添加的EDID vendor ID添加到他们的直连模式白名单。该HMD显示器必须被vendor显卡驱动认定为一个直连模式的显示器。这个过程的处理不同厂商有不同方法,应该直接联系他们让他们将EDID添加到他们的白名单。应该联系nVidia将新显示器的EDID添加到他们的驱动白名单中,需要注意的是他们已经在非兼容HDCP协议的笔记本上以及带多GPU的系统上停止了HMD直连模式的支持(并且他们一直在提示我们以后应该在任何显示器上支持HDCP协议)。然后,AMD使用另外的方法注册设备,因此也需要联系他们。Intel的显卡要求HMD添加一个指定的注册入口以标识它们应该在直连模式中被使用。
追踪和状态上报:
HMD大概都有内置或者外置的追踪器。如果是一个现成的追踪器,很可能已经通过VRPN在OSVR中支持了:需要链接更多请点击:http://osvr.github.io/compatibility/
一个为HMD服务的追踪器位于两眼的正中间应该提供别名/me/head。
如果有一个客制化的追踪系统,并且如果设备有一个接口用来提供控制和状态信息,应该写一个设备插件来提供更多的与OSVR系统的交互,而不是仅仅是一个显示设备。
若需要编写一个插件请参考:http://osvr.github.io/build-with/#building-a-plugin
确认HMD在OSVR上工作正常:
1.可使用OSVR Tracker Viewer(https://github.com/osvr/OSVR-Tracker-Viewer)来验证追踪器是否工作。当移动HMD时,它会通过3个轴显示HMD的位置和方位。
2.可通过运行一个demo App来验证显示描述字段和畸变矫正是否工作良好。demon App参考:https://github.com/sensics/OSVR-RenderManager#example-programs
3.还可通过SteamVR游戏来测试HMD是否工作正常,需要使用到Steam-OSVR driver 参考:https://github.com/osvr/SteamVR-OSVR
发布HMD插件:
为了让新添加的HMD插件被大多数OSVR用户所使用,建议:
1.创建一个简单的安装包来发布插件
2.添加安装包到OSVR插件仓库
3.如果合适,还可以开源插件代码以便社区开发者将它移植到其他平台且优化它。
===========================================================================================