使用 VideoPlayer 播放 360 立体视频 [英] Play 360 Stereoscopic video with VideoPlayer

查看:73
本文介绍了使用 VideoPlayer 播放 360 立体视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Android 上的 Unity 虚拟现实中播放立体 360 度视频.到目前为止,我一直在做一些研究,我的左右眼有两个摄像头,每个摄像头周围都有一个球体.我还需要一个自定义着色器来在球体内部渲染图像.通过将 y 平铺设置为 0.5,我将图像的上半部分显示在一个球体上,下半部分显示在另一个球体上,y 平铺设置为 0.5,y 偏移量为 0.5.有了这个,我可以显示已经正确的 3D 360 度图像.整个想法来自本教程.

I want to play a stereo 360 degree video in virtual reality in Unity on an Android. So far I have been doing some research and I have two cameras for the right and left eye with each a sphere around them. I also need a custom shader to make the image render on the inside of the sphere. I have the upper half of the image showing on one sphere by setting the y-tiling to 0.5 and the lower half shows on the other sphere with y-tiling 0.5 and y-offset 0.5. With this I can show a 3D 360 degree image already correct. The whole idea is from this tutorial.

现在对于视频,我需要控制视频速度,所以事实证明我需要来自新 Unity 5.6 的 VideoPlayer测试版.现在我的设置到目前为止需要视频播放器在两个球体上播放视频,一个球体播放上半部分(一只眼睛),另一个视频播放下半部分(另一只眼睛).

Now for video, I need control over the Video speed so it turned out I need the VideoPlayer from the new Unity 5.6 beta. Now my setup so far would require the Video Player to play the video on both spheres with one sphere playing the upper part (one eye) and the other video playing the lower part (other eye).

这是我的问题:我不知道如何让视频播放器在两种不同的材料上播放相同的视频(因为它们具有不同的平铺值).有没有办法做到这一点?

Here is my problem: I don't know how to get the video Player to play the same video on two different materials (since they have different tiling values). Is there a way to do that?

我得到了一个提示,我可以使用相同的材​​料并通过 UV 实现平铺效果,但我不知道这是如何工作的,我什至没有让视频播放器使用两者的材料相同.我有一个截图这里.右边的球体只有材质 videoMaterial.没有平铺,因为我必须通过 UV 来做到这一点.

I got a hint that I could use the same material and achieve the tiling effect via UV, but I don't know how that works and I haven't even got the video player to play the video on two objects using the same material on both of them. I have a screenshot of that here. The Right sphere just has the material videoMaterial. No tiling since I'd have to do that via UV.

该走哪条路,怎么做?我来对了吗?

Which way to go and how to do it? Am I on the right way here?

推荐答案

我来对了吗?

几乎,但您目前正在使用 RendererMaterial 而不是 RenderTextureMaterial.

Almost but you are currently using Renderer and Material instead of RenderTexture and Material.

该走哪条路以及如何去做?

Which way to go and how to do it?

为此您需要使用 RenderTexture.基本上,您将视频渲染到 RenderTexture,然后将该纹理分配给两个球体的材质.

You need to use RenderTexture for this. Basically, you render the Video to RenderTexture then you assign that Texture to the material of both Spheres.

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

1.Create a RenderTexture and assign it to the VideoPlayer.

2.为球体创建两种材质.

2.Create two materials for the spheres.

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

4.将两个球体的纹理设置为 RenderTexture

4.Set the Texture of both Spheres to the Texture from the RenderTexture

5.准备和播放视频.

下面的代码正在做这件事.它应该是开箱即用的.您唯一需要做的就是根据您的需要修改每种材料的平铺和偏移.

The code below is doing that exact thing. It should work out of the box. The only thing you need to do is to modify the tiling and offset of each material to your needs.

您还应该注释掉:

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 的球体播放视频不是一个好主意,因为球体没有足够的细节来使视频流畅.

then use a Sphere imported from any 3D application. That line of code is only there for testing purposes and it's not a good idea to play video with Unity's sphere because the spheres don't have enough details to make the video smooth.

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.

There is also Unity tutorial on how to do this with a special shader but this does not work for me and some other people. I suggest you use the method above until VR support is added to the VideoPlayer API.

这篇关于使用 VideoPlayer 播放 360 立体视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆