c# - tour - Reproduzca video estereoscópico 360 con VideoPlayer
video 360 vr unity (1)
Quiero reproducir un video estéreo de 360 grados en realidad virtual en Unity en un Android. Hasta ahora he estado investigando y tengo dos cámaras para el ojo derecho y el izquierdo con cada una una esfera a su alrededor. También necesito un sombreador personalizado para hacer que la imagen se renderice en el interior de la esfera. Tengo la mitad superior de la imagen que muestra en una esfera estableciendo y-tiling en 0.5 y la mitad inferior en la otra esfera con y-tiling 0.5 y y-offset 0.5. Con esto puedo mostrar una imagen 3D de 360 grados ya correcta . La idea general es de este tutorial .
Ahora, para video, necesito control sobre la velocidad del video, así que resultó que necesito el VideoPlayer de la nueva versión de Unity 5.6 beta. Ahora mi configuración hasta ahora requeriría que el reproductor de video reproduzca el video en ambas esferas con una esfera tocando la parte superior (un ojo) y el otro video tocando la parte inferior (otro ojo).
Este es mi problema : no sé cómo hacer que el reproductor de video reproduzca el mismo video en dos materiales diferentes (ya que tienen diferentes valores de mosaico). ¿Hay una manera de hacer eso?
Tengo una pista de que podría usar el mismo material y lograr el efecto de mosaico mediante UV, pero no sé cómo funciona eso y ni siquiera tengo el reproductor de video para reproducir el video en dos objetos usando el mismo material en ambos. Tengo una captura de pantalla de eso aquí . La esfera derecha solo tiene el material videoMaterial. Sin mosaicos ya que tendría que hacer eso a través de UV.
¿Qué camino seguir y cómo hacerlo? ¿Estoy en el camino correcto aquí?
¿Estoy en el camino correcto aquí?
Casi, pero actualmente estás usando Renderer
y Material
lugar de RenderTexture
y Material
.
¿Qué camino seguir y cómo hacerlo?
Necesitas usar RenderTexture
para esto. Básicamente, renderizas el Video para RenderTexture
luego asignas esa Textura al material de ambas Esferas.
1. RenderTexture
una RenderTexture
y RenderTexture
al VideoPlayer
.
2. Crear dos materiales para las esferas.
3. Establezca VideoPlayer.renderMode
en VideoRenderMode.RenderTexture;
4. Establezca la textura de ambas esferas en la textura de RenderTexture
5. Prepare y reproduzca el video.
El siguiente código está haciendo exactamente eso. Debería funcionar de la caja. Lo único que debe hacer es modificar el mosaico y el desplazamiento de cada material según sus necesidades.
También deberías comentar:
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));
luego use una Esfera importada de cualquier aplicación 3D. Esa línea de código solo está ahí para realizar pruebas y no es una buena idea reproducir videos con la esfera de Unity porque las esferas no tienen suficientes detalles para que el video sea fluido.
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;
}
}
}
También hay un tutorial de Unity sobre cómo hacer esto con un sombreador especial, pero esto no funciona para mí y algunas otras personas. Le sugiero que use el método anterior hasta que se agregue compatibilidad VR a la API de VideoPlayer
.