在VR應用中,有一個相對簡單的虛擬現實體驗,那就是360°全景照片瀏覽器, 他可使得手機拍照的」全景」照片, 得以」恢復」當時拍照的場景全貌, 這個創意的確比單純的2d圖片更有震撼力一些,故本文就製做360全景照片的過程進行簡單小結。git
能夠經過手機的陀螺儀,在魔鏡中查看360°圖片;不用依賴任何藍牙輸入,僅經過Gaze Input進行選擇下一張360°圖片(盯着縮放圖2s,進度條旋轉完成後,就切換圖片;用Gear VR的磁鐵觸發功能也能夠實現選擇下一張圖片)。程序員
硬件:暴風魔鏡4 + 小米Note頂配版(2K屏幕)github
SDK:魔鏡手柄、反畸變SDK_Unity版,或者 Google cardboard-unity,本文使用的是Googe CardBoard瀏覽器
360°照片,展開看就是一個投影的2D照片,這個在初中學習世界地理的時候將相似投影球形地圖到2維平面上,原理相似,只不過一個360°照片的投影失真會小不少. 網絡
爲了復原,須要創建一個3D Object\Sphere, 咱們經過把圖片貼到這個球體上,從內側看效果。 而後拖放照片到Sphere上,球體放大10倍; 這個時候,發現一個問題在Game視圖中看不到東西了,由於Camera沒有在球心位置,修改Camera座標爲(0,0,0)位於球心。app
咱們依然看不到圖片,由於Spere默認用的是Unlit/Transparent Shade,他爲了渲染高效,把背面給剔除了,而在這裏,咱們洽洽須要渲染背面,故得重新寫個shade–關閉cull off。ide
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
}this//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設備上
先禁用掉默認的MainCamera、light。
而後添加VR攝像機—導入Google的CardboardSDKForUnity.unitypackage後,拖入CardboardMain.prefab到場景中。 這時候點擊Play啓動UnityEditor,便可看到雙VR Camera的效果,點擊調試快捷鍵:Alt + 移動鼠標,便可看到模擬的陀螺儀效果。
這個時候打包爲apk,安裝到手機,用真機的陀螺儀體驗,效果更酷。
完成《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°照片中的大樹、地板吧。