Unity Shader Graph - How to Change Parameters --- How to change a parameter of a mesh on all objects at the same time?

8.2k Views Asked by At

I created my first shader by following this video. Dissolve Shader Video Link

In a Coroutine,i took the Material's component from the object:

PalaceMaterial = palaceInstance.GetComponent <Renderer> () .material;

I set the parameter to 0:

PalaceMaterial.SetFloat ("_ CutoffHeight", 0);

To have this effect, I had to modify the parameter "CuttoffHeight" gradually putting it in Update ()

 PalaceMaterial.SetFloat("_CutoffHeight", Mathf.MoveTowards(PalaceMaterial.GetFloat("_CutoffHeight"), CutoffHeight, 100 * Time.deltaTime));

I applied this to all objects. Every 2 seconds i instantiate an "invisible object" (CutoffHeight set to 0) and in Update() it change the value gradually. Now I would like to change this parameter to all objects that use this shader simultaneously. I hope i was clear.

Video of my project : Project, Dissolve_Effect

I would like to change the "_CutoffHeight" parameter simultaneously in all the cubes that are in the first platform, then in the second one, etc. etc. Do you have any idea?

1

There are 1 best solutions below

3
On BEST ANSWER

In general you shouldn't additionally use GetFloat but rather store the value locally and calculate it from there.


Then this already should work if multiple objects share the exact same material by using e.g.

GetComponent<Renderer>().sharedMaterial.SetFloat(...);

but this works only as long as you don't have multiple instances of the material in your renderers.


There is a way to set a property for all Shaders (which have that property) and their according instances (= Materials) I came across in this thread

To do this you have to

  • Disable "exposed" for the according property. Apparently it only works for properties that are not exposed in the Inspector.

  • Use the generated shader property ID you can find in the Inspector of the shader asset itself.

    You can also retrieve it using Shader.PropertyToID

    You can also change it to match your actual parameter name.

  • Use the global setter methods of the shader like Shader.SetGlobalXY

enter image description here

e.g. in order to set the Spec Brightness you would do

Shader.SetGlobalFloat("Vector1_DD757871", value);

So in your case you could probably have one single controller doing something like

// Need this only if you have to get the initial value once
[SerializeField] private Material PalaceMaterial;

private float currentValue;
private string propertyId;

private void Awake()
{
    propertyId = Shader.PropertyToID("_CutoffHeight");
    currentValue = PalaceMaterial.GetFloat("_CutoffHeight");
}

private void Update()
{
    currentValue = Maths.MoveTowards(currentValue, CutoffHeight, 100 * Time.deltaTime);
    Shader.SetGlobalFloat(propertyId, currentValue);
}