Search Unity

Alternative to MovieTexture on iOS

Discussion in 'iOS and tvOS' started by cr0ybot, Jun 23, 2011.

  1. cr0ybot

    cr0ybot

    Joined:
    Apr 29, 2011
    Posts:
    7
    The lack of support for MovieTexture on iOS is really frustrating, but, as I understand from some posts in this forum by Prime31, there's a bug from Apple preventing this feature.

    So I'm looking for suggestions about alternative ways to create an animated texture on iOS.

    I made a prototype in Flash that shows the Earth morphing (continents moving and changing shape) over several millennia to the present day, using a movie texture on a sphere. The user can manipulate a slider to go to different periods of the Earth's past. The prototype looks great, but I need to be able to create something similar in Unity3D for the iPad.

    Obviously I'm not going to be able to get even close to that in Unity right now, but I'm having trouble finding any other viable methods for showing this type of content.

    I've had a few ideas, but I haven't tested anything yet. I'm wondering if someone else has figured out a way to do this before I waste my time trying things that won't work. I thought about creating some material that would let me swap out 2 textures that could be blended, a la this thread, or maybe find a way to use a sprite animation technique, where the frames are on a large texture and the UV coordinates are offset (the problem here being that the texture would have to be quite large...). Other than that, I haven't run into any other "solutions".

    I know that the "iOS doesn't support MovieTextures" has been discussed to death, but I'd like to have a positive conversation about other possibilities. ;)
     
    Last edited: Jun 23, 2011
  2. cr0ybot

    cr0ybot

    Joined:
    Apr 29, 2011
    Posts:
    7
    Well, for now I've come up with my own solution, if anyone is interested. I did use the blend shader from here, and I have a system set up with a slider to blend between textures and swap them out as needed.

    I've only tested this with 13 texture "frames" so far, but it runs at a solid 60fps on my iPad, regardless of how fast I scrub.

    Blend Shader:
    Code (csharp):
    1. Shader "Blend" {
    2.     Properties {
    3.         _Blend ("Blend", Range (0, 1)) = 0.5
    4.         _MainTex ("Base (RGB)", 2D) = "white"
    5.         _BlendTex ("Blend (RGB)", 2D) = "black"
    6.     }
    7.     SubShader {
    8.         Pass {
    9.             SetTexture [_MainTex]
    10.            
    11.             SetTexture [_BlendTex] {
    12.                 constantColor (0, 0, 0, [_Blend])
    13.                 combine texture lerp (constant) previous
    14.             }
    15.         }
    16.     }
    17. }

    BlendManager Class:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BlendManager : MonoBehaviour {
    5.    
    6.     public Texture2D[] blendTextures;
    7.    
    8.     public GameObject BlendObject;
    9.    
    10.     private Rect sliderRect;
    11.     private float sliderValue = 0.0f;
    12.     private float lastSliderValue = 0.0f;
    13.     private int textureIndex = 0;
    14.     private int textureIndexMax;
    15.    
    16.     void Start() {
    17.        
    18.         sliderRect = new Rect( 100, Screen.height - 75, Screen.width - 200, 50 );
    19.        
    20.         if ( blendTextures.Length < 2 ) {
    21.            
    22.             throw new System.ArgumentException( "blendTextures must contain more than 1 texture" );
    23.            
    24.         } else {
    25.            
    26.             BlendObject.renderer.material.SetTexture( "_MainTex", blendTextures[0] );
    27.             BlendObject.renderer.material.SetTexture( "_BlendTex", blendTextures[1] );
    28.            
    29.             textureIndexMax = blendTextures.Length - 2;
    30.            
    31.         }
    32.        
    33.     }
    34.    
    35.     void Update() {
    36.        
    37.         if ( sliderValue != lastSliderValue ) {
    38.            
    39.             float blendValue = sliderValue - (int)sliderValue;
    40.            
    41.             if ( textureIndex != (int)sliderValue ) {
    42.                
    43.                 textureIndex = (int)sliderValue;
    44.                
    45.                 if ( textureIndex > textureIndexMax ) {
    46.                     textureIndex = textureIndexMax;
    47.                     blendValue = 1.0f;
    48.                 }
    49.                
    50.                 BlendObject.renderer.material.SetTexture( "_MainTex", blendTextures[textureIndex] );
    51.                 BlendObject.renderer.material.SetTexture( "_BlendTex", blendTextures[textureIndex + 1] );
    52.                
    53.             }
    54.            
    55.             BlendObject.renderer.material.SetFloat( "_Blend", blendValue );
    56.            
    57.             lastSliderValue = sliderValue;
    58.            
    59.         }
    60.        
    61.     }
    62.    
    63.     void OnGUI() {
    64.        
    65.         sliderValue = GUI.HorizontalSlider( sliderRect, sliderValue, 0.0f, textureIndexMax + 1 );
    66.        
    67.     }
    68. }
     
    Last edited: Jun 23, 2011
  3. RalphFW

    RalphFW

    Joined:
    May 7, 2011
    Posts:
    18
    Why not use the same technique Prime31's AR plug-in does but instead of putting video output from the AVCaptureSession into GL texture, put the output of video playback? Could be a good idea for a new Prime31 plug-in!