Creating the ice and snow materials

Bernardo Iraci

December 2013

(For more resources related to this topic, see here.)

Getting ready

We will create the ice and the snow using a single material, and mix them using a new technique. Select the iceberg mesh and add a new material to it.

How to do it...

We will now see the steps required to create the ice as well as the snow material.

Creating ice

The following are the steps to create ice:

  1. Add Glossy BSDF and Glass BSDF and mix them using a Mix Shader node. Let's put Glossy in the first socket and Glass in the second one.
  2. As input for the color of both the BSDFs, we will use a color Mix node with Color1 as white and Color2 as RGB 0.600, 1.00, 0.760.
  3. As input for the Fac value of the color Mix node, we will use a Voronoi Texture node with the Generated coordinates, Intensity mode, and Scale 100. Invert the color output using an Invert node and plug it into the Fac value of the color Mix node.
  4. As the input for Roughness of the Glossy BSDF, we will use the Layer Weight node's Facing output with a Blend value of 0.800. Then we will plug this into a ColorRamp node and set the color stops as shown in the following screenshot. The first color stop is HSV 0.000, 0.000, 0.090 and the second one is HSV 0.000, 0.000, 0.530. Remember to plug the ColorRamp node into the Glossy BSDF roughness socket.

  5. Finally, set Glass BSDF node's IOR to 1.310 and Roughness to 0.080.
  6. Now we will create the Fac input for the Shader Mix node of the two BSDFs. Now we will add Noise Texture to the Generated coordinates with a Scale of 130, Detail of 1, and Distortion of 0.500. Plug this into a ColorRamp node and set the color stops as shown in the the following screenshot:

  7. Let's now add a Subsurface Scattering node. Set the mode to Compatible, the Scale to 10.000 and the Radius to 0.070, 0.070, 0.10.
  8. As a color input, let's add another color Mix node with Color1 as RGB 0.780, 0.960, 1.000 and Color2 as RGB 0.320, 0.450, 0.480.
  9. The Fac input for the color Mix node will be the same as for the color Mix node of the Glass and Glossy BSDFs. Now mix the SSS node with the mix of the other two BSDFs, using an Add Shader node.
  10. Now, we will create the normals for the shader. Add three Image Texture nodes. In the first one, let's load the IceScratches.jpg file. We will use the Generated coordinates with a Scale of XYZ 20.000, 20.000, 20.000. Set the projection mode to Box and the Blend to 0.500.
  11. In the second Image Texture node, load the ice_snow_DISP.pngfile, using the UV coordinates.
  12. Finally, load the ice_snow_NRM.png file in the third Image Texture node, using again the UV textures.
  13. Now let's mix the IceScratches.jpg with the ice_snow_DISP.png textures, using a color Mix node with the Displacement Texture into the Color1 socket and the scratches texture into the Color2 socket. Set the Fac value to 0.100.
  14. Plug the mix of the textures into the Height socket of a Bump node and then plug the ice_snow_NRM.png texture into the Color socket of a Normal Map node. Finally, plug this one into the Normal socket of the Bump node.
  15. Set the Normal Map node's Strength to 0.050, the Bump node's Strength to 0.500 and the Distance to 1.000.
  16. Plug the Bump node into all of the BSDFs we added so far.
  17. Frame every node we created and label the frame ICE.

Creating snow

  1. The nodes we will add now will still be within the same material, but outside the ICE group we just created. Add a Glossy and a Subsurface Scatter BSDF nodes. Mix them using a Mix Shader node with 20 percent of influence from the Glossy BSDF node.
  2. Set both the colors to white. Also, set the SSS Scale to 3.00 and the Radius to 0.400, 0.400, 0.450. Set the Glossy mode to GGX and the Roughness to 0.600.
  3. Add a Noise Textures node and set Scale to 2000.000, Detail to 2.000 and Distortion to 0.000. We will use Generated coordinates for this texture.
  4. Connect the Fac output of the Noise Texture node to the Height socket of the Bump node and set the Strength to 0.200 and the Distance to 1.000. Connect the Normal output of the Noise Texture node to the Normal input of the Subsurface Scatter BSDF and Glossy BSDF nodes.
  5. Now let's mix the Mix Shader node of the Subsurface Scatter BSDF and Glossy BSDF nodes with an Emission shader using another Mix Shader node.
  6. Add new Noise Textures, this time with Scale as 2500.000, Detail as 2.000, and Distortion as 0.000.
  7. Connect the Fac output of the Noise Texture node to the Color input of the Gamma node, with a Gamma value of 8.000, and then add the Color output of the Gamma node to the Fac input of the ColorRamp node. We will set up the color stops as seen in the next screenshot.
  8. Connect the ColorRamp node's Color socket to the Fac socket of the previous Mix Shader node. Remember to use the Color output of the ColorRamp node.
  9. Frame all these nodes and label the frame SNOW.

Mixing ice and snow

  1. Add a Geometry(Add | Input) and a Normal node (Add | Vectors). Connect the Normal output from the Geometry node to the Normal input of the Normal node.
  2. Now connect the Dot output of the Normal node to the first socket of a Multiply node and set the mode to Multiply and the second value to 2.000.
  3. Add a Mix shader node and connect the ICE frame into the first Shader socket and the SNOW frame into the second one. Finally, connect the output of the Multiply node into the Fac value of the Mix Shader node.

How it works...

Let's see the most interesting points of this material in detail. For the ice material, we used a Voronoi Texture node to create a pattern for the surface color. Then we mixed the Glass and Glossy BSDF nodes using a Noise Texture node to simulate both, the more and less transparent areas: for example, the ice may be less transparent due to some part of it being covered with snow, difference in purity of the water, or the thickness of the ice. Then we mixed the two BSDFs with a Subsurface Scatter node to simulate the dispersion of the lighting inside the ice. Note that we used the ColorRamp node quite often in order to fine tune the various mixing and inputs.

The snow material is quite similar for the main concept, but is missing the refractive part of the ice. Here we did something else. We used a Noise Texture node with some tweaking (Gamma and ColorRamp) to make it really contrasted to mix an emission shader to the rest of the material. This will create a small emission dot over the snow surface that we will use in compositing to create the flakes.

It is really interesting how we mixed the two materials. We wanted the snow to be placed only on the flat surfaces of the iceberg, while we wanted the slopes to be just ice. To obtain this effect, we extracted the normal information about the mesh and used it to understand which part of the mesh is facing upward. We must imagine the normals to be working like the sunlight falling on the surface of the earth. Half of the sphere is in darkness, and half is hit by the light. We can decide from which direction the light hits the surface. Now imagine the same principle applied to the shape of our mesh. In this way we can create a white mask on the areas that are hit by the normal sphere direction. With the Normal node, we can orient this effect wherever we want. The default position of the sphere is exactly what we needed: the parts of the mesh that are faced upward are made white, while the rest of the mesh is black. Turning the sphere around will make the direction of the ramp that has been created, change accordingly.

The sphere, maybe, is not the best way to set these kind of things as it lacks a bit of precision (as for the setting of the sky), but this will probably change in the future with something that allows more precise settings. Finally we used a Multiply node to multiply the value coming from the Normal node and increased the contrast of the mask.

There's more...

The normal method we just saw in this article is not the only way of mixing materials. Just some time ago, two new plugins have been developed. The first one allows us to obtain the same results we got in this article by creating a weight map or a vertex paint based on the slope of the mesh, while the second creates the same based on the altitude. This opens up many possibilities not only in terms of material creation, but also for the distribution of particle systems! The plugins can be downloaded from the following links, where we can find some instructions about them:

See also

In the following link, Andrew Price teaches us how to create a different kind of ice material; for example, material that is more suitable for ice cubes. Surely worth a watch!

Creating the sea material in Cycles

Although we've already created some sea material, this one is going to be something new. While the other sea materials were just a mix of reflective and refractive shaders, now we are going to try to mimic a real mass of water, where the color and the roughness of the refraction changes with the change of the depth. To obtain such an effect in computer graphics the most useful thing would be volumetric. This, for now, is not yet implemented in Cycles, so we will have to fake it. Anyway, as we've already learned, cheating is quite normal while creating 3D graphic scenes, and the result will be great anyway! Let's get started.

Getting ready

Select the sea mesh and add a new material to it. Name it sea.

How to do it...

To create the sea material, follow the ensuing steps:

  1. Let's add a Refraction BSDF node and a Glossy BSDF node and mix them together using a Mix Shader node, with Refraction to the first socket and the Glossy to the second one. As input for the Fac socket, we will use a Fresnel node with IOR 1.120.
  2. Let's set the Refraction node's IOR to 1.333 and the Glossy node's Roughness to 0.005. Also set the Glossy color to white.
  3. Now we are going to create the input for the Refraction BSDF roughness. Add a Camera Data node (Add | Input) and a Multiply node. Connect the camera data View Distance output to the first Value socket of the Multiply node. Set this to the Multiply mode and set the second Value to 0.001.
  4. Finally, connect the Multiply node to the Roughness socket of the Refraction BSDF node.
  5. Now it's time to create the sea bump. Add a Noise Texture node to a Wave Texture node using a Mix color node in the Add mode. Set the Wave Texture node's Scale to 30.000, Distortion to 14.000, Detail to 4.000, and Detail Scale to 2.000. Then, set the Noise Texture node's Scale to 400.000, Detail to 2.000, and Distortion to 0.000. Finally, set the Mix color node's Fac value to 1.000.
  6. Add a Voronoi Texture node in the Intensity mode and multiply it to the sum of the two previous textures. Set the Fac value of the Mix node to 0.400. Also, set the Voronoi Texture node's Scale to 400.000.
  7. Connect the previous Mix node to the Height socket of a Bump node. Set Strength to 0.250 and Distance to 1.000. Finally, connect the Normal output to all the Normal inputs of the BSDFs.
  8. Now we want to create some fake water-like caustics. Add another Voronoi Texture node and set Scale to 200.000 and the mode to Intensity. Connect the Fac output from the Voronoi Texture node to an Invert node.
  9. Then add a ColorRamp node after the Invert node and set the interpolation mode to Constant. Set the color stops as shown in the following screenshot. After the ColorRamp node, add a Math node and set it to Multiply. Set the second socket's value to 5.000.
  10. Connect the Math node to a Transparent BSDF node. Mix the Transparent BSDF node with the mix of the other two BSDFs using a Mix Shader node. Make sure the Transparent BSDF node is connected to the lower socket.
  11. Finally, add a Light Path node and connect the Is Shadow Ray to the Fac value of the Mix Shader node.

How it works...

Let's understand the most important things about this sea material. Surely, even if it is quite simple, the most interesting thing is how we achieved a variable roughness for the Refraction BSDF node. The Camera Data node, as the name says, gives us information about the camera. We need information about the distance of the shading point from the camera. We can use View Z Depth of View Distance. The difference between the two is that, the first one gives a constant distance from the plane, which is perpendicular to the view vector of the camera. The second one returns the distance exactly from where the camera rays are shot, which is the camera itself.

It is important to note that while we are in real-time preview mode, the distance is calculated from the point from where we are looking at the scene, even if this point is not the camera. Of course, while rendering, this point can only be the active camera of our scene.

As we said at the beginning of the article, this method is not accurate, and for our purpose, can work only for a still image. Anyway, the effect that we can get is enough for our purpose. Using View Distance, we can create some sort of a depth spherical map around the camera.

This means that the roughness will increase not only with the depth, but also with the distance from the camera over the water surface. This last thing is not exactly what we want, but from our camera's point of view, it will not be a big problem.

After this we created a bump using a combination of procedural textures and some fake caustics, with the addition of a Voronoi Texture node to generate the initial pattern.

There's more...

As said at the beginning of the article, the correct way to achieve the variable roughness in the water would be through volumetric, which at the moment, is still not supported in Cycles. Anyway, as I am writing these words, there are already experimental builds on Graphical that contain a very early version of the volumetric shading. For those who would like to play a bit with them, I advise you to download the builds released by Tungersunder the name GSoC 2013—DingTo(Google summer of code). For example, this one:

See also

This thread on Blender artists (also in the following pages) has the first experiments with the volumetric in Cycles. There are some interesting node setups, tips, and tricks to pick up!


In this article, we learned how to create all the material for an iceberg. Our target was to have snow on the flat surfaces and ice on the slopes, where it is too steep for the snow to stay. Let's get started!

Resources for Article:

Further resources on this subject:

You've been reading an excerpt of:

Blender Cycles: Lighting and Rendering Cookbook

Explore Title