Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Dynamic Emission in Real Time GI?

Discussion in 'Unity 5 Pre-order Beta' started by Gokcan, Jan 26, 2015.

  1. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    Hello all
    I am working on b21. It is written in unity manual(Global Illumunation Quickstart) that "currently using the Universal shader doesn’t allow to switch to dynamic emission. To try it out you can use surface shaders with legacy deferred rendering path."

    My first question is it will be supported in unity 5.0 final release? What prevents unity team to support standart shader for Dynamic Emission?

    Secondly, Since I cannot use standart shader, I have written my own shader for dynamic emission. It was working on b20, but somethings are wrong with b21 and it is not working. My shader is:

    Shader "SimgeSimulation/Self-Illumin/Cutout/Diffuse" {
    Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    _Illum ("Illumin (A)", 2D) = "white" {}
    _EmissionLM ("Emission (Lightmapper)", Float) = 0
    [Toggle] _DynamicEmissionLM ("Dynamic Emission (Lightmapper)", Int) = 0
    }

    SubShader {
    Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    LOD 200

    CGPROGRAM
    #pragma surface surf Lambert alphatest:_Cutoff

    sampler2D _MainTex;
    sampler2D _Illum;
    fixed4 _Color;

    struct Input {
    float2 uv_MainTex;
    float2 uv_Illum;
    };

    void surf (Input IN, inout SurfaceOutput o) {
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Emission = c.rgb * tex2D(_Illum, IN.uv_Illum).a;
    o.Alpha = c.a;
    }
    ENDCG
    }

    Fallback "Transparent/Cutout/VertexLit"
    }
     
  2. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
  3. KEngelstoft

    KEngelstoft

    Unity Technologies

    Joined:
    Aug 13, 2013
    Posts:
    1,366
    The Global Illumination Quickstart is outdated, we are working on updating it.

    The Standard shader does allow for realtime emission already :)

    It does so using the new meta shader pass that is responsible for generating albedo and emissive for Enlighten. Have a look in the standard shader source if you want to see how it is done. The self-illuminating legacy shaders have also been updated to use a meta pass.
     
  4. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    Do I need to call any function(DynamicGI.UpdateMaterials or any other) after I changed emissive value in real time? I am happy to hear those:)
     
  5. KEngelstoft

    KEngelstoft

    Unity Technologies

    Joined:
    Aug 13, 2013
    Posts:
    1,366
    The fast path is SetEmissive. You can call SetEmissive like this, no call to UpdateMaterials is needed here:

    DynamicGI.SetEmissive(GetComponent<Renderer>(), yourcolor);
     
  6. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    But I want to change "_EmissionScaleUI" in the material not color. Color is same, I just want to set the intensity real time.
    I have tried mat.SetFloat ("_EmissionScaleUI", value); but not worked.
    I have tried DynamicGI.SetEmissive(GetComponent<Renderer>(), yourcolor); it works but as I said it is color not intensity
     
  7. KEngelstoft

    KEngelstoft

    Unity Technologies

    Joined:
    Aug 13, 2013
    Posts:
    1,366
    As the name suggests, the scale value you are changing is only used in the UI. Try setting the variable without UI in its name.
     
  8. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    No way:(

    This is the script I have

    public class NewBehaviourScript : MonoBehaviour
    {
    public GameObject obj;


    private Renderer rend;
    private Material mat;
    private float value;
    // Use this for initialization
    void Start ()
    {
    rend = obj.GetComponent<Renderer> ();
    mat = rend.sharedMaterial;
    }

    // Update is called once per frame
    void Update ()
    {
    DynamicGI.SetEmissive(rend,Color.white);//Changes emiission color run time
    mat.SetFloat ("_EmissionScaleUI", value); //Changes emission scale in editor but no affect in real time GI
    //DynamicGI.UpdateMaterials (rend);
    }

    void OnGUI()
    {
    value=GUILayout.VerticalSlider (value, 0, 2);
    }
    }

    I didnt understand what is going on here:(
     
  9. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    mat.SetFloat ("_EmissionScale", value); has no affect
     
    Ignacii likes this.
  10. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    I'm by no means a shader expert yet, but just poking around with some of the source files I wonder if EmissionScale is only present in the UI. Because when I look at the editor code for the shaders, it appear to multiply the scale by the colour and then send that to the shader as a color. This implies the same should be done for realtime updating, update the emission colour after multiplying the required color by the required scale?

    eg line 327 of StandardShaderGUI.cs:

    return material.GetColor("_EmissionColorUI") * Mathf.LinearToGammaSpace(material.GetFloat("_EmissionScaleUI"));
     
  11. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    My problem is simple. I want to simulate day times in GI. So when it is day time I want to set emission scale to some value and when it is night I want to set it to 0. Lerp between these times etc.

    I can achive the same effect by changing emission color between white and black , but why? simply chnaging scale solves problem.
     
  12. lilymontoute

    lilymontoute

    Joined:
    Feb 8, 2011
    Posts:
    1,181
    @Gokan - final emission color is baked in from emission color and emission scale. You should be able to do the calculation yourself to change the scale at runtime:

    1) Get _EmissionColorUI and _EmissionScaleUI
    2) Perform the calculation above: finalColor = _EmissionColorUI * Mathf.LinearToGammaSpace(_EmissionScaleUI)
    3) Set emission color to the resulting color

    It would be nice if Unity provided a method overload for DynamicGI.SetEmissive that took a color and a scale, though.
     
    plmx and Psyco92 like this.
  13. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    @Thinksquirrel - thanks for your answer. I will do it but as you said it would be nice if unity provide a method for scale:)
     
  14. KEngelstoft

    KEngelstoft

    Unity Technologies

    Joined:
    Aug 13, 2013
    Posts:
    1,366
    Yeah, a workaround is needed for now. We will come up with a nicer way of setting it.
     
  15. noneee

    noneee

    Joined:
    Nov 26, 2014
    Posts:
    3
    no ways works for me described up, i only need to highlight selected object by change emissive color say green or red,

    function selectObject(){

    for (var mat in selectedObject.GetComponent.<Renderer>().materials)
    {
    mat.EnableKeyword ("_Emission");
    mat.SetColor("_Emission", Color.green);
    }

    objects uses only unity's "standard" shader, maybe "emission" is not a parameter for this? or i dont know else :(
     
  16. Gokcan

    Gokcan

    Joined:
    Aug 15, 2013
    Posts:
    289
    DynamicGI.SetEmissive(renderer,Color.white);

    this one works. Make sure you set your emmisive objects to ligtmap static. Make sure you have precomputed GI. Then Use this method real time to change color. Debug your script and make sure you pass correct renderer of objects!!!