Unity3D for VR 学习(7): 360°全景照片
2016-04-07 18:50
711 查看
在VR应用中,有一个相对简单的虚拟现实体验,那就是360°全景照片浏览器, 他可以使得手机拍照的”全景”照片, 得以”恢复”当时拍照的场景全貌, 这个创意的确比单纯的2d图片更有震撼力一些,故本文就制作360全景照片的过程进行简单小结。
SDK:魔镜手柄、反畸变SDK_Unity版,或者 Google cardboard-unity,本文使用的是Googe CardBoard
为了复原,需要建立一个3D Object\Sphere, 我们通过把图片贴到这个球体上,从内侧看效果。 然后拖放照片到Sphere上,球体放大10倍; 这个时候,发现一个问题在Game视图中看不到东西了,因为Camera没有在球心位置,修改Camera坐标为(0,0,0)位于球心。
我们依然看不到图片,因为Spere默认用的是Unlit/Transparent Shade,他为了渲染高效,把背面给剔除了,而在这里,我们洽洽需要渲染背面,故得从新写个shade–关闭cull off。
DoubleSided.Shader文件
Shader "Unlit/DoubleSided"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
//Ambient pass
Pass
{
Name "BASE"
Tags {"LightMode" = "Always" /* Upgrade NOTE: changed from PixelOrNone to Always */}
Color[_PPLAmbient]
SetTexture[_BumpMap]
{
constantColor(.5,.5,.5)
combine constant lerp(texture) previous
}
SetTexture[_MainTex]
{
constantColor[_Color]
Combine texture * previous DOUBLE, texture *constant
}
}
//Vertex lights
Pass{
Name "BASE"
Tags {"LightMode" = "Vertex"}
Material
{
Diffuse[_Color]
Emission[_PPLAmbient]
Shininess[_Shininess]
Specular[_SpecColor]
}
SeparateSpecular On
Lighting On
cull off
SetTexture[_BumpMap]
{
constantColor(.5,.5,.5)
combine constant lerp(texture) previous
}
SetTexture[_MainTex]
{
Combine texture *previous DOUBLE, texture *primary
}
}
}
FallBack "Diffuse", 1
}
替换了新的Shade后,效果好了很多了,唯一有问题的是我们看到的照片是反的,故修改Spere的.Z为-10.
通过在Unity.Editor上Play效果,已经很不错了,至此完成了大部分的工作,下面开始”移植”到VR设备上
然后添加VR摄像机—导入Google的CardboardSDKForUnity.unitypackage后,拖入CardboardMain.prefab到场景中。 这时候点击Play启动UnityEditor,即可看到双VR Camera的效果,点击调试快捷键:Alt + 移动鼠标,即可看到模拟的陀螺仪效果。
这个时候打包为apk,安装到手机,用真机的陀螺仪体验,效果更酷。
这里,我们添加4个Plane,通过上面章节的《Unity3D for VR 学习(5): VR Gaze Input》,期望可以实现通过Gaze一个Plane 3s,然后能够切换新的照片功能。
添加Plane,坐标修改如下:
添加一个脚本,实现响应EventSystem,可通过2种办法
方法1: 添加Event Trigger脚本,响应PointerEnter、PointerExit等方法,如图
方法2:脚本直接继承IPointerDownHandler、IPointerExitHandler等接口,这个看起来更符合程序员胃口
我们通过控制Plan的Color.a来实现高亮选择,代码如下
public void SetGazeAt(bool gazeAt)
{
Debug.Log("SetGazeAt: " + gazeAt);
Renderer render = this.GetComponent<Renderer>();
Color cor = render.material.color;
cor.a = gazeAt ? 1f : 0.5f;
render.material.color = cor;
}
另外,当Gaze 2s后,会动态替换material的Texture来实现替换360°照片,代码如下
public void OnClick()
{
Renderer renderSrc = this.GetComponent<Renderer>();
Renderer renderDst = pano.GetComponent<Renderer>();
Texture tex = renderSrc.materials[0].GetTexture("_MainTex");
renderDst.materials[0].SetTexture("_MainTex", tex);
}
备注:
360°全景照片,非常大,有好几M,这个对手机app来说会造成文件太大,实际商用中,需要采用AB(AssetBundle)实现动态从网络侧更新360图片,那样会更酷一些(轻量级)。
本文用到的完整的 demo Git地址: Git.OSChina.net
昨天网上一个朋友问了一个VR问题:
可否像3D Max那样,动态替换材质,如替换房间地板材质,实现全景照片替换?
回答:不行,只能动态替换整个的全景照片;我昨晚细细思索,好像还是不行,除非建立3D模型,采用动态换装才能实现动态换360°照片中的大树、地板吧。
转载请注明转自《Unity3D for VR 学习(7): 360°全景照片》
Step 1:预期需求
可以通过手机的陀螺仪,在魔镜中查看360°图片;不用依赖任何蓝牙输入,仅通过Gaze Input进行选择下一张360°图片(盯着缩放图2s,进度条旋转完成后,就切换图片;用Gear VR的磁铁触发功能也可以实现选择下一张图片)。Step 2: 准备材料
硬件:暴风魔镜4 + 小米Note顶配版(2K屏幕)SDK:魔镜手柄、反畸变SDK_Unity版,或者 Google cardboard-unity,本文使用的是Googe CardBoard
Step 3: 创建材质球
360°照片,展开看就是一个投影的2D照片,这个在初中学习世界地理的时候将类似投影球形地图到2维平面上,原理类似,只不过一个360°照片的投影失真会小很多.为了复原,需要建立一个3D Object\Sphere, 我们通过把图片贴到这个球体上,从内侧看效果。 然后拖放照片到Sphere上,球体放大10倍; 这个时候,发现一个问题在Game视图中看不到东西了,因为Camera没有在球心位置,修改Camera坐标为(0,0,0)位于球心。
我们依然看不到图片,因为Spere默认用的是Unlit/Transparent Shade,他为了渲染高效,把背面给剔除了,而在这里,我们洽洽需要渲染背面,故得从新写个shade–关闭cull off。
DoubleSided.Shader文件
Shader "Unlit/DoubleSided"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
//Ambient pass
Pass
{
Name "BASE"
Tags {"LightMode" = "Always" /* Upgrade NOTE: changed from PixelOrNone to Always */}
Color[_PPLAmbient]
SetTexture[_BumpMap]
{
constantColor(.5,.5,.5)
combine constant lerp(texture) previous
}
SetTexture[_MainTex]
{
constantColor[_Color]
Combine texture * previous DOUBLE, texture *constant
}
}
//Vertex lights
Pass{
Name "BASE"
Tags {"LightMode" = "Vertex"}
Material
{
Diffuse[_Color]
Emission[_PPLAmbient]
Shininess[_Shininess]
Specular[_SpecColor]
}
SeparateSpecular On
Lighting On
cull off
SetTexture[_BumpMap]
{
constantColor(.5,.5,.5)
combine constant lerp(texture) previous
}
SetTexture[_MainTex]
{
Combine texture *previous DOUBLE, texture *primary
}
}
}
FallBack "Diffuse", 1
}
替换了新的Shade后,效果好了很多了,唯一有问题的是我们看到的照片是反的,故修改Spere的.Z为-10.
通过在Unity.Editor上Play效果,已经很不错了,至此完成了大部分的工作,下面开始”移植”到VR设备上
Step 4: 添加VR Camera
先禁用掉默认的MainCamera、light。然后添加VR摄像机—导入Google的CardboardSDKForUnity.unitypackage后,拖入CardboardMain.prefab到场景中。 这时候点击Play启动UnityEditor,即可看到双VR Camera的效果,点击调试快捷键:Alt + 移动鼠标,即可看到模拟的陀螺仪效果。
这个时候打包为apk,安装到手机,用真机的陀螺仪体验,效果更酷。
Step 5: 添加Gaze-and-Tap 用户界面
完成《Step 4: 添加VR Camera》后,实际上已经完成了360°全景照片功能,但是这个仅仅是一个demo,有一个致命的痛点:只有1张照片,如果我有4张照片,每次独立打包为一个apk,这显然不合理。 故需要做一些VR交互。这里,我们添加4个Plane,通过上面章节的《Unity3D for VR 学习(5): VR Gaze Input》,期望可以实现通过Gaze一个Plane 3s,然后能够切换新的照片功能。
添加Plane,坐标修改如下:
添加一个脚本,实现响应EventSystem,可通过2种办法
方法1: 添加Event Trigger脚本,响应PointerEnter、PointerExit等方法,如图
方法2:脚本直接继承IPointerDownHandler、IPointerExitHandler等接口,这个看起来更符合程序员胃口
我们通过控制Plan的Color.a来实现高亮选择,代码如下
public void SetGazeAt(bool gazeAt)
{
Debug.Log("SetGazeAt: " + gazeAt);
Renderer render = this.GetComponent<Renderer>();
Color cor = render.material.color;
cor.a = gazeAt ? 1f : 0.5f;
render.material.color = cor;
}
另外,当Gaze 2s后,会动态替换material的Texture来实现替换360°照片,代码如下
public void OnClick()
{
Renderer renderSrc = this.GetComponent<Renderer>();
Renderer renderDst = pano.GetComponent<Renderer>();
Texture tex = renderSrc.materials[0].GetTexture("_MainTex");
renderDst.materials[0].SetTexture("_MainTex", tex);
}
备注:
360°全景照片,非常大,有好几M,这个对手机app来说会造成文件太大,实际商用中,需要采用AB(AssetBundle)实现动态从网络侧更新360图片,那样会更酷一些(轻量级)。
本文用到的完整的 demo Git地址: Git.OSChina.net
昨天网上一个朋友问了一个VR问题:
可否像3D Max那样,动态替换材质,如替换房间地板材质,实现全景照片替换?
回答:不行,只能动态替换整个的全景照片;我昨晚细细思索,好像还是不行,除非建立3D模型,采用动态换装才能实现动态换360°照片中的大树、地板吧。
转载请注明转自《Unity3D for VR 学习(7): 360°全景照片》
相关文章推荐
- Unity3D for VR 学习(6): 再次温故知新-3D数学
- Unity3D for VR 学习(4): 自绘摄像机的视口区域锥体
- Unity3D for VR 学习(3): 暴风魔镜PC Input小改造–自己动手、丰衣足食
- Unity3D for VR 学习(2): 暴风魔镜框架探索
- Unity3D for VR 学习(1): 又一个新玩具 暴风魔镜 4(Android)
- [Unity游戏开发]向量在游戏开发中的应用(三)
- Unity3D shader 人物被选中光环/技能范围光环
- 3dsMax导入Unity3d要注意的问题
- unity3d创建材质时,无法添加材质贴图的解决方法
- Unity后期处理-抗锯齿
- Unity Drawcall 优化
- 【unity小技巧之三】添加自定义拓展,动态向某个类注入静态函数
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- unity中使用usafe代码的设置
- [置顶] Unity开发规范(个人习惯,仅供参考)
- 使用Unity5.1进行VR开发的配置(最新的未必是最好的!!!)
- Unity脚本获取内存和FPS
- Unity脚本获取内存和FPS
- Unity3d 读写文本
- unity3d动画帧事件回调脚本必须直接挂在模型上