Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity 5.0 Shader (Assigning MovieTexture in Emission Map Slot Problem)

Discussion in 'Shaders' started by Matthew Scott, Mar 11, 2015.

  1. Matthew Scott

    Matthew Scott

    Joined:
    Jan 16, 2013
    Posts:
    33
    Hey Guys,

    I've been updating my current project to Unity 5.0 but I'm having some issues with a simple television screen that is programmed to cycle through channels with a key press.

    The shader produces a warning inside the GUI when I assign a movie texture into the _EmissionMap slot via code.

    It states the following:

    "Emission value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive."

    Interestingly enough...if I change the texture slot using "material" (creates a new instance) rather than "sharedMaterial", the emission map changes but doesn't show in game right away. I press the key to load the first movie texture into the emission map slot but then I have to click on the new instanced material in the GUI to make it update/show in the game. From then on I can continue to cycle through other channels and it loads the movie textures into the slots just fine.

    Is there something I'm missing here? Surely there is support for emission map's containing movie textures because it works just fine if I assign in the inspector and just hit play. But I need to able to cycle/change the movies during game play.

    Just for reference, here is the code attached to the television screen.

    Code (JavaScript):
    1. #pragma strict
    2.  
    3. //EDITOR SETTINGS
    4. enum Channel         { Off = 0, Static = 1, Weather = 2, Test = 3 }
    5. var staticChannel     : MovieTexture;
    6. var staticAudio     : AudioClip;
    7. var weatherChannel     : MovieTexture;
    8. var weatherAudio     : AudioClip;
    9. var testChannel     : MovieTexture;
    10. var testAudio         : AudioClip;
    11.  
    12. //SCRIPT SETTINGS
    13. var channel : Channel = Channel.Off;
    14. var lastChannel : Channel;
    15. var numberofChannels = System.Enum.GetValues(Channel).Length;
    16. var rend : Renderer;
    17.  
    18. function Awake(){
    19.     rend = GetComponent.<Renderer>();
    20. }
    21.  
    22. function Update(){
    23.     if(Input.GetKeyDown(KeyCode.E)){
    24.         channel += 1;
    25.         if(channel == numberofChannels){
    26.             channel = 0;
    27.         }
    28.     }
    29.     if(channel != lastChannel){
    30.         ChangeChannel();
    31.     }
    32. }
    33.  
    34. function ChangeChannel(){
    35.     switch (channel){
    36.         case Channel.Off:
    37.             rend.sharedMaterial.SetTexture("_EmissionMap", null);
    38.             rend.sharedMaterial.SetColor("_EmissionColor", new Color(0.0,0.0,0.0,0.0));
    39.             break;
    40.         case Channel.Static:
    41.             rend.sharedMaterial.SetTexture("_EmissionMap", staticChannel);
    42.             rend.sharedMaterial.SetColor("_EmissionColor", new Color(1.0,1.0,1.0,1.0));
    43.             staticChannel.Play();
    44.             staticChannel.loop = true;
    45.             break;
    46.         case Channel.Weather:
    47.             rend.sharedMaterial.SetTexture("_EmissionMap", weatherChannel);
    48.             rend.sharedMaterial.SetColor("_EmissionColor", new Color(1.0,1.0,1.0,1.0));
    49.             weatherChannel.Play();
    50.             weatherChannel.loop = true;
    51.             break;
    52.         case Channel.Test:
    53.             rend.sharedMaterial.SetTexture("_EmissionMap", testChannel);
    54.             rend.sharedMaterial.SetColor("_EmissionColor", new Color(1.0,1.0,1.0,1.0));
    55.             testChannel.Play();
    56.             testChannel.loop = true;
    57.             break;
    58.         default:
    59.             Debug.LogWarning("A switch case was not recognised");
    60.             break;
    61.     }
    62.     lastChannel = channel;
    63. }
     
  2. Matthew Scott

    Matthew Scott

    Joined:
    Jan 16, 2013
    Posts:
    33
    Having further investigated the issue, I've isolated the problem to the SetColor Code lines. Having commented them out, the texture is set correctly, changes with no problems.

    It's only when I try to change the emissive color value that the shaders prompts that warning inside the GUI and it ceases to work. I need to be able to modify this value so that when the emission slot is null (The TV is OFF) the albedo texture isn't glowing bright white.

    Am I assigning the color incorrectly?
     
  3. kilogold

    kilogold

    Joined:
    May 28, 2013
    Posts:
    9
  4. kilogold

    kilogold

    Joined:
    May 28, 2013
    Posts:
    9
    Still here. Wondering if anyone knows anything?
     
  5. amjcrawford

    amjcrawford

    Joined:
    Aug 17, 2012
    Posts:
    4
    BUMPing this ~ has anyone determined whether or not Unity can do realtime emissive video textures yet ?

    looks like UE4 can now with VXGI:
     
  6. Mad-Monkey-Art

    Mad-Monkey-Art

    Joined:
    Oct 22, 2014
    Posts:
    7
    In case anyone is still looking for this, we have been looking into this this afternoon. Ended up being pretty simple to achieve. We've attached the movie texture to both the Albedo and the Emission slots. In Start let the movie play (and loop, if you want) and then in Update call for UpdateMaterials and it works pretty well.

    And if you desire to be able to switch between movies, you can assign a new movie texture and play it when you press a key.

    For just the one object, performance was good with UpdateMaterials being called each frame. But we haven't tested with multiple movie textures at once on different objects.



    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class playMovie : MonoBehaviour {
    6.  
    7.     public MovieTexture newMovie;
    8.     private Renderer renderer;
    9.  
    10.     void Start () {
    11.         renderer = GetComponent<Renderer>();
    12.         ((MovieTexture)renderer.material.mainTexture).Play();
    13.         ((MovieTexture)renderer.material.mainTexture).loop = true;
    14.     }
    15.  
    16.     void Update (){
    17.         DynamicGI.UpdateMaterials(renderer);
    18.  
    19.         if (Input.GetKeyDown (KeyCode.U))
    20.         {
    21.             renderer.material.SetTexture("_MainTex", newMovie);
    22.             renderer.material.SetTexture("_EmissionMap", newMovie);
    23.             ((MovieTexture)renderer.material.mainTexture).Play();
    24.             ((MovieTexture)renderer.material.mainTexture).loop = true;
    25.         }
    26.     }
    27. }
    28.  
     
    Last edited: Jun 19, 2016
  7. nbac

    nbac

    Joined:
    Jul 7, 2015
    Posts:
    267
    hi

    this script gives me

    Warning CS0108: 'playMovie.renderer' hides inherited member 'UnityEngine.Component.renderer'. Use the new keyword if hiding was intended. (CS0108) (Assembly-CSharp)

    what does cause this
     
  8. Mad-Monkey-Art

    Mad-Monkey-Art

    Joined:
    Oct 22, 2014
    Posts:
    7
    Yeah somewhere along the last couple of updates the MovieTexture got deprecated. We're now using the new Video Player to get the same effect. Import your movie as a 'VideoClip' instead of the old 'MovieTexture'. Then add the 'Video Player' component to the surface, put you imported movie in the 'Video Clip' slot and select '_EmissionMap' as the 'Material Property'. This component now play's the video for you, but we still have to make the GI refresh to get the effect on the walls etc.

    You'll have to enable realtime GI for your object and make it static. Then tell the renderer to pass Emission data trough to the GI system. We can still use UpdateGIMaterials() in an Update for this, but we noticed that updating the GI every frame caused some framerate issues. The script below will refresh the GI 10 times a second, independent of your framerate:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class moviePlayerGI : MonoBehaviour {
    5.  
    6.     Renderer renderer;
    7.  
    8.     void Start () {
    9.         renderer = GetComponent<Renderer>();
    10.         InvokeRepeating("UpdateGI", 0, 0.1F);
    11.     }
    12.  
    13.     void UpdateGI (){
    14.         RendererExtensions.UpdateGIMaterials(renderer);
    15.     }
    16. }
     
  9. nbac

    nbac

    Joined:
    Jul 7, 2015
    Posts:
    267
    thank you very much! i got it to run now, before i saw your answer, but as you did i have fps problems now! i will try it this way!
     
  10. nbac

    nbac

    Joined:
    Jul 7, 2015
    Posts:
    267
    this new video player component is a 5.6 feature. it is much faster even without

    Code (CSharp):
    1. InvokeRepeating("UpdateGI", 0, 0.1F);
    since i have a pause play in my update.

    anyway i cant get any audio from my videos.

    this is maybe why?

    this is my code

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayVideo : MonoBehaviour {
    5.  
    6.     private Renderer render;
    7.     int vsyncprevious;
    8.  
    9.     void Start () {
    10.         render = GetComponent<Renderer>();
    11.         vsyncprevious = QualitySettings.vSyncCount;
    12.         QualitySettings.vSyncCount = 0;
    13.         }
    14.  
    15.     void Update(){
    16.         RendererExtensions.UpdateGIMaterials(render);
    17.         QualitySettings.vSyncCount = vsyncprevious;
    18.         var videoPlayer = GetComponent<UnityEngine.Video.VideoPlayer> ();
    19.  
    20.         if (Input.GetKeyDown (KeyCode.Space)) {
    21.  
    22.             if (videoPlayer.isPlaying) {
    23.                 videoPlayer.Pause();
    24.             }
    25.             else {
    26.                 videoPlayer.Play();
    27.             }
    28.         }  
    29.     }
    30. }
     
  11. nbac

    nbac

    Joined:
    Jul 7, 2015
    Posts:
    267
    sorry for the dump questions i am not a coder ...
    i did not understand the concept of unitys audio sources as well
    now i have sorted everything out.
     
  12. Crignog

    Crignog

    Joined:
    Oct 5, 2016
    Posts:
    6
    I'm trying to get the emissive map to work, but I can't. I'm using 5.6 and if I change the Material Property to _emissionMap then there is no visible video anymore (although audio still plays). I tried adding another VideoPlayer component that was set with the emission map but that didn't work either. Any thoughts? :S
     
  13. Crignog

    Crignog

    Joined:
    Oct 5, 2016
    Posts:
    6
    When I've tried to do as you've said the video doesn't show when I run the game. It's just blank but with audio :/
     
  14. Mad-Monkey-Art

    Mad-Monkey-Art

    Joined:
    Oct 22, 2014
    Posts:
    7
    Is Autoplay turned on? And also make sure that the material that's assigned to the video object has 'Emission' turned on also. If not, the video component does assign the video to the emission slot, but has no intensity so you'll not be able to see it.
     
  15. Crignog

    Crignog

    Joined:
    Oct 5, 2016
    Posts:
    6
    Sorry for such a late reply, thank you so so much! The shader applied to the video component didn't have emission turned on :L Thanks again :)
     
    Mad-Monkey-Art likes this.
  16. franck_7L

    franck_7L

    Joined:
    Dec 16, 2015
    Posts:
    1
    Please Mad-Monkey-Art, how do you setup unity and/or the surfaces/materials in front of the tv, such as it's able to catch light ?
     
  17. Gavert

    Gavert

    Joined:
    Jan 31, 2017
    Posts:
    12