使用VideoPlayer播放360度立体视频

3
我希望在Android上的Unity虚拟现实中播放立体360度视频。到目前为止,我已经做了一些研究,并且有两个摄像头,分别对应左右眼,每个摄像头周围都有一个球体。我还需要一个自定义着色器来使图像在球体内部渲染。通过将y-tiling设置为0.5,我可以在一个球体上显示图像的上半部分,在另一个球体上显示图像的下半部分,其中y-tiling为0.5,y-offset为0.5。这样我就可以正确地显示3D 360度图像。整个想法来自于this tutorial
现在对于视频,我需要控制视频速度,所以结果我需要新版Unity 5.6 beta中的VideoPlayer。到目前为止,我的设置需要Video Player在两个球体上播放视频,其中一个球体播放视频的上部分(一个眼睛),另一个球体播放视频的下部分(另一个眼睛)。 这是我的问题:我不知道如何让视频播放器在两个不同的材质上播放相同的视频(因为它们具有不同的平铺值)。有没有办法做到这一点?
我得到了一个提示,可以使用相同的材质,并通过UV实现平铺效果,但我不知道如何操作,甚至还没有使用相同的材质在两个对象上播放视频。我在这里截图。右边的球只有材质videoMaterial。由于需要通过UV进行平铺,因此没有平铺。
哪种方法更好,如何操作?我走对了吗?

"我有两个相机,一个在右眼,一个在左眼,每个相机周围都有一个球形。" 这是为了虚拟现实吗? - Programmer
1
那就打上vr标签吧。看起来你想要C#的解决方案,为什么不也打上这个标签呢?标签很重要。我已经帮你打上了。 - Programmer
感谢添加VR标签。我不需要C#的解决方案。如果有人说我需要用另一种语言来做,我会尝试的 :) - findusl
:D 我以前没有使用过Unityscript,但我以前使用过Boo,因为我在那方面有答案。而且你回答得这么详细,我可能不会有问题:3 非常感谢。我很快就会测试你的解决方案。可悲的是,新的VideoPlayer支持Android平台非常有限(至少在我的手机上无法运行),由于头部跟踪,我不能使用模拟器,除非删除Google库... 所以我必须等到下一天再次得到朋友的手机。 - findusl
1
Boo已经在Unity中停用,但我会尽力为其提供解决方案。这是一种非常棒的语言。VideoPlayer仍然很新,处于beta阶段,并且仍然无法在某些Android设备上工作。Unity已经意识到了这个问题,并正在努力解决。请放心慢慢来。 - Programmer
显示剩余2条评论
1个回答

4
我看你差不多了,但是你目前正在使用的是`Renderer`和`Material`,而不是`RenderTexture`和`Material`。

你需要使用`RenderTexture`。基本上,你需要先将视频渲染到`RenderTexture`中,然后将该纹理分配给两个球体的材质。

1.创建一个`RenderTexture`并将其分配给`VideoPlayer`。

2.为球体创建两个材质。

3.将`VideoPlayer.renderMode`设置为`VideoRenderMode.RenderTexture;`。

4.将两个球体的纹理设置为来自`RenderTexture`的纹理。

5.准备并播放视频。

下面的代码就是在做这件事情。它应该可以直接使用。你唯一需要做的事情就是根据你的需求修改每个材质的平铺和偏移。

你也应该注释掉:

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教程,介绍如何使用特殊着色器来实现此功能,但这对我和其他一些人不起作用。我建议您使用上述方法,直到VR支持被添加到VideoPlayer API中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接