2017-03-24 68 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。