Search Unity

Shader.SetGlobalVector doesn't work

Discussion in 'Shaders' started by Aldrick, Feb 21, 2017.

  1. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    I am passing scene datas into shader properties.My earlier way is to use Material.SetVector method on every relevant materials and it works fine.But as number of involved materials gets bigger,I am trying a simple way of using Shader.SetGlobalVector to handle the shaders shared by many materials directly,which save the process of collecting materials one by one each time a new material is added into scene.This method should work intuitively as is name suggests but nothing happens.What's wrong or what other tips do I miss?

    shader property:

    Code (CSharp):
    1. _MyLightDir("Custom Light Direction",Color) = (1,1,1,1)

    C#:

    Code (CSharp):
    1.  void Update()
    2.     {
    3.         MyLightDir.x = Mathf.Clamp(MyLightDir.x, -0.99f, 0.99f);
    4.         MyLightDir.y = Mathf.Clamp(MyLightDir.y, -.99f, 0.99f);
    5.         var LightZ = Mathf.Sqrt(1 - MyLightDir.x * MyLightDir.x - MyLightDir.y * MyLightDir.y);
    6.         MyLightDir.z = LightZ;
    7.         Matrix4x4 m = MyCam.cameraToWorldMatrix;
    8.        
    9.         Vector3 TmpVector3 = m.MultiplyVector(MyLightDir);
    10.  
    11.         Vector4 TransformedVector = new Vector4(TmpVector3.x, TmpVector3.y, TmpVector3.z, 0.0f);
    12.         Shader.SetGlobalVector("_MyLightDir",TransformedVector);
    13.  
    14. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Shader globals shouldn't be specified in the shader's properties.
     
    SgerbwdGwyn, UsabilityFox and Aldrick like this.
  3. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    Thank you endlessly bgolus.I noticed the scripting reference mentioning exposing the properties stuff,but didn't think it's mandatory.Your reply save me a lot of time!
     
  4. zuhane

    zuhane

    Joined:
    Mar 29, 2019
    Posts:
    6
    A clearer answer for those stuck:

    Make sure you don't have "Exposed" ticked in the ShaderGraph blackboard. The material will proceed to overwrite changes you make via scripts if this is enabled. Disabling still allows you to edit through scripts, but won't expose this field on the material.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    This thread was from almost a year before Shader Graph was released, and even a few months before being announced, and is thus explicitly talking about vertex fragment or Surface shaders.

    But yes, if you are using Shader Graph for the URP or HDRP, uncheck Exposed option for properties added to the blackboard will let them be controlled as global shader values. Alternatively if you use a Custom Function node with an .hlsl file, any value defined outside of a function can be set with a global shader value even if you don't add it to the blackboard at all.

    Under the hood Shader Graph is doing exactly the same thing though. Shader Graph is a vertex fragment shader generator, and unchecking Exposed skips adding the value to the
    Properties
    of the generated shader file.
     
    unity_aica01 likes this.