Ali Youssef talked about the way he builds a pretty good-looking ice shader in Unreal Engine 4.
Hi, my name is Ali Youssef, I’m a third-year computer science student studying in Kiev, Ukraine. I’m aspiring to work as a 3D environment artist after graduating, so I’m mainly creating environments for my portfolio and doing research in my spare time. I’m going to talk about an ice shader I’m currently working on and a few techniques I’ve picked up on using the material editor in UE4.
I was planning to start working on a glacier environment, so I was gathering references for cracked ice, and stumbled upon the following image:
I really liked how you could see the sides of each cracked chunk as opposed to having carved lines on a plane, so that was my main focus for the shader, as well as give depth to the ice so it doesn’t look flat.
My first step was to create a simple material in Substance Designer to serve as a colour base for the ice and generate a mask for the cracks along with very subtle normal and roughness maps that help isolate the individual chunks.
The material itself is opaque, as my goal was to make the ice look volumetric using parallax mapping and subsurface.
Here’s the complete graph inside the material editor:
The Substance helped with the surface of the ice, with snow stuck in the cracks as wind blows over; the normal map giving each cracked chunk a rounded edge, while subtle, helps tremendously with reflections; and the roughness map being a bit rougher on the edges which gives the ice “glassy” specular highlights.
What lies beneath
Ice looks very cloudy naturally, and as the water freezes top-first, the minerals in the water get pushed down before freezing into bubbles which creates the cloudy look.
This is where subsurface comes in, using a cloud texture for the subsurface (plugged into the opacity pin) gives a variation of clearness along the ice.
But the mask should be visible below the ice, not on top, otherwise it looks like dust or dirt on the surface.
To give depth to the subsurface I plugged the same cloud texture into a bump offset node, which displaces the texture based on the camera position, giving it a fake 3-dimensional look.
The reason I used the same texture as both the height and opacity, is because height offsets the texture based on each pixel, so the brighter a pixel is, the deeper it will seem, and the more light it will block for subsurface.
And that gives the cloudy depth look for the ice.
As overwhelming as it may look, the parallax section of the shader is fairly simple, it uses the same node as the subsurface (bump offset), only it iterates several times to give a solid shape rather than random noise.
This time instead of using the node for a fake 3d texture, I used it to generate a mask which lightens and tints the colour based on the camera angle.
The mask also fades out on each iteration, which mimics less visible depth as the ice goes thicker.
The process is shown in the above image, a mask is plugged into the height pin of the bump offset, and a height ratio is input into its correspondent pin after getting added to the previous iteration’s height ratio (so each iteration looks deeper).
The bump offset then displaces the same mask, which gets clamped each iteration to fade out as it goes deeper.
The whole process is repeated 24 times to avoid artifacts when looking at a steep angle, a more optimized material can definitely pull off less iterations, but for demonstration purposes I’ve used 24.
Here’s a clearer representation of the effect in action:
As soon as I got a result I was more or less happy with, I posted my progress on Polycount to get some feedback and improvement suggestions. The most consistent critique I got was the lack of reflections, which very accurately described something I’ve overlooked. The problem was that, using screen-space reflections, nothing that should be reflected was visible, especially since most shots were taken looking directly at the ground and nothing else.
So following Sébastien’s suggestion, I switched to planar reflections, which did wonders by reflecting the sky. I’ve also added more bumpy normals to give noisier reflections (much like water), which got it looking closer to the reference that I’ve used, where the ice reflects more clearly the further it is from the camera.
For anyone wishing to start working with UE4’s material editor, the only tip I can provide is to just dive right into it. There are several resources out there that can help with the first steps, including Epic’s own live streams, like this one with Ryan Brucks. Or even the countless articles here on 80.lv, I’ve read many articles that taught me interesting effects and techniques regarding technical shaders.
Generally, a lot of what I’ve learned is from trial and error, and testing out random ideas. And if I have no idea how to recreate a specific effect, odds are someone has made something similar and has shared their experience.