Search Unity

Passing data to constants...

Discussion in 'Shaders' started by Jonathan Czeck, Oct 20, 2005.

  1. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Is this feasible in a fragment program? For instance, I can do:

    Local 0, [_Color0]

    And then change _Color0 from scripting, but is there a performance hit to doing this? Like something has to get recompiled?

    In that case, why can't I do something like:

    Local 3, ([_SinTime],[_SinTime],[_CosTime],0)

    Or all those only for Cg?

    Thanks,
    -Jon
     
  2. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Hi Aarku...

    So good to finally see somebody getting turned into a shader developer ;-)

    Yes... You set the constants from scripting. There is no performance hit.

    SinTime is a 4-component vector property. So you would do Local 0, [_SinTime]

    This will load up Local 0 with (sin (time *.125f), sin (time *.25f), sin(time * .5f), sin(time * 1f)), so you basically get 4 sine values oscillating at different speeds.

    To choose one, you use component swizzling inside your fragment/vertex, e.g.
    MOV r0, c0.rrrr; <- in the case of ATI_FRAGMENT.

    Here is an example from Intifada; it loads up a bunch of values used in vertex/fragment programs:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Atmosphere : MonoBehaviour {
    6.     /// Gradient back and forth between rayleigh  mie scattering
    7.     public float haze = 1f;
    8.     public float hazeSunPwr = 2.5f;
    9.     public float mist = 1f;
    10.     public float mistSunPwr = 4f;
    11.     public float mistDirectionality = .7f;
    12.  
    13.     Vector3 lightDirection = new Vector3 (0,-1,0);
    14.     Color lightColor = Color.white;
    15.  
    16.     Light sunLight;
    17.  
    18.  
    19.     void CalculateConstants () {
    20.         // Get light values from the SunLight
    21.         if (!sunLight) {
    22.             GameObject go = GameObject.FindGameObjectWithTag ("SunLight");
    23.             if (!go) {
    24.                 Debug.LogError ("Atmosphere scattering requires a directional light tagged as SunLight");
    25.                 return;
    26.             }
    27.             sunLight = go.GetComponent (typeof (Light)) as Light;
    28.             if (!sunLight) {
    29.                 Debug.LogError ("Atmosphere scattering requires a directional light tagged as SunLight");
    30.                 return;
    31.             }
    32.         }
    33.         lightColor = sunLight.color;
    34.         lightDirection = sunLight.transform.TransformDirection (Vector3.forward);
    35.    
    36.         // Hard-coded color falloff coefficients
    37.         Color betaRayleigh = new Color(0.58898305f, 1, 2.06779661f, 0) * .02f;
    38.         Color betaMie = new Color(4e-7f, 6e-7f, 2.4e-6f, 0) * (1 / 1.18e-5f) * 2f * .02f * 1f;
    39.  
    40.         // wiegh them in and out
    41.         betaRayleigh = betaRayleigh * haze;
    42.         betaMie = betaMie * mist;
    43.        
    44.         // calculate constants for shader
    45.         Color betaRayleighMie = betaRayleigh + betaMie;
    46.         Color invBetaRayleighMie = 1f / betaRayleighMie;
    47.        
    48.         Color betaRayDash =  3f / (16f * 3.14159265f) * betaRayleigh * lightColor * hazeSunPwr;
    49.         Color betaMieDash = 1 / (4f * 3.14159265f) * betaMie  * lightColor * mistSunPwr;
    50.          
    51.         Shader.SetColor ("_BetaRayleigh", betaRayleigh);
    52.         Shader.SetColor ("_BetaMie", betaMie);
    53.         Shader.SetColor ("_BetaRayleighMie", betaRayleighMie);
    54.         Shader.SetColor ("_InvBetaRayleighMie", invBetaRayleighMie);
    55.         Shader.SetColor ("_BetaRayDash", betaRayDash);
    56.         Shader.SetColor ("_BetaMieDash", betaMieDash);
    57.         Shader.SetColor ("_SunColor", sunLight.color);
    58.         Vector3 lightDir = Vector3.Normalize (lightDirection);
    59.         Shader.SetColor ("_LightDir", new Color (
    60.             lightDir.x, lightDir.y, lightDir.z, 0));
    61.        
    62.         // HG Mie coefficients
    63.         Shader.SetColor ("_GConst", new Color ((1-mistDirectionality) * (1-mistDirectionality), 1 + mistDirectionality* mistDirectionality, 2 * mistDirectionality,0));
    64.     }
    65.  
    66.     // Update is called once per frame
    67.     void LateUpdate () {
    68.         CalculateConstants ();
    69.     }
    70.    
    71.     void OnDrawGizmosSelected () {
    72.         CalculateConstants ();
    73.     }
    74.     void OnDrawGizmos () {
    75.         CalculateConstants ();
    76.     }
    77. }
    78.  
    This is much faster than calculating the stuff on every vertex or (gasp) every pixel.
     
  3. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Hi Aarku...

    So good to finally see somebody getting turned into a shader developer ;-)

    Yes... You set the constants from scripting. There is no performance hit.

    SinTime is a 4-component vector property. So you would do Local 0, [_SinTime]

    This will load up Local 0 with (sin (time *.125f), sin (time *.25f), sin(time * .5f), sin(time * 1f)), so you basically get 4 sine values oscillating at different speeds.

    To choose one, you use component swizzling inside your fragment/vertex, e.g.
    MOV r0, c0.rrrr; <- in the case of ATI_FRAGMENT.

    Here is an example from Intifada; it loads up a bunch of values used in vertex/fragment programs:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Atmosphere : MonoBehaviour {
    6.     /// Gradient back and forth between rayleigh  mie scattering
    7.     public float haze = 1f;
    8.     public float hazeSunPwr = 2.5f;
    9.     public float mist = 1f;
    10.     public float mistSunPwr = 4f;
    11.     public float mistDirectionality = .7f;
    12.  
    13.     Vector3 lightDirection = new Vector3 (0,-1,0);
    14.     Color lightColor = Color.white;
    15.  
    16.     Light sunLight;
    17.  
    18.  
    19.     void CalculateConstants () {
    20.         // Get light values from the SunLight
    21.         if (!sunLight) {
    22.             GameObject go = GameObject.FindGameObjectWithTag ("SunLight");
    23.             if (!go) {
    24.                 Debug.LogError ("Atmosphere scattering requires a directional light tagged as SunLight");
    25.                 return;
    26.             }
    27.             sunLight = go.GetComponent (typeof (Light)) as Light;
    28.             if (!sunLight) {
    29.                 Debug.LogError ("Atmosphere scattering requires a directional light tagged as SunLight");
    30.                 return;
    31.             }
    32.         }
    33.         lightColor = sunLight.color;
    34.         lightDirection = sunLight.transform.TransformDirection (Vector3.forward);
    35.    
    36.         // Hard-coded color falloff coefficients
    37.         Color betaRayleigh = new Color(0.58898305f, 1, 2.06779661f, 0) * .02f;
    38.         Color betaMie = new Color(4e-7f, 6e-7f, 2.4e-6f, 0) * (1 / 1.18e-5f) * 2f * .02f * 1f;
    39.  
    40.         // wiegh them in and out
    41.         betaRayleigh = betaRayleigh * haze;
    42.         betaMie = betaMie * mist;
    43.        
    44.         // calculate constants for shader
    45.         Color betaRayleighMie = betaRayleigh + betaMie;
    46.         Color invBetaRayleighMie = 1f / betaRayleighMie;
    47.        
    48.         Color betaRayDash =  3f / (16f * 3.14159265f) * betaRayleigh * lightColor * hazeSunPwr;
    49.         Color betaMieDash = 1 / (4f * 3.14159265f) * betaMie  * lightColor * mistSunPwr;
    50.          
    51.         Shader.SetColor ("_BetaRayleigh", betaRayleigh);
    52.         Shader.SetColor ("_BetaMie", betaMie);
    53.         Shader.SetColor ("_BetaRayleighMie", betaRayleighMie);
    54.         Shader.SetColor ("_InvBetaRayleighMie", invBetaRayleighMie);
    55.         Shader.SetColor ("_BetaRayDash", betaRayDash);
    56.         Shader.SetColor ("_BetaMieDash", betaMieDash);
    57.         Shader.SetColor ("_SunColor", sunLight.color);
    58.         Vector3 lightDir = Vector3.Normalize (lightDirection);
    59.         Shader.SetColor ("_LightDir", new Color (
    60.             lightDir.x, lightDir.y, lightDir.z, 0));
    61.        
    62.         // HG Mie coefficients
    63.         Shader.SetColor ("_GConst", new Color ((1-mistDirectionality) * (1-mistDirectionality), 1 + mistDirectionality* mistDirectionality, 2 * mistDirectionality,0));
    64.     }
    65.  
    66.     // Update is called once per frame
    67.     void LateUpdate () {
    68.         CalculateConstants ();
    69.     }
    70.    
    71.     void OnDrawGizmosSelected () {
    72.         CalculateConstants ();
    73.     }
    74.     void OnDrawGizmos () {
    75.         CalculateConstants ();
    76.     }
    77. }
    78.  
    This is much faster than calculating the stuff on every vertex or (gasp) every pixel.
     
  4. Jhung

    Jhung

    Joined:
    Jan 22, 2008
    Posts:
    10
    wow a shaderlab impl of rayleigh mie scattering.. nicholas, can i, um, pleese have a look at this shader?
     
  5. Jhung

    Jhung

    Joined:
    Jan 22, 2008
    Posts:
    10
    disregard my last post! lol, sry im a shader noob.. (thanks again for sharing your impl)