2017-03-24 88 views
2

我想在Android上的Unity中的虛擬現實中播放立體聲360度視頻。到目前爲止,我一直在做一些研究,我有兩個左右眼相機,每個相機都有一個球體。我還需要一個自定義着色器來使圖像在球體內部呈現。我通過將y平鋪設置爲0.5而將圖像的上半部分顯示在一個球體上,而下半部分顯示在y平鋪0.5和y-平移0.5的另一球體上。 有了這個,我可以顯示一個3D 360度圖像已經正確。整個想法是從this tutorial使用VideoPlayer播放360立體視頻

現在對於視頻,我需要控制視頻的速度,所以我需要新的Unity 5.6測試版中的VideoPlayer。現在我的設置到目前爲止需要視頻播放器在兩個球體上播放視頻,一個球體播放上半部分(一隻眼睛),另一個視頻播放下半部分(另一隻眼睛)。

這是我的問題:我不知道如何讓視頻播放器在兩種不同材質上播放相同的視頻(因爲它們有不同的平鋪值)。有沒有辦法做到這一點?

我得到了一個暗示,我可以使用相同的材​​料,並通過紫外線實現拼貼效果,但我不知道這是如何工作,我甚至沒有視頻播放器使用兩個對象播放視頻在他們兩個相同的材料。我有一個截圖of that here。正確的球體只有材質videoMaterial。沒有平鋪,因爲我必須通過UV來做到這一點。

下一步該怎麼做?我在這裏正確的方式嗎?

+0

*「我有兩隻左右眼相機,每隻相機都有一個球體」*這是VR嗎? – Programmer

+0

啊,是的,我應該在某處提及它。到目前爲止,我只提到立體聲。 – findusl

+1

然後標籤vr。它看起來像你想在C#中的解決方案。爲什麼不標記呢?標籤很重要。只是爲你做了。 – Programmer

回答

3

我在正確的路上嗎?

差不多,但你目前正在使用RendererMaterial代替RenderTextureMaterial

下一步該怎麼辦?

您需要爲此使用RenderTexture。基本上,您將視頻渲染到RenderTexture,然後將該紋理分配給兩個球體的材質。

。創建一個RenderTexture並將其分配給VideoPlayer

。爲球體創造兩種材料。

.SET VideoPlayer.renderModeVideoRenderMode.RenderTexture;

.SET兩個球體的紋理的從RenderTexture

。準備的紋理和播放視頻。

下面的代碼正在做這件事情。它應該開箱即用。您需要做的唯一事情就是修改每種材料的平鋪和偏移以滿足您的需求。

你也應該註釋掉:

leftSphere = createSphere("LeftEye", new Vector3(-5f, 0f, 0f), new Vector3(4f, 4f, 4f)); 
rightSphere = createSphere("RightEye", new Vector3(5f, 0f, 0f), new Vector3(4f, 4f, 4f)); 

然後使用來自任何3D應用程序導入一個球體。該行代碼僅用於測試目的,因爲這些領域沒有足夠的細節來使視頻流暢,因此使用Unity的視頻播放視頻並不是一個好主意。

using UnityEngine; 
using UnityEngine.Video; 

public class StereoscopicVideoPlayer : MonoBehaviour 
{ 
    RenderTexture renderTexture; 

    Material leftSphereMat; 
    Material rightSphereMat; 

    public GameObject leftSphere; 
    public GameObject rightSphere; 

    private VideoPlayer videoPlayer; 

    //Audio 
    private AudioSource audioSource; 

    void Start() 
    { 
     //Create Render Texture 
     renderTexture = createRenderTexture(); 

     //Create Left and Right Sphere Materials 
     leftSphereMat = createMaterial(); 
     rightSphereMat = createMaterial(); 

     //Create the Left and Right Sphere Spheres 
     leftSphere = createSphere("LeftEye", new Vector3(-5f, 0f, 0f), new Vector3(4f, 4f, 4f)); 
     rightSphere = createSphere("RightEye", new Vector3(5f, 0f, 0f), new Vector3(4f, 4f, 4f)); 

     //Assign material to the Spheres 
     leftSphere.GetComponent<MeshRenderer>().material = leftSphereMat; 
     rightSphere.GetComponent<MeshRenderer>().material = rightSphereMat; 

     //Add VideoPlayer to the GameObject 
     videoPlayer = gameObject.AddComponent<VideoPlayer>(); 

     //Add AudioSource 
     audioSource = gameObject.AddComponent<AudioSource>(); 

     //Disable Play on Awake for both Video and Audio 
     videoPlayer.playOnAwake = false; 
     audioSource.playOnAwake = false; 

     // We want to play from url 
     videoPlayer.source = VideoSource.Url; 
     videoPlayer.url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"; 

     //Set Audio Output to AudioSource 
     videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource; 

     //Assign the Audio from Video to AudioSource to be played 
     videoPlayer.EnableAudioTrack(0, true); 
     videoPlayer.SetTargetAudioSource(0, audioSource); 

     //Set the mode of output to be RenderTexture 
     videoPlayer.renderMode = VideoRenderMode.RenderTexture; 

     //Set the RenderTexture to store the images to 
     videoPlayer.targetTexture = renderTexture; 

     //Set the Texture of both Spheres to the Texture from the RenderTexture 
     assignTextureToSphere(); 

     //Prepare Video to prevent Buffering 
     videoPlayer.Prepare(); 

     //Subscribe to prepareCompleted event 
     videoPlayer.prepareCompleted += OnVideoPrepared; 
    } 


    RenderTexture createRenderTexture() 
    { 

     RenderTexture rd = new RenderTexture(1024, 1024, 16, RenderTextureFormat.ARGB32); 
     rd.Create(); 
     return rd; 
    } 

    Material createMaterial() 
    { 
     return new Material(Shader.Find("Specular")); 
    } 

    void assignTextureToSphere() 
    { 
     //Set the Texture of both Spheres to the Texture from the RenderTexture 
     leftSphereMat.mainTexture = renderTexture; 
     rightSphereMat.mainTexture = renderTexture; 
    } 

    GameObject createSphere(string name, Vector3 spherePos, Vector3 sphereScale) 
    { 
     GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); 
     sphere.transform.position = spherePos; 
     sphere.transform.localScale = sphereScale; 
     sphere.name = name; 
     return sphere; 
    } 

    void OnVideoPrepared(VideoPlayer source) 
    { 
     Debug.Log("Done Preparing Video"); 

     //Play Video 
     videoPlayer.Play(); 

     //Play Sound 
     audioSource.Play(); 

     //Change Play Speed 
     if (videoPlayer.canSetPlaybackSpeed) 
     { 
      videoPlayer.playbackSpeed = 1f; 
     } 
    } 
} 

還有Unity tutorial關於如何使用特殊的着色器做到這一點,但這並不適合我和其他一些人的工作。我建議你使用上面的方法,直到VR支持被添加到VideoPlayer API。