Search Unity

What am I doing wrong with Shader.SetGlobal...

Discussion in 'Shaders' started by ananrara, Aug 17, 2018.

  1. ananrara

    ananrara

    Joined:
    Feb 10, 2013
    Posts:
    6
    As a minimal example, I'm trying to set a global property that all shaders should be able to access.

    C#
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SetGlobalColorProperty : MonoBehaviour {
    4.  
    5.     private void OnPreCull()
    6.     {
    7.  
    8.         Shader.SetGlobalColor("_GlobalColor", Color.blue);
    9.        
    10.     }
    11.  
    12. }
    Shader
    Code (CSharp):
    1. Shader "Unlit/GlobalColor"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType"="Opaque" }
    6.         LOD 100
    7.  
    8.         Pass
    9.         {
    10.             CGPROGRAM
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.            
    14.             #include "UnityCG.cginc"
    15.  
    16.             struct appdata
    17.             {
    18.                 float4 vertex : POSITION;
    19.             };
    20.  
    21.             struct v2f
    22.             {
    23.                 float4 vertex : SV_POSITION;
    24.             };
    25.  
    26.             uniform float4 _GlobalColor;
    27.  
    28.             v2f vert (appdata v)
    29.             {
    30.                 v2f o;
    31.                 o.vertex = UnityObjectToClipPos(v.vertex);
    32.                 return o;
    33.             }
    34.            
    35.             fixed4 frag (v2f i) : SV_Target
    36.             {
    37.                 return fixed4(_GlobalColor);
    38.             }
    39.             ENDCG
    40.         }
    41.     }
    42. }
    43.  
    I've tried SetGlobal Vector and Color both, tried adding 'disable batching' in the tags of the shader. Is the Shader.SetGlobal... being called in the wrong execution order?

    https://docs.unity3d.com/ScriptReference/Shader.SetGlobalVector.html
     
    mgsvevo likes this.
  2. Jona-Marklund

    Jona-Marklund

    Joined:
    Jun 27, 2012
    Posts:
    34
    I honestly can't see any errors in your code.

    Some things you might want to try to debug is.

    Call it in Update and debug.log the value.
    Try to create a variable myColor = new Color(0, 0, 1); and use that inside of Color.blue.
     
  3. ananrara

    ananrara

    Joined:
    Feb 10, 2013
    Posts:
    6
    Calling it in Update worked like a charm.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    OnPreCull only gets called if the script is placed on the same game object as a enabler camera component. Likely why it wasn't working for you before.
     
  5. ananrara

    ananrara

    Joined:
    Feb 10, 2013
    Posts:
    6
    Seem to be exactly the case. "This function is called only if the script is attached to the camera and is enabled." from the docs

    Only checked this page and assumed it would get called anyway.

    Always nice to know the reason things didn't go as one thought.
     
  6. JonPQ

    JonPQ

    Joined:
    Aug 10, 2016
    Posts:
    120
    for others out there.... the SetGlobal values can also get overwritten by other screen space or filter FX. IF you have such components on the Camera, try disabling them.