đ§Shader Properties
Methods for animating material shader properties
Last updated
Methods for animating material shader properties
Last updated
There are two primary methods for animating material shader properties using Timeflow: direct material animation, and global shader properties. Each has its usage and caveats as explained in more detail below.
Please see the example scene included:
Assets/AxonGenesis/Timeflow/Examples/Scenes/Animation/ShaderProperties.unity
The most direct way of animating materials on an object is to target the material property using any Timeflow behavior, such as Keyframer or Tween. Right click on an object in the Timeflow view to select a material property. The context menu shows a full list of available properties for each material on the object.
When using this method of animating materials, it is important to understand how Unity performs material instancing since that directly affects behavior at runtime which differs from working in edit mode.
In edit mode, all materials are referenced through a shared material reference directly relating to the material asset. However, at runtime each object is assigned an instance of the original material which no longer shares a connection with the original.
When material properties are animated, they only affect the object they are applied to. In edit mode, objects with the same shared material may appear to have the same animation, however upon entering runtime only the single object material is affected. This may appear to be a bug to anyone unaccustomed to the behavior of materials in Unity.
To work around this issue, one solution is to replicate the material animation on each object. This is fine if there are not many objects, however it is not the most efficient way.
Beware of Cross-Scene Material References
Whenever you have the same material used in multiple places throughout a project, animating the material could cause issues if in one context material values are set and in another they are not.
For example, animating the color of a material in one scene (while working in the editor) will change the color of the material used in any other scenes. If changes are only made at runtime, this isn't a problem, however since Timeflow works mostly in edit mode it could cause confusion when working with shared materials.
The solution to this dilemma is to be intentional about the use of materials, especially when animated. It helps to have a clear method of organization and may be advisable to duplicate materials where they need to be animated differently.
Another approach using Timeflow is to use Channel Link to connect the original animated properties to other objects. Each linked object can have the same or a different material, so long as the property names match.
At runtime, each object instantiates a material instance and these mappings then propagate the animation. This process may be repeated on as many objects as needed, as well as mapping from one property to an entirely different one.
A more efficient way to animate material properties across multiple objects with little to no additional overhead or management of links and channels is to use global shader properties. These are properties defined in shaders with the global keyword and not exposed in the material inspector.
The main advantage to this approach is that the global property only needs to be set once per frame and affects all objects which use the shader. In the example shown above, "_TimeflowTime" is the default name set in Timeflow by enabling Set Shader Time in the Settings.
There is also an option for Set Shader Frame which as the name indicates sends the frame number, instead of time in seconds.
There are many potential uses for this in Shader Graph and generally _TimeflowTime can be used instead of the built-in Time node to drive shader behaviors. Below is an example showing how it can be used to control the speed of a texture offset.
Besides the above method of setting time and frame numbers, most channels in Timeflow also have the option for setting a global shader value, which can be exposed in the channel settings on the Timeflow Object or parent behavior.
In the above example, the _Beat01 variable was added to shader graphs with the intention of it being used to drive audio-reactive behaviors. Of course, global shader properties can be named anything you like, so long as it is unique and won't get confused with other shader properties.
The best part of using global shader properties is that you can drive material animation on unlimited numbers of objects across different materials without adding any additional channels or behaviors to the scene.
Additional properties may be created to add user control to determine animation behavior on a per material basis, simply by setting the values as desired in the material inspector. Below is an example of how _Beat01 is controlled by BeatInfluence and BeatIntensity.
These shaders are included in the Timeflow package for further inspection and can be modified, or using this knowledge you may create your own global shader behaviors for unlimited possibilities and special effects.