Interested in this Exercise?

Watch the course trailer to see what's inside, read the description, and then start learning on CG Cookie today.

Watch course trailer Start a Free Trial

Dynamic Snow Accumulation

crew
  • Software:Unity 2017  ·
  • Difficulty:Intermediate

Rules of the Exercise

  • 1
    Use the included snow particle system in the project files
  • 2
    Create a snow shader that has snow accumulating on one side of the rocks facing the snow particle system
  • 3
    Create a C# script that slowly increases the snow amount on the rocks over time

Dynamic Snow Effects

In this exercise you'll learn how to slowly accumulate snow on an object over time. This will involve using a C# script to control the shader properties of our snow shader. Combined a particle system to mimic the effect of snow falling and accumulating onto our rocks. Shaders can be used in dynamic environments and knowing how to use these shaders through C# scripting can be invaluable in controlling how your game will look at run time. 

Submitting Your Exercise

Upload a video showcasing how your dynamic snow effect works. Use the included project files which include a snow particle effect. Link your video as a submission to be graded. 


Instructors Notes

If you're struggling with this exercise or just want to know how it was done take a look down below. 

The scene has been setup for you already in the starting files, you don't need to make modifications to the shader but you will be required to access the snow shader properties within a C# script. Below is how you would write this script. 

First we must access the shader through script. Create a new script and call is SnowAccumulation. At the top include these variables:

[Range(0f,0.05f)]
public float snowAmount = 0.0025f;
private Renderer rend;
private float snow;

The key thing to look for is the "Renderer" type, this will allow us to access the material and subsequently the shader attached to it. Next we'll grab the material in the start method by way of the renderer:

    void Start () {
        rend = GetComponent<Renderer> ();
        rend.material.shader = Shader.Find ("ShaderSchool/Examples/Snow_Fade");
}

First we get the renderer component, then from there we can access the material then the shader. The find the shader we use "Shader.Find" then provide the "directory" of where this is found. 

I included a simple Coroutine to gradually increase the snow amount over time:

IEnumerator SnowBuild ()
    {
        snow = rend.material.GetFloat ("_SnowAmount");
        while (snow < 0.75f) {
            snow += snowAmount;     
            rend.material.SetFloat ("_SnowAmount", snow);
            yield return new WaitForSeconds (0.05f);
        }
    
    }

This first gets a float value assigned to snow based off the "_SnowAmount" property of our shader. We use "GetFloat" for that. The rest involves using a while loop to check if the snow value is still less than 0.75f, if so continue looping and increasing the snow amount. We do this using "SetFloat" after we increment our snow value, then pass that back to the "_SnowAmount". We wait 0.05f seconds then repeat until snow is at 0.75f or higher. You can call this Coroutine from the start method like this:

    void Start () {
        rend = GetComponent<Renderer> ();
        rend.material.shader = Shader.Find ("ShaderSchool/Examples/Snow_Fade");
        StartCoroutine ("SnowBuild");
    }

This same process of accessing a shader can be applied to all shaders. Being able to control shaders through script provides immense control over how visually interesting your game can look.