Bruno Formagio
Bruno Formagio

Reputation: 13

Shaders are always showed with fixed values in material editor? (Unity)

I'm trying to get a value property from a shader attached in an object at runtime, but it's never changes in material editor. Maybe I misunderstood anything of how shaders works?

I read about the GetFloat, GetColor, etc but don't figure out yet how it properly works to get an information of a shader in Update(). The real objective here is catch a specific value from shader (in realtime) and do something in C# script, if it's possible.

C# example:

public Color colorInfo;

Awake()
{
    rend = GetComponent<Renderer>();// Get renderer
    rend.material.shader = Shader.Find("Unlit/shadowCreatures");//shader
}

Update()// I want the info in a realtime
{
    //get current float state of the shader
    colorInfo = rend.material.GetColor("_Color"); 
    //If I setup a white color in shader properties, the color in material editor is always white
}

Shader:

Shader "Unlit/shadowCreatures"
{
Properties {
    _Color ("Color", Color) = (1,1,1,1)
    [PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}
    _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
    Tags 
    { 
        "Queue"="Geometry"
        "RenderType"="TransparentCutout"
        "PreviewType"="Plane"
        "CanUseSpriteAtlas"="True"
    }
    LOD 200

    Cull Off

    CGPROGRAM
    // Lambert lighting model, and enable shadows on all light types
    #pragma surface surf Lambert addshadow fullforwardshadows

    // Use shader model 3.0 target, to get nicer looking lighting
    #pragma target 3.0

    sampler2D _MainTex;
    fixed4 _Color;
    fixed _Cutoff;

    struct Input
    {
        float2 uv_MainTex;
    };

    void surf (Input IN, inout SurfaceOutput o) {
        fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
        o.Albedo = c.rgb;
        o.Alpha = c.a;
        clip(o.Alpha - _Cutoff);
        _Color = (0,0,0,0); //trying turn to black just for a test, and nothing happens
    }
    ENDCG
}
FallBack "Diffuse"
}

Thank you for your time

Upvotes: 1

Views: 583

Answers (1)

I think I figured out what you're trying to do and

That's not how things work, sorry

Piecing together your comments and question, this is what I think you're trying to fiddle with:

void surf (Input IN, inout SurfaceOutput o) {
    _Color = (0,0,0,0); //trying turn to black just for a test, and nothing happens
}

That doesn't do what you think it does. That line sets this _Color:

#pragma target 3.0

sampler2D _MainTex;
fixed4 _Color;
fixed _Cutoff; //here

Not this one:

Properties {
    _Color ("Color", Color) = (1,1,1,1) //here
    [PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}
    _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
}

That second one is what is shown in the inspector panel, and its linkage with the CGPROGRAM block is effectively one-way because frag surf and geom are all called multiple times, in parallel, and rely on receiving the same data in, so the Properties value is read into the CGPROGRAM and the CGPROGRAM's values are discarded when it is done.

I don't think there's any way you can make the shader CGPROGRAM do anything that you can read from C# (because that code runs hundreds of times per frame, how would you know which one to read from?)

I know you can get at the properties (including changing a property for one instance or for all instances), but not the underlying CGPROGRAM data. The only way I can even think of getting around this would be to render to a texture and then read the texture data, and that would be slow (and again, you get into "which pixel has the value you want"?)

Upvotes: 1

Related Questions